Re: Re: Curried functions

2015-10-19 Thread Bob Myers
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 <renyon...@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 <isiahmead...@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 <lior...@gmail.com> wrote:
>> >
>> > On 17 Oct 2015 04:48, "Yongxu Ren" <renyon...@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@mozilla.org
>> > https://mail.mozilla.org/listinfo/es-discuss
>> >
>>
>>
>>
>> --
>> Isiah Meadows
>>
>
>
> ___
> es-discuss mailing list
> es-discuss@mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss
>
>
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Re: Curried functions

2015-10-19 Thread Hemanth H.M
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 <r...@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 <renyon...@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 <isiahmead...@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 <lior...@gmail.com> wrote:
>>> >
>>> > On 17 Oct 2015 04:48, "Yongxu Ren" <renyon...@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 

Re: Re: Curried functions

2015-10-18 Thread Yongxu Ren
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 <isiahmead...@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 <lior...@gmail.com> wrote:
> >
> > On 17 Oct 2015 04:48, "Yongxu Ren" <renyon...@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@mozilla.org
> > https://mail.mozilla.org/listinfo/es-discuss
> >
>
>
>
> --
> Isiah Meadows
>
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Re: Curried functions

2015-10-17 Thread Isiah Meadows
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 <lior...@gmail.com> wrote:
>
> On 17 Oct 2015 04:48, "Yongxu Ren" <renyon...@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@mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss
>



-- 
Isiah Meadows
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Re: Curried functions

2015-10-16 Thread Michał Wadas
We can reverse this argument - why we needed Function.prototype.bind? It's
quite easy to polyfill (especially if you have Reflect.construct for edge
case of constructor or use eval for ES3/5 compatible implementation). There
were hundreds libraries providing .bind.

Returning threads about partially applied function without writing
boilerplate code or using external library are good argument to consider
implementing it into language.

And in my opinion method is more readable than function.
On Oct 16, 2015 8:36 PM, "Isiah Meadows"  wrote:

> An npm package (not mine): https://npm.im/curry
>
> Another simple implementation, ES3-compatible:
>
> ```js
> function curry(f) {
>   function curried() {
> if (arguments.length >= f.length) {
>   return f.apply(this, arguments);
> } else {
>   var args = []
>   for (var i = 0; i < arguments.length; i++) {
> args.push(arguments[i]);
>   }
>   return function () {
> var rest = args.slice();
> for (var i = 0; i < arguments.length; i++) {
>   rest.push(arguments[i]);
> }
> return curried.apply(this, rest);
>   }
> }
>   }
>   Object.defineProperty(curried, "length",
> Object.getOwnPropertyDescriptor(f, "length"));
>   return curried;
> }
> ```
>
> I don't need it often enough to want a standard library feature, but it's
> an easy function to make. And it does exactly what you want it to: curry a
> function without binding `this`.  If you want to make it a method decorator
> as well, you can use this (also ES3-compatible):
>
> ```js
> function helper(f) {
>   function curried() {
> if (arguments.length >= f.length) {
>   return f.apply(this, arguments);
> } else {
>   var args = []
>   for (var i = 0; i < arguments.length; i++) {
> args.push(arguments[i]);
>   }
>   return function () {
> var rest = args.slice();
> for (var i = 0; i < arguments.length; i++) {
>   rest.push(arguments[i]);
> }
> return curried.apply(this, rest);
>   }
> }
>   }
>   Object.defineProperty(curried, "length",
> Object.getOwnPropertyDescriptor(f, "length"));
>   return curried;
> }
>
> function curry(target, prop, desc) {
>   if (typeof target === "function") {
> // called on function
> return helper(target);
>   } else {
> // called as decorator
> desc.value = helper(desc.value);
>   }
> }
> ```
>
> On Fri, Oct 16, 2015, 05:39 Michał Wadas  wrote:
>
>>
>> 2015-10-15 22:20 GMT+02:00 Yongxu Ren :
>>
>>>
>>> First, I do not think anyone will ever intended to write code like this,
>>>
>>
>>
>> It's a wrong assumption - tons of library code depends on some argument
>> being null or undefined.
>>
>> function ajax(url, options) {
>> options = options || defaultOptions;
>> ...
>> }
>>
>> And in user code it can be called:
>>
>> ajax('menu.html');
>> ajax('menu.html', null);
>> ajax('menu.html', undefined);
>>
>>
>> BTW - I think ES2016 needs some way to curry function without binding
>> `this`. Function.prototype.curry or something like that.
>>
>>
>>
>>
>> ___
>> es-discuss mailing list
>> es-discuss@mozilla.org
>> https://mail.mozilla.org/listinfo/es-discuss
>>
>
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Re: Curried functions

