Re: Syntax sugar for partial application

2015-04-13 Thread Jussi Kalliokoski
On Mon, Apr 13, 2015 at 12:15 AM, liorean lior...@gmail.com wrote:

 On 12 April 2015 at 17:39, Jussi Kalliokoski
 jussi.kallioko...@gmail.com wrote:
  No, «this» is lexically bound to be that of the enclosing lexical
  scope in arrow functions, so it would be whatever that is. But that
  doesn't really matter as the function call to «foo» doesn't use the
  «this» of the arrow function.
 
  Exactly why you get `null` as `this`.

 Which makes the behaviour identical to that of the code as you wrote it.


If you looked at the gist I made, the placeholder syntax creates functions
where `this` remains untouched, so it can be separately bound, unlike in
your examples. See [1] for example of how the syntax desugars to ES6.


  Now, if we were to say your «foo» were actually «foo.bar», and you did
  the same replacement in the arrow function, the «this» value of the
  «bar» call would be «foo», so that's pretty much what is wanted as
  well. The case where this breaks is if you were to replace only the
  «bar» method with the arrow function, in which case it would use the
  lexical «this» instead of «foo», but that's obviously not the right
  transformation to use.
 
   This might not seem like such a big deal until you consider it in
   combination with the proposed bind syntax [1].
  
   Also in your examples, redefining `foo` will lead to different
 results.
   The
   placeholder syntax has a lot more room for optimization in the JIT
   compiler
   (the partially applied result is guaranteed to have no side effects
 for
   example, so the compiler can create a version of the original function
   where
   it can inline the specified arguments; less moving parts, easier to
   optimize).
 
  Yeah, it's susceptible to that problem, yes. Do you want me to fix
  that for you if you really want it?
 
  Your «foo(1, ?, 2);» is equivalent to «((f,a)=f(1,a,2))(foo)».
 
  Your «foo(?, 1, ???);» is equivalent to
 «((f,a,...b)=f(a,1,...b))(foo)».
  Your «foo(1, ???, 2);» is equivalent to
  «((f,...a)=f(...[1,...a,2]))(foo)».
 
 
  Your new examples directly execute the function instead of creating a new
  function. :) Which goes to show how it would be nice to have specific
 syntax
  for this to make it more obvious what's happening.

 Oops. I needed to actually add that extra argument as a separate fat arrow,
«(f=(...a)=f(...[1,...a,2]))(foo)» etc.

  I write my code pretty much the same way. However, it's hard for the
  compiler to trust that you're not changing things, regardless of style.

 Guess it'd be hard for it unless it has the knowledge of whether
 functions are pure or not, yes.

 I'd love for a compiler that can tell that I don't modify my arguments
 and thus optimises code like
 «
 let map= // Usage: map(function)(...array)
 (f,...acc)=(head,...tail)=(
 undefined===head
 ?acc
 :map(f,...acc,f(head))(...tail));
 »

 So that it doesn't actually create the «tail» array every recursion,
 just a narrower and narrower subarray of the same actual array, and
 likewise that the only thing that is done with «acc» is the production
 of an array that is identical to it with an addition of one element at
 its end, so doesn't break it down and rebuild it every recursion. And
 of course tail call optimisation on it, because that code is horrid
 without those optimisations.


Me too, yet while nothing is impossible, this sort of optimization (tail
call optimization aside) would be super difficult to implement, and
expensive too, because the compiler would have to check that the invariants
weren't violated on every call. However, there is hope in the light of
immutable collections proposals where the compiler has solid guarantee that
the collection isn't morphed mid-iteration and can safely use a cursor to a
sub-collection.

[1]
https://gist.github.com/anonymous/5c4f6ea07ad3017d61be#leading-placeholder


 --
 David liorean Andersson
 ___
 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: Syntax sugar for partial application

