Curried functions
Bob Myers
rtm at gol.com
Mon Oct 19 07:30:43 UTC 2015
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
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20151019/e1d8e03a/attachment.html>
More information about the es-discuss
mailing list