2015-10-16 Thread Jeremy Darling
Maybe it belongs on the Function prototype, something like
Function.prototype.curry.  To me, having Curry built into the language
would be beneficial especially with the large push that is being seen
toward Functional development in JavaScript.

On Fri, Oct 16, 2015 at 2:16 PM, Yongxu Ren  wrote:

> Michał, thanks for pointing that out. Yes, optional options as the last
> optional parameter does exist, in multiple libraries. But I is there really
> existed any library that using arrow function like this? I doubt it.
>
> I think arrow function should only be used for lambda expression, callback
> and short in block function. It does cause incompatibility if anyone used
> arrow function for API interface, but doing that is anti-pattern.
>
> Curry function are often used in iterations, a slow polyfill will defeat
> the purpose.
> Considering this case:
> ```
> map (add 1) [1..10]
> ```
> I think native syntax support for curry will be a good thing, it can be
> used for JIT.
> However, javascript already too big, so why not just let existing syntax
> to do the work?
>
> ___
> es-discuss mailing list
> es-discuss@mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss
>
>
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Re: Curried functions

2015-10-16 Thread Yongxu Ren
Michał, thanks for pointing that out. Yes, optional options as the last
optional parameter does exist, in multiple libraries. But I is there really
existed any library that using arrow function like this? I doubt it.

I think arrow function should only be used for lambda expression, callback
and short in block function. It does cause incompatibility if anyone used
arrow function for API interface, but doing that is anti-pattern.

Curry function are often used in iterations, a slow polyfill will defeat
the purpose.
Considering this case:
```
map (add 1) [1..10]
```
I think native syntax support for curry will be a good thing, it can be
used for JIT.
However, javascript already too big, so why not just let existing syntax to
do the work?
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Re: Curried functions

2015-10-16 Thread Isiah Meadows
The main reason I don't use it is because I have bad experiences with
transparent currying in dynamic languages. It'll be one of those things I
almost never have the use case for. Kinda like SIMD and Math.imul. YMMV

On Fri, Oct 16, 2015, 15:27 Jeremy Darling  wrote:

> Maybe it belongs on the Function prototype, something like
> Function.prototype.curry.  To me, having Curry built into the language
> would be beneficial especially with the large push that is being seen
> toward Functional development in JavaScript.
>
> On Fri, Oct 16, 2015 at 2:16 PM, Yongxu Ren  wrote:
>
>> Michał, thanks for pointing that out. Yes, optional options as the last
>> optional parameter does exist, in multiple libraries. But I is there really
>> existed any library that using arrow function like this? I doubt it.
>>
>> I think arrow function should only be used for lambda expression,
>> callback and short in block function. It does cause incompatibility if
>> anyone used arrow function for API interface, but doing that is
>> anti-pattern.
>>
>> Curry function are often used in iterations, a slow polyfill will defeat
>> the purpose.
>> Considering this case:
>> ```
>> map (add 1) [1..10]
>> ```
>> I think native syntax support for curry will be a good thing, it can be
>> used for JIT.
>> However, javascript already too big, so why not just let existing syntax
>> to do the work?
>>
>> ___
>> es-discuss mailing list
>> es-discuss@mozilla.org
>> https://mail.mozilla.org/listinfo/es-discuss
>>
>>
> ___
> es-discuss mailing list
> es-discuss@mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss
>
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Curried functions

2015-10-16 Thread Isiah Meadows
I also prefer explicit currying and partial application, since it's
easier to reason about types. I would rather not deal with
transparent, keyword-only currying, since it can eventually become
hard to debug because it can get confusing as to how many parameters
are left before application. It's especially the case with dynamically
typed languages.