2015-04-12 Thread Jussi Kalliokoski
On Sat, Apr 11, 2015 at 4:54 AM, liorean lior...@gmail.com wrote:

 On 9 April 2015 at 16:11, Jussi Kalliokoski jussi.kallioko...@gmail.com
 wrote:
  On Thu, Apr 9, 2015 at 4:04 PM, liorean lior...@gmail.com wrote:
 
  Do we really need it?
  Your «foo(1, ?, 2);» is equivalent to «a=foo(1,a,2)».
  Your «foo(?, 1, ???);» is equivalent to «(a,...b)=foo(a,1,...b)».
  Your «foo(1, ???, 2);» is equivalent to «(...a)=foo(...[1,...a,2])».
 
 
  Not exactly. Using the placeholder syntax, `this` remains context
 dependent,
  whereas with your examples you get `null` as `this`.

 No, «this» is lexically bound to be that of the enclosing lexical
 scope in arrow functions, so it would be whatever that is. But that
 doesn't really matter as the function call to «foo» doesn't use the
 «this» of the arrow function.


Exactly why you get `null` as `this`.


 Now, if we were to say your «foo» were actually «foo.bar», and you did
 the same replacement in the arrow function, the «this» value of the
 «bar» call would be «foo», so that's pretty much what is wanted as
 well. The case where this breaks is if you were to replace only the
 «bar» method with the arrow function, in which case it would use the
 lexical «this» instead of «foo», but that's obviously not the right
 transformation to use.

  This might not seem like such a big deal until you consider it in
  combination with the proposed bind syntax [1].
 
  Also in your examples, redefining `foo` will lead to different results.
 The
  placeholder syntax has a lot more room for optimization in the JIT
 compiler
  (the partially applied result is guaranteed to have no side effects for
  example, so the compiler can create a version of the original function
 where
  it can inline the specified arguments; less moving parts, easier to
  optimize).

 Yeah, it's susceptible to that problem, yes. Do you want me to fix
 that for you if you really want it?

 Your «foo(1, ?, 2);» is equivalent to «((f,a)=f(1,a,2))(foo)».

Your «foo(?, 1, ???);» is equivalent to «((f,a,...b)=f(a,1,...b))(foo)».
 Your «foo(1, ???, 2);» is equivalent to
 «((f,...a)=f(...[1,...a,2]))(foo)».


Your new examples directly execute the function instead of creating a new
function. :) Which goes to show how it would be nice to have specific
syntax for this to make it more obvious what's happening.



 I guess I didn't think of these cases though, because I only use
 explicit arguments to my functions these days, I never use the «this»
 keyword. If I want a function to operate on an object, I pass that
 object into the function.
 I also try to not reuse my variables unless they are part of an
 iteration, in which case they are always local variables that are only
 handled in the iteration process itself. But that's a side issue, as
 it's about my code rather than precepts of the language.


I write my code pretty much the same way. However, it's hard for the
compiler to trust that you're not changing things, regardless of style.

Also because most of the standard library of the language operates on
`this` instead of a separate argument, combining standard library methods
with methods that have their data as an explicit argument often lead to
awkward reading order issues, e.g.

foo(x
  .filter(...)
  .map(...)
  .reduce(...)
)

whereas with the bind operator you get

x
  .filter(...)
  .map(...)
  .reduce(...)
  ::foo()


Which is where this proposal shines, if foo is a partially applied function.

But anyway, seems that this is not something people want, at least yet, so
I'll rest my case. :)


 --
 David liorean Andersson
 ___
 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: Syntax sugar for partial application

2015-04-12 Thread liorean
On 12 April 2015 at 17:39, Jussi Kalliokoski
jussi.kallioko...@gmail.com wrote:
 No, «this» is lexically bound to be that of the enclosing lexical
 scope in arrow functions, so it would be whatever that is. But that
 doesn't really matter as the function call to «foo» doesn't use the
 «this» of the arrow function.

 Exactly why you get `null` as `this`.

