Curried functions

Hemanth H.M hemanth.hm at gmail.com
Mon Oct 19 10:16:05 UTC 2015


Something like [curry-this](http://nmotw.in/curry-this) would be nice to
have, so we could do something like:

```js
const add = (
    (a, b, c) => a + b + c
)::curry();
```

On Mon, Oct 19, 2015 at 1:00 PM, Bob Myers <rtm at gol.com> wrote:

> Of course, faster is always better, and native is always (?) faster.
>
> Having said that, with the fastest polyfill I have managed to write, given
>
> ```js
> function add(a, b, c) { return a + b + c; }
> var _add = currify(add);
> ````
>
> A call to `add(1,2,3)` takes 0.016 microseconds. A call to `_add(1)(2)(3)`
> takes 0.43 microseconds, 25 times longer. However, in the real world, it is
> more common to curry the function once and then invoke the curried function
> multiple times. If we do `add1 = _add(1)`, then each call to `add1(2)(3)`
> takes 0.30 microseconds, or 20 times longer. If we do `add2=_add(1, 2)`,
> then each call to `add2(3)` takes 0.10 microseconds, or 6 times longer. In
> relative terms this still seems like a large penalty, but in absolute
> terms, maybe not so much.
>
> On another topic, in terms of the approach for delivering this
> functionality, the best solution would seem to be to put this in a new
> standard library. If we want to instead extend the language syntax, of
> course we cannot introduce a new `curry` keyword, but maybe we can take a
> hint from the `*` used for generators and do something like
>
> ```js
> function #add(a, b, c) { }
> function :add(a, b, c) { }
> function ()add(a, b, c) { }
> function add((a, b, c)) { }
> ```
>
> etc. etc.
>
> --
> Bob
>
>
> On Mon, Oct 19, 2015 at 3:14 AM, Yongxu Ren <renyongxu at gmail.com> wrote:
>
>> As long as the total numbers of argument and types are consistent, which
>> are mostly true for curry functions, it should be able to easily optimized.
>>
>> Also, the polyfill for curry is just way too slow.
>>
>>
>> On Sat, Oct 17, 2015 at 11:51 PM, Isiah Meadows <isiahmeadows at gmail.com>
>> wrote:
>>
>>> Here's what I see as what's being proposed here. Correct me if I'm wrong.
>>>
>>> Function currying means it can be partially applied when only given
>>> some of its arguments. For example:
>>>
>>> ```js
>>> var add = _.curry(function (a, b, c) { return a + b + c })
>>>
>>> add(1)(2)(3) === 6
>>> add(1, 2)(3) === 6
>>> add(1)(2, 3) === 6
>>> add(1, 2, 3) === 6
>>>
>>> var add3 = add(3)
>>>
>>> add3(2, 1) === 6
>>> add3(2)(1) === 6
>>>
>>> var add5 = add(3, 2)
>>>
>>> add5(1) === 6
>>> ```
>>>
>>> That's exactly the behavior in Underscore's and Lodash's `_.curry()`.
>>> And that's exactly what I (and most others) would expect.
>>>
>>> -----
>>>
>>> As for Yongxu Ren's idea, that wouldn't be very performant, as engines
>>> have never been made to handle very highly nested closures very well.
>>> That's a great idea in statically typed, mostly pure functional
>>> languages (Haskell and OCaml both do that), but in languages that
>>> accept multiple arguments for a single function like Java or Python,
>>> it's hard to optimize at all. JavaScript is no exception. It's also
>>> cheaper to do a function length comparison than an unavoidable
>>> `IsCallable` check for each argument passed (which that would
>>> require).
>>>
>>> On Fri, Oct 16, 2015 at 11:41 PM, liorean <liorean at gmail.com> wrote:
>>> >
>>> > On 17 Oct 2015 04:48, "Yongxu Ren" <renyongxu at gmail.com> wrote:
>>> >>
>>> >> How about we use a different approach?
>>> >>
>>> >> Instead of allowing ```a(b)(c)``` for ```let a = (b,c) => b+c;```,
>>> >>
>>> >> Maybe we can use ```a(b,c)``` for ```let a = b => c => b + c```?
>>> >
>>> > Would that do any of the useful stuff you could reasonably want either
>>> > currying or partial application for, though? I mean the main use is
>>> that it
>>> > allows us to do
>>> >     let d=a(b);
>>> >     ...
>>> >     d(c);
>>> > And I don't really see how your desugaring a single multiple argument
>>> > application into several single parameter curried functions allows that
>>> > usefulness.
>>> >
>>> > It's the multiple applications to fill single parameter list thing
>>> that is
>>> > the most useful part of it, mostly as it allows caching the closure at
>>> any
>>> > step for reuse, not single application to fill multiple sequential
>>> single
>>> > parameter lists. Also, consider rest parameters, defaults etc. and
>>> whether
>>> > doing what you want for the simple example case would have weird or
>>> possibly
>>> > ambiguous meaning. Also, what happens to this value if the functions
>>> are old
>>> > style and not new style?
>>> >
>>> >
>>> > _______________________________________________
>>> > es-discuss mailing list
>>> > es-discuss at mozilla.org
>>> > https://mail.mozilla.org/listinfo/es-discuss
>>> >
>>>
>>>
>>>
>>> --
>>> Isiah Meadows
>>>
>>
>>
>> _______________________________________________
>> es-discuss mailing list
>> es-discuss at mozilla.org
>> https://mail.mozilla.org/listinfo/es-discuss
>>
>>
>
> _______________________________________________
> es-discuss mailing list
> es-discuss at mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss
>
>


-- 
*'I am what I am because of who we all are'*
h3manth.com <http://www.h3manth.com>
*-- Hemanth HM *
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20151019/44d59f3e/attachment-0001.html>


More information about the es-discuss mailing list