On Fri, Oct 16, 2015 at 1:27 AM, Bob Myers  wrote:
> It's trivially simply to write a function `currify` which essentially does
> what your proprosed `curry` keyword does.
>
> ```js
> function currify(f) {
>   return function _currify(flen, _f) {
> return (...args) => {
>   var remaining = flen - args.length;
>   return remaining <= 0 ?
> _f(...args) :
> _currify(remaining, (...args2) => _f(...args, ...args2));
> };
>   }(f.length, f);
> }
>
>
> function add(a, b, c) { return a + b + c; }
> var _add = currify(add);
>
> console.log(_add(1)(2)(3));
> console.log(_add(1, 2)(3));
> console.log(_add(1)(2, 3));
> console.log(_add(1, 2, 3));
> ```
>
> --
> Bob
>
>
>
> On Fri, Oct 16, 2015 at 1:15 AM, Michael McGlothlin
>  wrote:
>>
>> I dislike that syntax because it makes the order of operations mysterious.
>> I like the idea of currying but it should always be clear what is going on.
>> A couple parentheses would make things a lot more obvious.
>>
>> On Thu, Oct 15, 2015 at 8:02 AM, Mark S. Miller 
>> wrote:
>>>
>>> const add = a => b => a + b;
>>>
>>>
>>> On Thu, Oct 15, 2015 at 8:08 AM, Niloy Mondal 
>>> wrote:

 It would be really cool to have syntax to curry functions built into the
 languages. Something like...

 ```js
 curry function add(a, b) {
 return a + b;
 }

 add(2)(3); // 5

>
>
> ___
> es-discuss mailing list
> es-discuss@mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss
>



-- 
Isiah Meadows
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Re: Curried functions

2015-10-16 Thread Michał Wadas
2015-10-15 22:20 GMT+02:00 Yongxu Ren :

>
> First, I do not think anyone will ever intended to write code like this,
>


It's a wrong assumption - tons of library code depends on some argument
being null or undefined.

function ajax(url, options) {
options = options || defaultOptions;
...
}

And in user code it can be called:

ajax('menu.html');
ajax('menu.html', null);
ajax('menu.html', undefined);


BTW - I think ES2016 needs some way to curry function without binding
`this`. Function.prototype.curry or something like that.
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Re: Curried functions

2015-10-16 Thread liorean
Well, as I see it, there is nothing that currently could be done with
regards to this if what you desire is to make it automatic.
What we could add are various ways of manually doing this, either as
syntax or as library extensions. And then comes the question of which
way and what exactly.

Are you talking about pure currying, that is, taking a multiple
parameter function and turning if into a series of it's arity many
single argument functions, i.e:
(a,b,c)=>a+b+c
-->
 a=>b=>c=>a+b+c
?

Are you talking about partial application,i.e:
(a,b,c)=>a+b+c
-->
(a,b,c..._)=>a+b+c
OR
(a,b)=>(c,..._)=>a+b+c
OR
a=>(b,c,..._)=>a+b+c
OR
a=>b=>(c,..._)=>a+b+c
And where any zero argument applications return the same function?

Is it currying or partial application you want? How do you handle
functions that take rest parameters, optional parameters, true
variadric functions like e.g. sum that is theoretically zero to
infinity arity? or whose arity with regards to partial application
(and not the formal functionobject.length arity) is dependent on the
contents of those arguments? How do you handle this value? How do you
handle arguments object? How do you handle named autorecursion? Do you
want to be able to do this for constructors as well? How about getters
and setters? Generators? How do you handle extremely high argument
counts? How do you handle defaults? How do you handle argumentless
applications?

Automating this is in the language as it is would be a no-go for
backwards compatibility reasons I would say. Possibly you could have
manual currying, like what I wrote for rosettacode here:

Note the several caveats in that code. And sure, you could add syntax
for it instead of using a function like I do there, but it's still the
same explicit action, so would syntax really help in any way?
And for several cases you'd actually have to make a decision and stick
to it, or implement all the alternatives. Just see how I had to deal
with rest arguments there, because without two different versions, I
would have to choose either to handle rest arguments always with a
separate application, or never. If you want partial application,
that's slightly different in a few ways, but not notably harder.

-- 
David "liorean" Andersson
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Re: Curried functions

2015-10-16 Thread Yongxu Ren
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```?
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Re: Curried functions

2015-10-16 Thread liorean
On 17 Oct 2015 04:48, "Yongxu Ren" <renyon...@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@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Re: Curried functions

2015-10-16 Thread Isiah Meadows
An npm package (not mine): https://npm.im/curry