Which makes the behaviour identical to that of the code as you wrote it.

 Now, if we were to say your «foo» were actually «foo.bar», and you did
 the same replacement in the arrow function, the «this» value of the
 «bar» call would be «foo», so that's pretty much what is wanted as
 well. The case where this breaks is if you were to replace only the
 «bar» method with the arrow function, in which case it would use the
 lexical «this» instead of «foo», but that's obviously not the right
 transformation to use.

  This might not seem like such a big deal until you consider it in
  combination with the proposed bind syntax [1].
 
  Also in your examples, redefining `foo` will lead to different results.
  The
  placeholder syntax has a lot more room for optimization in the JIT
  compiler
  (the partially applied result is guaranteed to have no side effects for
  example, so the compiler can create a version of the original function
  where
  it can inline the specified arguments; less moving parts, easier to
  optimize).

 Yeah, it's susceptible to that problem, yes. Do you want me to fix
 that for you if you really want it?

 Your «foo(1, ?, 2);» is equivalent to «((f,a)=f(1,a,2))(foo)».

 Your «foo(?, 1, ???);» is equivalent to «((f,a,...b)=f(a,1,...b))(foo)».
 Your «foo(1, ???, 2);» is equivalent to
 «((f,...a)=f(...[1,...a,2]))(foo)».


 Your new examples directly execute the function instead of creating a new
 function. :) Which goes to show how it would be nice to have specific syntax
 for this to make it more obvious what's happening.

Oops. I needed to actually add that extra argument as a separate fat arrow,
   «(f=(...a)=f(...[1,...a,2]))(foo)» etc.

 I write my code pretty much the same way. However, it's hard for the
 compiler to trust that you're not changing things, regardless of style.

Guess it'd be hard for it unless it has the knowledge of whether
functions are pure or not, yes.

I'd love for a compiler that can tell that I don't modify my arguments
and thus optimises code like
«
let map= // Usage: map(function)(...array)
(f,...acc)=(head,...tail)=(
undefined===head
?acc
:map(f,...acc,f(head))(...tail));
»

So that it doesn't actually create the «tail» array every recursion,
just a narrower and narrower subarray of the same actual array, and
likewise that the only thing that is done with «acc» is the production
of an array that is identical to it with an addition of one element at
its end, so doesn't break it down and rebuild it every recursion. And
of course tail call optimisation on it, because that code is horrid
without those optimisations.
-- 
David liorean Andersson
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Syntax sugar for partial application

2015-04-10 Thread liorean
On 9 April 2015 at 16:11, Jussi Kalliokoski jussi.kallioko...@gmail.com wrote:
 On Thu, Apr 9, 2015 at 4:04 PM, liorean lior...@gmail.com wrote:

 Do we really need it?
 Your «foo(1, ?, 2);» is equivalent to «a=foo(1,a,2)».
 Your «foo(?, 1, ???);» is equivalent to «(a,...b)=foo(a,1,...b)».
 Your «foo(1, ???, 2);» is equivalent to «(...a)=foo(...[1,...a,2])».


 Not exactly. Using the placeholder syntax, `this` remains context dependent,
 whereas with your examples you get `null` as `this`.

No, «this» is lexically bound to be that of the enclosing lexical
scope in arrow functions, so it would be whatever that is. But that
doesn't really matter as the function call to «foo» doesn't use the
«this» of the arrow function.

Now, if we were to say your «foo» were actually «foo.bar», and you did
the same replacement in the arrow function, the «this» value of the
«bar» call would be «foo», so that's pretty much what is wanted as
well. The case where this breaks is if you were to replace only the
«bar» method with the arrow function, in which case it would use the
lexical «this» instead of «foo», but that's obviously not the right
transformation to use.

 This might not seem like such a big deal until you consider it in
 combination with the proposed bind syntax [1].

 Also in your examples, redefining `foo` will lead to different results. The
 placeholder syntax has a lot more room for optimization in the JIT compiler
 (the partially applied result is guaranteed to have no side effects for
 example, so the compiler can create a version of the original function where
 it can inline the specified arguments; less moving parts, easier to
 optimize).

Yeah, it's susceptible to that problem, yes. Do you want me to fix
that for you if you really want it?

Your «foo(1, ?, 2);» is equivalent to «((f,a)=f(1,a,2))(foo)».
Your «foo(?, 1, ???);» is equivalent to «((f,a,...b)=f(a,1,...b))(foo)».
Your «foo(1, ???, 2);» is equivalent to «((f,...a)=f(...[1,...a,2]))(foo)».





I guess I didn't think of these cases though, because I only use
explicit arguments to my functions these days, I never use the «this»
keyword. If I want a function to operate on an object, I pass that
object into the function.
I also try to not reuse my variables unless they are part of an
iteration, in which case they are always local variables that are only
handled in the iteration process itself. But that's a side issue, as
it's about my code rather than precepts of the language.
-- 
David liorean Andersson
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Syntax sugar for partial application

2015-04-09 Thread Jussi Kalliokoski
On Thu, Apr 9, 2015 at 4:04 PM, liorean lior...@gmail.com wrote:

 Do we really need it?
 Your «foo(1, ?, 2);» is equivalent to «a=foo(1,a,2)».
 Your «foo(?, 1, ???);» is equivalent to «(a,...b)=foo(a,1,...b)».
 Your «foo(1, ???, 2);» is equivalent to «(...a)=foo(...[1,...a,2])».


Not exactly. Using the placeholder syntax, `this` remains context
dependent, whereas with your examples you get `null` as `this`.

This might not seem like such a big deal until you consider it in
combination with the proposed bind syntax [1].

Also in your examples, redefining `foo` will lead to different results. The
placeholder syntax has a lot more room for optimization in the JIT compiler
(the partially applied result is guaranteed to have no side effects for
example, so the compiler can create a version of the original function
where it can inline the specified arguments; less moving parts, easier to
optimize).

[1] http://wiki.ecmascript.org/doku.php?id=strawman:bind_operator



 Also, the ? token is already taken by the ternary conditional
 operator. Do we really want to overload it here for a nullary
 operator/special form, when we have as low overhead syntax as we
 already do in fat arrows for doing the exact same thing?
 --
 David liorean Andersson
 ___
 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: Syntax sugar for partial application

2015-04-09 Thread Andrea Giammarchi
FWIW: agreed with others, it looks a pretty pointless sugar.
It doesn't seem to bring anything new or that needed to the language.

-1 here

On Thu, Apr 9, 2015 at 2:04 PM, liorean lior...@gmail.com wrote:

 Do we really need it?
 Your «foo(1, ?, 2);» is equivalent to «a=foo(1,a,2)».
 Your «foo(?, 1, ???);» is equivalent to «(a,...b)=foo(a,1,...b)».
 Your «foo(1, ???, 2);» is equivalent to «(...a)=foo(...[1,...a,2])».

 Also, the ? token is already taken by the ternary conditional
 operator. Do we really want to overload it here for a nullary
 operator/special form, when we have as low overhead syntax as we
 already do in fat arrows for doing the exact same thing?
 --
 David liorean Andersson
 ___
 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: Syntax sugar for partial application

2015-04-09 Thread liorean
Do we really need it?
Your «foo(1, ?, 2);» is equivalent to «a=foo(1,a,2)».
Your «foo(?, 1, ???);» is equivalent to «(a,...b)=foo(a,1,...b)».
Your «foo(1, ???, 2);» is equivalent to «(...a)=foo(...[1,...a,2])».

Also, the ? token is already taken by the ternary conditional
operator. Do we really want to overload it here for a nullary
operator/special form, when we have as low overhead syntax as we
already do in fat arrows for doing the exact same thing?
-- 
David liorean Andersson
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss