The "Pipeline" Operator - Making multiple function calls look great

Gilbert B Garza gilbertbgarza at gmail.com
Sun Dec 6 20:13:34 UTC 2015


Status update: The JS community has shown [lots of excitement](
https://twitter.com/markdalgleish/status/673581814028492800) for the idea
of this proposal, but the syntax is still being debated. I outlined two
alternatives [in this GitHub issue](
https://github.com/mindeavor/es-pipeline-operator/issues/4), one of which I
will post here since it is my current favorite:

## Placeholder Arguments

The alternative is to have a new syntax for "placeholder arguments" –
basically, slots waiting to be filled by the next function call. For
example:

```js
//
// Placeholder style
//
run("hello") |> withThis(10, #);
// is equivalent to
withThis( 10, run("hello") );

//
// More complicated example
//
run("hello") |> withThis(10, #) |> andThis(#, 20);
// is equivalent to
andThis( withThis( 10, run("hello") ), 20 );
```

### Pros / Cons

- [pro] Very explicit (no surprises)
- [pro] Less function calls
- [pro] Compatible with even more of the JavaScript ecosystem
- [con] Requires more new syntax
- [con] Usage of the hash operator (#) would probably be hard to define
outside coupled use with pipeline operator (this problem could be avoided
by simply making it illegal)


On Tue, Nov 10, 2015 at 4:44 PM, Gilbert B Garza <gilbertbgarza at gmail.com>
wrote:

> Ah, sorry for being unclear. You're right, in the case of manual currying,
> the closure can not and should not be optimized away.
>
> I was talking about the case where you have arrow function literals. For
> example:
>
> ```js
> var bounded = 750
>     |> s => Math.max(100, s)
>     |> s => Math.min(0, s);
> ```
>
> I imagine if the compiler sees arrow functions used in this specific
> manner, it could automatically optimize to the following:
>
> ```js
> var bounded = Math.min( 0, Math.max(100, 750) )
> ```
>
> Semantically, they are equivalent; no closures nor scopes were effectively
> used in the intermediary arrow functions.
>
>
> On Tue, Nov 10, 2015 at 4:34 PM, Isiah Meadows <isiahmeadows at gmail.com>
> wrote:
>
>> Not with your semantics. It has to generate a closure each time, because
>> of the possibility it can't be used elsewhere. That's impossible to know
>> ahead of time if the variable is ever used outside of its closure or as a
>> value. In the case below, it should only log thrice. Otherwise, it's
>> unexpected behavior.
>>
>> ```js
>> function add(x) {
>>   console.log("Hit!");
>>   return y => x + y;
>> }
>>
>> let inc = add(1);
>>
>> 1 |> inc |> inc |> add(2) |> add(3);
>>
>> // Hit!
>> // Hit!
>> // Hit!
>> ```
>>
>> On Tue, Nov 10, 2015, 15:08 Gilbert B Garza <gilbertbgarza at gmail.com>
>> wrote:
>>
>> Normally yes, but since the pipeline operator is a pure function, I think
>> it's possible for the compiler to optimize away the intermediate arrow
>> functions. I mention this in the "Functions with Multiple Arguments"
>> section https
>> <https://github.com/mindeavor/ES7-pipeline-operator#functions-with-multiple-arguments>
>> ://
>> <https://github.com/mindeavor/ES7-pipeline-operator#functions-with-multiple-arguments>
>> github.com
>> <https://github.com/mindeavor/ES7-pipeline-operator#functions-with-multiple-arguments>
>> /
>> <https://github.com/mindeavor/ES7-pipeline-operator#functions-with-multiple-arguments>
>> mindeavor
>> <https://github.com/mindeavor/ES7-pipeline-operator#functions-with-multiple-arguments>
>> /
>> <https://github.com/mindeavor/ES7-pipeline-operator#functions-with-multiple-arguments>
>> ES7-pipeline-operator#functions
>> <https://github.com/mindeavor/ES7-pipeline-operator#functions-with-multiple-arguments>
>> -with-multiple-arguments
>> <https://github.com/mindeavor/ES7-pipeline-operator#functions-with-multiple-arguments>
>>
>>
>> On Tue, Nov 10, 2015 at 12:52 PM, Isiah Meadows <isiahmeadows at gmail.com>
>> wrote:
>>
>> Inline
>>
>> On Tue, Nov 10, 2015 at 12:52 PM, Kevin Smith <zenparsing at gmail.com>
>> wrote:
>> >> - I don't like the requirement to use the keyword `this` to compose
>> >> functions. JS already has many features to support the keyword `this`:
>> >> prototypes, method invocations, function binding, arrow functions, and
>> >> probably others. I prefer a feature that assists the other side of the
>> >> spectrum.
>> >
>> >
>> > Yep - a well documented critique.  It depends on your point of view, I
>> > think.  If you view these things as "extension methods", then using
>> `this`
>> > makes more sense.
>> >
>> >> - The fact that there are new semantics to what looks like a normal
>> >> function call (e.g. `->map(...)`) doesn't set well with me. You could
>> argue
>> >> that it's something to get used to. Even in that case, I would expect
>> the
>> >> first argument I give to `map` to stay the first argument.
>> >
>> >
>> > This is a reasonable objection, I think.
>>
>> Not to mention it's still a point of contention:
>> https
>> <https://github.com/zenparsing/es-function-bind/issues/26#issuecomment-154130932>
>> ://
>> <https://github.com/zenparsing/es-function-bind/issues/26#issuecomment-154130932>
>> github.com
>> <https://github.com/zenparsing/es-function-bind/issues/26#issuecomment-154130932>
>> /
>> <https://github.com/zenparsing/es-function-bind/issues/26#issuecomment-154130932>
>> zenparsing
>> <https://github.com/zenparsing/es-function-bind/issues/26#issuecomment-154130932>
>> /
>> <https://github.com/zenparsing/es-function-bind/issues/26#issuecomment-154130932>
>> es-function-bind
>> <https://github.com/zenparsing/es-function-bind/issues/26#issuecomment-154130932>
>> /issues/26#issuecomment-154130932
>> <https://github.com/zenparsing/es-function-bind/issues/26#issuecomment-154130932>
>> (from here, down)
>>
>> >
>> >> With the pipeline operator, partial application is left to the
>> developer.
>> >> They can choose to use arrow functions, or to curry their functions. I
>> think
>> >> this is the best option since it keeps things simple (no new
>> semantics), and
>> >> remains readable – see the "Function with Multiple Arguments" section
>> in the
>> >> GitHub link https <https://github.com/mindeavor/ES7-pipeline-operator>
>> :// <https://github.com/mindeavor/ES7-pipeline-operator>github.com
>> <https://github.com/mindeavor/ES7-pipeline-operator>/
>> <https://github.com/mindeavor/ES7-pipeline-operator>mindeavor
>> <https://github.com/mindeavor/ES7-pipeline-operator>/
>> <https://github.com/mindeavor/ES7-pipeline-operator>ES7-pipeline-operator
>> <https://github.com/mindeavor/ES7-pipeline-operator>
>> >
>> >
>> > I agree that your proposal wins points for simplicity (both semantic and
>> > syntactic), but having to create an arrow function to pass more than one
>> > argument feels a bit awkward and seems to defeat some of the readability
>> > benefit.
>>
>> Not to mention it would be pretty slow. That's going to be creating a
>> closure each call. Engines still struggle with making closures fast.
>> It's non-trivial at runtime to create a closure that's performant.
>>
>> >
>> >
>> >
>> > _______________________________________________
>> > es-discuss mailing list
>> > es-discuss at mozilla.org
>> > https <https://mail.mozilla.org/listinfo/es-discuss>://
>> <https://mail.mozilla.org/listinfo/es-discuss>mail.mozilla.org
>> <https://mail.mozilla.org/listinfo/es-discuss>/
>> <https://mail.mozilla.org/listinfo/es-discuss>listinfo
>> <https://mail.mozilla.org/listinfo/es-discuss>/
>> <https://mail.mozilla.org/listinfo/es-discuss>es-discuss
>> <https://mail.mozilla.org/listinfo/es-discuss>
>> >
>>
>> --
>> Isiah Meadows
>>
>>
>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20151206/a132a6d4/attachment.html>


More information about the es-discuss mailing list