Another simple implementation, ES3-compatible:

```js
function curry(f) {
  function curried() {
if (arguments.length >= f.length) {
  return f.apply(this, arguments);
} else {
  var args = []
  for (var i = 0; i < arguments.length; i++) {
args.push(arguments[i]);
  }
  return function () {
var rest = args.slice();
for (var i = 0; i < arguments.length; i++) {
  rest.push(arguments[i]);
}
return curried.apply(this, rest);
  }
}
  }
  Object.defineProperty(curried, "length",
Object.getOwnPropertyDescriptor(f, "length"));
  return curried;
}
```

I don't need it often enough to want a standard library feature, but it's
an easy function to make. And it does exactly what you want it to: curry a
function without binding `this`.  If you want to make it a method decorator
as well, you can use this (also ES3-compatible):

```js
function helper(f) {
  function curried() {
if (arguments.length >= f.length) {
  return f.apply(this, arguments);
} else {
  var args = []
  for (var i = 0; i < arguments.length; i++) {
args.push(arguments[i]);
  }
  return function () {
var rest = args.slice();
for (var i = 0; i < arguments.length; i++) {
  rest.push(arguments[i]);
}
return curried.apply(this, rest);
  }
}
  }
  Object.defineProperty(curried, "length",
Object.getOwnPropertyDescriptor(f, "length"));
  return curried;
}

function curry(target, prop, desc) {
  if (typeof target === "function") {
// called on function
return helper(target);
  } else {
// called as decorator
desc.value = helper(desc.value);
  }
}
```

On Fri, Oct 16, 2015, 05:39 Michał Wadas  wrote:

>
> 2015-10-15 22:20 GMT+02:00 Yongxu Ren :
>
>>
>> First, I do not think anyone will ever intended to write code like this,
>>
>
>
> It's a wrong assumption - tons of library code depends on some argument
> being null or undefined.
>
> function ajax(url, options) {
> options = options || defaultOptions;
> ...
> }
>
> And in user code it can be called:
>
> ajax('menu.html');
> ajax('menu.html', null);
> ajax('menu.html', undefined);
>
>
> BTW - I think ES2016 needs some way to curry function without binding
> `this`. Function.prototype.curry or something like that.
>
>
>
>
> ___
> es-discuss mailing list
> es-discuss@mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss
>
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Curried functions

2015-10-15 Thread Niloy Mondal
It would be really cool to have syntax to curry functions built into the
languages. Something like...

```js
curry function add(a, b) {
return a + b;
}

add(2)(3); // 5
```
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Re: Curried functions

2015-10-15 Thread Yongxu Ren
Sorry I actually didn’t mean to use this for currying
```
const add = a => b => a + b;
```
This was directly copied from Mark's example, I was thinking about making the 
non-nested arrow functional.
My idea is if you define
```
const add = (a,b) => a + b;
```
you will be able to use either ```add(a,b)``` or ```add(a)(b)```___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Re: Curried functions

2015-10-15 Thread Jeremy Darling
If I understand your question correctly, your asking if fat arrow functions
could be auto curried?  I think this would be great, but anything using
...rest arguments could never be curried without finalization.

On Thu, Oct 15, 2015 at 2:58 PM, Yongxu Ren  wrote:

> Sorry I actually didn’t mean to use this for currying
> ```
> const add = a => b => a + b;
> ```
> This was directly copied from Mark's example, I was thinking about making
> the non-nested arrow functional.
> My idea is if you define
> ```
> const add = (a,b) => a + b;
> ```
> you will be able to use either ```add(a,b)``` or ```add(a)(b)```
>
> ___
> es-discuss mailing list
> es-discuss@mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss
>
>
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Re: Curried functions

2015-10-15 Thread Yongxu Ren
Jeremy,
I think you were talking about are cases like this:
```
let add = (x,y,...z) => x+y+Math.max(z);
```
Since rested argument always has to be the last parameter, I guess this 
should’t be a big problem if we can interpret this case as:

```
//regular function and the rested argument are not curried by default
let add = (x,y) => function(...z){
return x+y+Math.max(z);
};
```
As long as we express it consistently, this shouldn’t be a problem.

Also, I do not believe this will be a problem:

> Too late, ```add(a)``` already returns ```a + undefined```.

First, I do not think anyone will ever intended to write code like this,

Second, if someone accidentally returned a function instead of an object, or a 
different function, it should be very obvious and can be very easily debugged.

___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Curried functions

2015-10-15 Thread Waldemar Horwat

On 10/15/2015 12:58, Yongxu Ren wrote:

Sorry I actually didn’t mean to use this for currying
```
const add = a => b => a + b;
```
This was directly copied from Mark's example, I was thinking about making the 
non-nested arrow functional.
My idea is if you define
```
const add = (a,b) => a + b;
```
you will be able to use either ```add(a,b)``` or ```add(a)(b)```


Alexander's point still stands.  This would break compatibility, which makes it 
a non-starter.  It also becomes dubious with variable numbers of parameters.

Waldemar

___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Fwd: Curried functions

2015-10-15 Thread Bob Myers
It's trivially simply to write a function `currify` which essentially does
what your proprosed `curry` keyword does.

```js
function currify(f) {
  return function _currify(flen, _f) {
return (...args) => {
  var remaining = flen - args.length;
  return remaining <= 0 ?
_f(...args) :
_currify(remaining, (...args2) => _f(...args, ...args2));
};
  }(f.length, f);
}


function add(a, b, c) { return a + b + c; }
var _add = currify(add);

console.log(_add(1)(2)(3));
console.log(_add(1, 2)(3));
console.log(_add(1)(2, 3));
console.log(_add(1, 2, 3));
```

--
Bob



On Fri, Oct 16, 2015 at 1:15 AM, Michael McGlothlin <
mike.mcgloth...@gmail.com> wrote:

> I dislike that syntax because it makes the order of operations mysterious.
> I like the idea of currying but it should always be clear what is going on.
> A couple parentheses would make things a lot more obvious.
>
> On Thu, Oct 15, 2015 at 8:02 AM, Mark S. Miller 
> wrote:
>
>> const add = a => b => a + b;
>>
>>
>> On Thu, Oct 15, 2015 at 8:08 AM, Niloy Mondal 
>> wrote:
>>
>>> It would be really cool to have syntax to curry functions built into the
>>> languages. Something like...
>>>
>>> ```js
>>> curry function add(a, b) {
>>> return a + b;
>>> }
>>>
>>> add(2)(3); // 5
>>>
>>>
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Curried functions

2015-10-15 Thread Michael McGlothlin
I dislike that syntax because it makes the order of operations mysterious.
I like the idea of currying but it should always be clear what is going on.
A couple parentheses would make things a lot more obvious.

On Thu, Oct 15, 2015 at 8:02 AM, Mark S. Miller  wrote:

> const add = a => b => a + b;
>
>
> On Thu, Oct 15, 2015 at 8:08 AM, Niloy Mondal 
> wrote:
>
>> It would be really cool to have syntax to curry functions built into the
>> languages. Something like...
>>
>> ```js
>> curry function add(a, b) {
>> return a + b;
>> }
>>
>> add(2)(3); // 5
>> ```
>>
>> ___
>> es-discuss mailing list
>> es-discuss@mozilla.org
>> https://mail.mozilla.org/listinfo/es-discuss
>>
>>
>
>
> --
> Cheers,
> --MarkM
>
> ___
> es-discuss mailing list
> es-discuss@mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss
>
>
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Curried functions

2015-10-15 Thread Alexander Jones
Too late, `add(a)` already returns `a + undefined`.

No reason why `const add = curry((a, b) => a + b)` couldn't work though?
Arrow functions have a length property AFAIK.

On Thursday, 15 October 2015, Yongxu Ren  wrote:

> How about making arrow function curry by default?
>
> const add = a => b => a + b;
>
> this will only works in case
>
> add(a)(b);
>
> But it won’t work if you do this
>
> add(a,b);
>
> If we could let arrow to work for both
>
> add(a)(b) and add(a,b)
>
> it will release the full power of functional programming and allow us to
> write code like in OCaml, F# or Haskell
>
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Re: Curried functions

2015-10-15 Thread Yongxu Ren
How about making arrow function curry by default?

const add = a => b => a + b;
this will only works in case
add(a)(b);
But it won’t work if you do this
add(a,b);
If we could let arrow to work for both
add(a)(b) and add(a,b)
it will release the full power of functional programming and allow us to write 
code like in OCaml, F# or Haskell___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss