1

From a book I read on functional programming I learned about closures in JavaScript and how they can work. A simple example is:

function StringCon(arg) {
   return function (ar) {
    return arg + ar;

   }
 }
StringCon("hello")(" world")//-> "hello world"

But as we want to add more arguments, we would need to return more and more functions which can quickly confuse.

I would like to create a function that will allow me to pass in a string, with the ability to add to this with more function calls. When finally it is passed an empty call, it should return the concatenated string. An examples might look like this.

StringCon("I ")("am ")("new ")("to")(" JavaScript")();//-> I am new to JavaScript

Also, if it is not totally possible, what would be the closest solution? Thanks in advance!

Alex
  • 123
  • 1
  • 9
  • 2
    What you're talking about here looks like _currying_ [here](http://stackoverflow.com/questions/36314/what-is-currying/36321#36321) – VLAZ Aug 16 '16 at 21:26
  • I didn`t know that, should I change the name of my question to "Curring in JavaScript"? – Alex Aug 16 '16 at 21:28
  • 1
    @Alex I guess that depends on if you have a specific issue with currying. There's already [examples](http://stackoverflow.com/questions/4394747/javascript-curry-function) available showing how to implement it. – Mike Cluck Aug 16 '16 at 21:30
  • This is really just a single example of javascript closures. For a good introduction to the broader concept, see http://javascriptissexy.com/understand-javascript-closures-with-ease/ – mcgraphix Aug 16 '16 at 21:32
  • Can you resume your question? I don't understand it... sorry –  Aug 16 '16 at 21:35
  • You could change the title if you want. I think it would be more clear - the two concepts aren't really related, although curry could make use of a closure functionality. – VLAZ Aug 16 '16 at 21:35
  • I don't think this is possible, as there is no way for strings to implement `[[call]]`. To elaborate, it is not defined whether the returned value should be string or a function, and it cannot be both. – ASDFGerte Aug 16 '16 at 21:38
  • 2
    At any rate, is your question, essentially "can I write an infinitely curried function?"? If so, the answer is "yes" but with a catch - you can't have exactly your example without either knowing the number of arguments beforehand, or doing _something_ to end the chain. That _something_ could be adding `()` at the end and if your curry functionality sees no input, it returns the result. Other people add an `execute` method _on_ the returned curried function so you'd do `f(1)(2)(3).exec()` to get the result. It's somewhat easier to pre-determined curry, so you'll have like `curry(5)(StringCon)` – VLAZ Aug 16 '16 at 21:40
  • 1
    nicematt, I think I should be the one who feels sorry, I didn`t explain the question well. Take a look, I added some more explanation – Alex Aug 16 '16 at 21:52
  • Vld, that sound like something I wanted to ask. Sorry, I didn`t put it like that right away. – Alex Aug 16 '16 at 21:54

2 Answers2

2

You can, basically:

  • creating a function that returns StringCon;
  • memorizing arg in any property of this function;
  • getting the concatenation result using the property that stores arg;

You can't directly access concatenation result, because you'd have to re-call the returns, even using proxies. It's also possible to limit calls to return the final result in a limited call.


function StringCon(arg) {
    var f = function(x) {
        return StringCon(arg + x);
    };
    // var f = StringCon.bind(this, arg + x);

    f.value = arg;

    return f;
}

StringCon("I ")("am ")("new ")("to")(" JavaScript")
.value // -> "I am new to JavaScript"
0

Sounds like your after something like this:

function concat() {
    return Array.prototype.slice.call(arguments).join(' ');
}

Takes many arguments, concatenates them and does not return another function. (Am I missing something?)

koster1889
  • 126
  • 7
  • Yes. The function calls. The TO uses _currying_. – Thomas Junk Aug 16 '16 at 21:31
  • 2
    "does not return another function" The idea is that it *does* return a function as long as there are more possible arguments to take. It should return a partial application of that function. – Mike Cluck Aug 16 '16 at 21:32
  • Unfortunately, this is not what I am looking for, I would like to keep this formatting f(arg)(arg) – Alex Aug 16 '16 at 21:32