Somehow, this missed the list... <br><br><div class="gmail_quote"><div dir="ltr">---------- Forwarded message ---------<br>From: Isiah Meadows <<a href="mailto:impinball@gmail.com">impinball@gmail.com</a>><br>Date: Wed, Sep 7, 2016, 12:03<br>Subject: Re: Function composition syntax<br>To:  <<a href="mailto:mikesamuel@gmail.com">mikesamuel@gmail.com</a>>,  <<a href="mailto:es-discuss@mozilla.org">es-discuss@mozilla.org</a>><br></div><br><br><div class="gmail_forwarded"><p dir="ltr">I was thinking in reverse order, but personally, I'm flexible on specifics like that. </p>
<br><div class="gmail_quote"><div dir="ltr">On Wed, Sep 7, 2016, 12:00 Isiah Meadows <<a href="mailto:isiahmeadows@gmail.com" target="_blank">isiahmeadows@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Inline. <br><br><div class="gmail_quote"><div dir="ltr">On Wed, Sep 7, 2016, 11:05 Mike Samuel <<a href="mailto:mikesamuel@gmail.com" target="_blank">mikesamuel@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">On Wed, Sep 7, 2016 at 10:10 AM, Isiah Meadows <<a href="mailto:isiahmeadows@gmail.com" target="_blank">isiahmeadows@gmail.com</a>> wrote:<br>
> I would like to see a function composition operator make it into the<br>
> language. Currently, there is:<br>
><br>
> - Lodash: `_.flow` and `_.flowRight` (lodash/fp alias: `_.compose` and<br>
> `_.composeRight`)<br>
> - Underscore: `_.compose`<br>
> - Ramda: `R.compose`<br>
> - Tons of npm modules: <a href="https://www.npmjs.com/search?q=function+composition" rel="noreferrer" target="_blank">https://www.npmjs.com/search?q=function+composition</a><br>
> - Numerous manual implementations<br>
><br>
> Function composition could be far more efficiently implemented in the<br>
> engine, in ways not possible at the language level:<br>
><br>
> 1. They can create pipelines to optimize multiple composition chains<br>
> together.<br>
> 2. They can avoid most of the closure allocation cost internally.<br>
> 3. The returned functions can internally use a separate call path to avoid<br>
> some of the [[Call]] boilerplate when called and when calling the functions<br>
> themselves (you don't need to verify twice).<br>
><br>
> Here's what I propose: a new infix operator `>=>` (operator and direction<br>
> can change) for composing two functions. It would do the following:<br>
<br>
What is the advantage of an operator over a static `Function.compose`<br>
or `Function.compose{Left,Right}`?<br></blockquote></div><div><br></div><div>See my section on why I suggested the operator instead of a function. One of the biggies is that the engine can statically optimize it, including inline arrow functions (no function object needs created). Another that I didn't list is that you are guaranteed 2 operands, so you can't "compose" 1 function<span style="font-size:13px">. Also, fewer parentheses are always better IMO. </span></div><div><span style="font-size:13px"><br></span></div><div><span style="font-size:13px">Oh, and there's a reason most `compose` functions accept multiple arguments: it would become way too unwieldy with all the parentheses otherwise. </span></div><div><br></div><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
> 1. Verify both operands are callable.<br>
<br>
What should happen if you try to compose something that only supports<br>
[[Call]] with something that only supports [[Construct]]?  For<br>
example, one might try to compose Object.freeze with a constructor to<br>
get a producer of frozen instances.<br></blockquote></div><div><br></div><div>I can adjust my proposal accordingly to cover "construct first when called as constructor". I missed that use case, but it's easy to fix.  </div><div><br></div><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
> 2. Create a callable-only function that calls its left operand with the<br>
> original arguments and `this`, then calling its right operand with the<br>
> result and the same `this`.<br>
<br>
> 3. Sets its length to the left operand.<br>
> 4. Return the new function.<br>
<br>
Is the new function strict only when both operands are strict or when<br>
either is strict?<br>
Or should it depend on the scope in which the operator appears?<br>
<br>
When the left operand is non-strict, is the composition the caller of<br>
the left operand?<br></blockquote></div><div><br></div><div>Composed functions would be similar to bound functions. So it shouldn't make a difference. </div><div><br></div><div>A transpiler can transform `f >=> g` directly to `function () { return g.call(this, f.apply(this, arguments)) }` (mod type checks).</div><div><br></div><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
> The reason I suggested an operator instead of a function:<br>
><br>
> 1. Fewer parentheses is always a plus.<br>
> 2. It allows engines to statically optimize functions in the middle (avoid<br>
> an extra function allocation), like with `f >=> x => console.log("x:" + x)`.<br>
<br>
This seems doable optimistically with Function.compose, though you'd<br>
have to back out when Function.compose is assigned.<br></blockquote></div><div><br></div><div>Engines don't usually make optimistic assumptions like that on the first pass, much less the first 100 or so (it takes thousands for V8's inliner to trigger, for example). They would have to cut a very specific special case for this (they don't even do that for `bind` IIRC), which I don't see as likely. </div><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
</blockquote></div></blockquote></div></div></div>