1

I am admittedly a beginner with JavaScript, but I need to piece together someone else's code and I am having trouble understanding the following function and how to call it in node.

const invoke = method => object => object[method]

This obviously is a function that takes a method that returns another function that takes an object that then returns object[method], but what exactly is the purpose? How would one use this? Thank you.

JamesE
  • 3,833
  • 9
  • 44
  • 82
  • 2
    `method` would be a string (property name). And actually there's no method invocation anywhere, it just returns the property value. Which might be a callable function, but it wouldn't be invoked as a method. – Bergi Apr 04 '18 at 20:15
  • 1
    If you found this in some code, surely you also found examples where it is used? Can you post them, and/or link the source where you found this? – Bergi Apr 04 '18 at 20:16
  • OK, so calling it would be something like `invoke("some method name")(object)`. I'll try to see if it is used anywhere. – JamesE Apr 04 '18 at 20:24
  • 1
    Yes. Probably more like `invoke("property")({property: 42}) == 42` than `invoke("method")({method(x) { return x+10; }})(0x20) == 42` – Bergi Apr 04 '18 at 20:26
  • 1
    `invoke` is a terrible name for this function - A possible better name is `get` or `prop` – Mulan Apr 04 '18 at 21:12

2 Answers2

2

the way i see it is as the const states, it invokes a function stored in an object , as you mentionned, this can be broken down to :

const invoke = (method) => {    
    return (object) => {    
      return object[method] ;
    }
}

the goal of this i believe is that you can call it ( like you're telling a story ) expressively and concisely : invoke the function a from the functions object. ( functionnal-programming )

from this article about functional programming

Functional programming is declarative rather than imperative, and application state flows through pure functions. Contrast with object oriented programming, where application state is usually shared and colocated with methods in objects.

but the term invoke got me thinking about Immediately invoked functions, so the usage of the const invoke can be :

getting function from the object ( without executing it ) not to have to instantiate the whole object and having the function in a variable and maybe manipulate it's prototype.

calling the function ( with parenthesis ).

getting a property from an object.

immediately invoke a function in an object.

const myFns = {
  'a' : function(x){
    console.log(x || 'something to log when no params passed');
  },
  'b': {
    username : 'Doe'
  } 
}

const invoke = method => object => object[method]

let myFunction = invoke('a')(myFns); 
myFunction('hello from myFunction'); // call it or modify myFunction.prototype ... etc.

invoke('a')(myFns)('hello'); // simply call it 

let user = invoke('b')(myFns); // get a property
console.log(user.username);

(invoke('a')(myFns))(); // immidiatly invoke the function

probalby to avoid eval() :P

Taki
  • 17,320
  • 4
  • 26
  • 47
  • 1
    Actually the name is really misleading. `invoke` does not invoke a function! It just accesses it. In your example, only the `…('hello')` actually calls the function. – Bergi Apr 04 '18 at 20:28
  • So FP is about story telling? I am disillusioned. –  Apr 04 '18 at 20:38
  • i think the term can be used for `call` , check this answer https://stackoverflow.com/questions/18505422/whats-the-difference-between-call-and-invoke , quote : `.. allows you to call an arbitrary method ...` – Taki Apr 04 '18 at 20:39
  • @ftor i think `story telling` is a bit overkill :P just to make a point , i meant `declarative rather than imperative` ( from the quote ) – Taki Apr 04 '18 at 20:40
  • You should also mention that the arguments of a curried function can be supplied lazily one at a time, so that you can compose it with other functions (`comp = f => g => x => f(g(x))`) or use specialized intermediates (e.g. `const invokeFoo = invoke("foo")`. –  Apr 04 '18 at 20:54
  • 1
    [*On Storytelling*](https://www.deconstructconf.com/2017/evan-czaplicki-on-storytelling) by Evan Czaplicki (creator of Elm) – Mulan Apr 04 '18 at 21:12
0

The name 'invoke' suggests it should really be written like this:

const invoke = method => object => object[method]()

The () is the invocation. It's very general, so hard to say exactly how it would be used, but here's a silly example.

class Dog {
    speak () { console.log('woof') }
}

var dogs = [ new Dog(), new Dog(), new Dog() ];

dogs.forEach( invoke( 'speak' ) );

-> 'woof'
-> 'woof'
-> 'woof'

It's a pretty common pattern to let an array method like forEach do the second call of a higher-order function like this.

Ben West
  • 4,398
  • 1
  • 16
  • 16