The "Pipeline" Operator - Making multiple function calls look great
I agree 100% that this would make a great addition to JS!
We've had the pipeline operator in Stratified JS for a while - see conductance.io/reference#sjs:%23language/syntax::double-dot - , and in our experience it makes a lot of code much more readable.
We call it '..' (the 'doubledot operator') instead of '|>' - IMO this
feels more aligned with existing JS syntax and less jarring than '|>'.
I agree 100% that this would make a great addition to JS! We've had the pipeline operator in Stratified JS for a while - see https://conductance.io/reference#sjs:%23language/syntax::double-dot - , and in our experience it makes a lot of code much more readable. We call it '..' (the 'doubledot operator') instead of '|>' - IMO this feels more aligned with existing JS syntax and less jarring than '|>'. On Tue, Nov 10, 2015 at 10:54 AM, Gilbert B Garza <gilbertbgarza at gmail.com> wrote: > Hello, I'm a JavaScript programmer and instructor who loves functional > programming and writing concise, readable code. I think in general > JavaScript supports programming in a functional style quite well. However, > there is one small missing piece that I miss from other FP languages: the > simple-yet-useful pipeline operator. > > Similar to F#, Elixir, Elm, and other FP languages, the pipeline operator |> > helps make multiple function invocations more readable. Basically, > `sqrt(64)` is equivalent to `64 |> sqrt`. For example, given the following > functions: > > ```js > function doubleSay (str) { return str + ", " + str; } > function capitalize (str) { return str[0].toUpperCase() + str.substring(1); > } > function exclaim (str) { return str + '!'; } > ``` > > you could use the pipeline operator to expand your invocations for > readability: > > ```js > // old way: > // var result = exclaim(capitalize(doubleSay("hello"))); > > // new way: > var result = "hello" > |> doubleSay > |> capitalize > |> exclaim; > > // or, if you like one-liners: > var result = "hello" |> doubleSay |> capitalize |> exclaim > > result //=> "Hello, hello!" > ``` > > You can see a few more examples, including an advanced example with > Promises, here: https://github.com/mindeavor/ES7-pipeline-operator > > I'm inclined to think this feature is small and straight-forward to > implement. Other than the operator, there are no new semantics. The syntax > transformation is simple, and all existing code would remain unaffected. > > Although small, this feature increases the expressiveness of JavaScript > significantly by opening more API design possibilities. You can see this in > the link I included above. > > Thanks for reading. Any thoughts or comments? > > _______________________________________________ > es-discuss mailing list > es-discuss at mozilla.org > https://mail.mozilla.org/listinfo/es-discuss > -- Alexander Fritze http://onilabs.com
I find this interesting, indeed.
Although, I believe the ( ) are like "representations OF a function call". I felt like if there was something missing there! What about something like this, then?
// exclaim(capitalize(doubleSay("hello"))); doubleSay("hello") |> capitalize |> exclaim;
For me, this feels like "calling doubleSay", then passing its results for capitalize, and its result to exclaim.
Some interesting implementations coupd be done with async await, I believe!
I find this interesting, indeed. Although, I believe the ( ) are like "representations OF a function call". I felt like if there was something missing there! What about something like this, then? // exclaim(capitalize(doubleSay("hello"))); doubleSay("hello") |> capitalize |> exclaim; For me, this feels like "calling doubleSay", then passing its results for capitalize, and its result to exclaim. Some interesting implementations coupd be done with async await, I believe! On Tue, Nov 10, 2015 at 3:09 PM, Alexander Fritze <alex at onilabs.com> wrote: > I agree 100% that this would make a great addition to JS! > > We've had the pipeline operator in Stratified JS for a while - see > https://conductance.io/reference#sjs:%23language/syntax::double-dot - > , and in our experience it makes a lot of code much more readable. > > We call it '..' (the 'doubledot operator') instead of '|>' - IMO this > feels more aligned with existing JS syntax and less jarring than '|>'. > > > On Tue, Nov 10, 2015 at 10:54 AM, Gilbert B Garza > <gilbertbgarza at gmail.com> wrote: > > Hello, I'm a JavaScript programmer and instructor who loves functional > > programming and writing concise, readable code. I think in general > > JavaScript supports programming in a functional style quite well. > However, > > there is one small missing piece that I miss from other FP languages: the > > simple-yet-useful pipeline operator. > > > > Similar to F#, Elixir, Elm, and other FP languages, the pipeline > operator |> > > helps make multiple function invocations more readable. Basically, > > `sqrt(64)` is equivalent to `64 |> sqrt`. For example, given the > following > > functions: > > > > ```js > > function doubleSay (str) { return str + ", " + str; } > > function capitalize (str) { return str[0].toUpperCase() + > str.substring(1); > > } > > function exclaim (str) { return str + '!'; } > > ``` > > > > you could use the pipeline operator to expand your invocations for > > readability: > > > > ```js > > // old way: > > // var result = exclaim(capitalize(doubleSay("hello"))); > > > > // new way: > > var result = "hello" > > |> doubleSay > > |> capitalize > > |> exclaim; > > > > // or, if you like one-liners: > > var result = "hello" |> doubleSay |> capitalize |> exclaim > > > > result //=> "Hello, hello!" > > ``` > > > > You can see a few more examples, including an advanced example with > > Promises, here: https://github.com/mindeavor/ES7-pipeline-operator > > > > I'm inclined to think this feature is small and straight-forward to > > implement. Other than the operator, there are no new semantics. The > syntax > > transformation is simple, and all existing code would remain unaffected. > > > > Although small, this feature increases the expressiveness of JavaScript > > significantly by opening more API design possibilities. You can see this > in > > the link I included above. > > > > Thanks for reading. Any thoughts or comments? > > > > _______________________________________________ > > es-discuss mailing list > > es-discuss at mozilla.org > > https://mail.mozilla.org/listinfo/es-discuss > > > > > > -- > Alexander Fritze > http://onilabs.com > _______________________________________________ > es-discuss mailing list > es-discuss at mozilla.org > https://mail.mozilla.org/listinfo/es-discuss > -- *Felipe N. Moura* Senior Web Developer and System Analyst. Website: http://felipenmoura.com Twitter: @felipenmoura <http://twitter.com/felipenmoura> LinkedIn: http://goo.gl/qGmq Meet some of my projects: BrazilJS Conference <http://braziljs.com.br/> | BrazilJS Foundation <http://braziljs.org> --------------------------------- *Changing the world* is the least I expect from myself! -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20151110/ec422dd1/attachment-0001.html>
Have you seen zenparsing/es-function-bind ? It's a
function bind-syntax proposal which covers some of the same use cases
(although by binding the this
parameter instead of passing the first
arg). We've also explored some alternatives more closely aligned with your
proposal. Check out the discussion here for the latest state:
zenparsing/es-function-bind#26
and
feel free to comment!
Hi Gilbert, Have you seen https://github.com/zenparsing/es-function-bind/ ? It's a function bind-syntax proposal which covers some of the same use cases (although by binding the `this` parameter instead of passing the first arg). We've also explored some alternatives more closely aligned with your proposal. Check out the discussion here for the latest state: https://github.com/zenparsing/es-function-bind/issues/26#issuecomment-154237803 and feel free to comment! On Tue, Nov 10, 2015 at 11:54 AM Gilbert B Garza <gilbertbgarza at gmail.com> wrote: > Hello, I'm a JavaScript programmer and instructor who loves functional > programming and writing concise, readable code. I think in general > JavaScript supports programming in a functional style quite well. However, > there is one small missing piece that I miss from other FP languages: the > simple-yet-useful pipeline operator. > > Similar to F#, Elixir, Elm, and other FP languages, the pipeline operator > |> helps make multiple function invocations more readable. Basically, > `sqrt(64)` is equivalent to `64 |> sqrt`. For example, given the following > functions: > > ```js > function doubleSay (str) { return str + ", " + str; } > function capitalize (str) { return str[0].toUpperCase() + > str.substring(1); } > function exclaim (str) { return str + '!'; } > ``` > > you could use the pipeline operator to expand your invocations for > readability: > > ```js > // old way: > // var result = exclaim(capitalize(doubleSay("hello"))); > > // new way: > var result = "hello" > |> doubleSay > |> capitalize > |> exclaim; > > // or, if you like one-liners: > var result = "hello" |> doubleSay |> capitalize |> exclaim > > result //=> "Hello, hello!" > ``` > > You can see a few more examples, including an advanced example with > Promises, here: https://github.com/mindeavor/ES7-pipeline-operator > > I'm inclined to think this feature is small and straight-forward to > implement. Other than the operator, there are no new semantics. The syntax > transformation is simple, and all existing code would remain unaffected. > > Although small, this feature increases the expressiveness of JavaScript > significantly by opening more API design possibilities. You can see this in > the link I included above. > > Thanks for reading. Any thoughts or comments? > _______________________________________________ > 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/20151110/07c70694/attachment.html>
Kevin: Ah yes, I have studied function-bind, but I have two issues with it:
-
I don't like the requirement to use the keyword
this
to compose functions. JS already has many features to support the keywordthis
: prototypes, method invocations, function binding, arrow functions, and probably others. I prefer a feature that assists the other side of the spectrum. -
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.
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 mindeavor/ES7
Kevin: Ah yes, I have studied function-bind, but I have two issues with it: - 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. - 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. 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://github.com/mindeavor/ES7-pipeline-operator On Tue, Nov 10, 2015 at 11:15 AM, Kevin Smith <zenparsing at gmail.com> wrote: > Hi Gilbert, > > Have you seen https://github.com/zenparsing/es-function-bind/ ? It's a > function bind-syntax proposal which covers some of the same use cases > (although by binding the `this` parameter instead of passing the first > arg). We've also explored some alternatives more closely aligned with your > proposal. Check out the discussion here for the latest state: > https://github.com/zenparsing/es-function-bind/issues/26#issuecomment-154237803 and > feel free to comment! > > On Tue, Nov 10, 2015 at 11:54 AM Gilbert B Garza <gilbertbgarza at gmail.com> > wrote: > >> Hello, I'm a JavaScript programmer and instructor who loves functional >> programming and writing concise, readable code. I think in general >> JavaScript supports programming in a functional style quite well. However, >> there is one small missing piece that I miss from other FP languages: the >> simple-yet-useful pipeline operator. >> >> Similar to F#, Elixir, Elm, and other FP languages, the pipeline operator >> |> helps make multiple function invocations more readable. Basically, >> `sqrt(64)` is equivalent to `64 |> sqrt`. For example, given the following >> functions: >> >> ```js >> function doubleSay (str) { return str + ", " + str; } >> function capitalize (str) { return str[0].toUpperCase() + >> str.substring(1); } >> function exclaim (str) { return str + '!'; } >> ``` >> >> you could use the pipeline operator to expand your invocations for >> readability: >> >> ```js >> // old way: >> // var result = exclaim(capitalize(doubleSay("hello"))); >> >> // new way: >> var result = "hello" >> |> doubleSay >> |> capitalize >> |> exclaim; >> >> // or, if you like one-liners: >> var result = "hello" |> doubleSay |> capitalize |> exclaim >> >> result //=> "Hello, hello!" >> ``` >> >> You can see a few more examples, including an advanced example with >> Promises, here: https://github.com/mindeavor/ES7-pipeline-operator >> >> I'm inclined to think this feature is small and straight-forward to >> implement. Other than the operator, there are no new semantics. The syntax >> transformation is simple, and all existing code would remain unaffected. >> >> Although small, this feature increases the expressiveness of JavaScript >> significantly by opening more API design possibilities. You can see this in >> the link I included above. >> >> Thanks for reading. Any thoughts or comments? >> _______________________________________________ >> 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/20151110/3e2c4269/attachment.html>
Although, I believe the ( ) are like "representations OF a function call". I felt like if there was something missing there! What about something like this, then?
// exclaim(capitalize(doubleSay("hello")));
doubleSay("hello") |> capitalize |> exclaim;
Felipe: That is perfectly valid syntax under the current proposal, and you are free to choose to write your code in that way :)
> > Although, I believe the ( ) are like "representations OF a function call". > I felt like if there was something missing there! > What about something like this, then? > // exclaim(capitalize(doubleSay("hello"))); > doubleSay("hello") |> capitalize |> exclaim; Felipe: That is perfectly valid syntax under the current proposal, and you are free to choose to write your code in that way :) On Tue, Nov 10, 2015 at 11:15 AM, Felipe Nascimento de Moura < felipenmoura at gmail.com> wrote: > I find this interesting, indeed. > > > For me, this feels like "calling doubleSay", then passing its results for > capitalize, and its result to exclaim. > > Some interesting implementations coupd be done with async await, I believe! > > > > > On Tue, Nov 10, 2015 at 3:09 PM, Alexander Fritze <alex at onilabs.com> > wrote: > >> I agree 100% that this would make a great addition to JS! >> >> We've had the pipeline operator in Stratified JS for a while - see >> https://conductance.io/reference#sjs:%23language/syntax::double-dot - >> , and in our experience it makes a lot of code much more readable. >> >> We call it '..' (the 'doubledot operator') instead of '|>' - IMO this >> feels more aligned with existing JS syntax and less jarring than '|>'. >> >> >> On Tue, Nov 10, 2015 at 10:54 AM, Gilbert B Garza >> <gilbertbgarza at gmail.com> wrote: >> > Hello, I'm a JavaScript programmer and instructor who loves functional >> > programming and writing concise, readable code. I think in general >> > JavaScript supports programming in a functional style quite well. >> However, >> > there is one small missing piece that I miss from other FP languages: >> the >> > simple-yet-useful pipeline operator. >> > >> > Similar to F#, Elixir, Elm, and other FP languages, the pipeline >> operator |> >> > helps make multiple function invocations more readable. Basically, >> > `sqrt(64)` is equivalent to `64 |> sqrt`. For example, given the >> following >> > functions: >> > >> > ```js >> > function doubleSay (str) { return str + ", " + str; } >> > function capitalize (str) { return str[0].toUpperCase() + >> str.substring(1); >> > } >> > function exclaim (str) { return str + '!'; } >> > ``` >> > >> > you could use the pipeline operator to expand your invocations for >> > readability: >> > >> > ```js >> > // old way: >> > // var result = exclaim(capitalize(doubleSay("hello"))); >> > >> > // new way: >> > var result = "hello" >> > |> doubleSay >> > |> capitalize >> > |> exclaim; >> > >> > // or, if you like one-liners: >> > var result = "hello" |> doubleSay |> capitalize |> exclaim >> > >> > result //=> "Hello, hello!" >> > ``` >> > >> > You can see a few more examples, including an advanced example with >> > Promises, here: https://github.com/mindeavor/ES7-pipeline-operator >> > >> > I'm inclined to think this feature is small and straight-forward to >> > implement. Other than the operator, there are no new semantics. The >> syntax >> > transformation is simple, and all existing code would remain unaffected. >> > >> > Although small, this feature increases the expressiveness of JavaScript >> > significantly by opening more API design possibilities. You can see >> this in >> > the link I included above. >> > >> > Thanks for reading. Any thoughts or comments? >> > >> > _______________________________________________ >> > es-discuss mailing list >> > es-discuss at mozilla.org >> > https://mail.mozilla.org/listinfo/es-discuss >> > >> >> >> >> -- >> Alexander Fritze >> http://onilabs.com >> _______________________________________________ >> es-discuss mailing list >> es-discuss at mozilla.org >> https://mail.mozilla.org/listinfo/es-discuss >> > > > > -- > *Felipe N. Moura* > Senior Web Developer and System Analyst. > > Website: http://felipenmoura.com > Twitter: @felipenmoura <http://twitter.com/felipenmoura> > LinkedIn: http://goo.gl/qGmq > > Meet some of my projects: > BrazilJS Conference <http://braziljs.com.br/> | BrazilJS Foundation > <http://braziljs.org> > --------------------------------- > *Changing the world* is the least I expect from myself! > > _______________________________________________ > 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/20151110/49dbd8bf/attachment-0001.html>
- I don't like the requirement to use the keyword
this
to compose functions. JS already has many features to support the keywordthis
: 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 tomap
to stay the first argument.
This is a reasonable objection, I think.
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 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.
> > - 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. 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://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. -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20151110/9a4175e7/attachment.html>
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 keywordthis
: 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 tomap
to stay the first argument.This is a reasonable objection, I think.
Not to mention it's still a point of contention: zenparsing/es-function-bind#26 (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 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.
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://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://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://mail.mozilla.org/listinfo/es-discuss > -- Isiah Meadows
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.
I find it to be pleasant :) It gives opportunity to semantically name your arrow function parameter, and it also follows the consistency of "the value on the left gets fed to the function on the right".
But yes, I do agree having partial application somehow built-in would be nice.
Not to mention it would be pretty slow. That's going to be creating a closure
each call.
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 mindeavor/ES7-pipeline-operator#functions
> > 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. I find it to be pleasant :) It gives opportunity to semantically name your arrow function parameter, and it also follows the consistency of "the value on the left gets fed to the function on the right". But yes, I do agree having partial application somehow built-in would be nice. Not to mention it would be pretty slow. That's going to be creating a closure > each call. 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://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://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://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://mail.mozilla.org/listinfo/es-discuss > > > > > > -- > Isiah Meadows > -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20151110/3efeb0c3/attachment-0001.html>
Seems pointless. Functions can be trivially composed to form a “pipeline” without introducing new syntax: lodash.com/docs#flow
Seems pointless. Functions can be trivially composed to form a “pipeline” without introducing new syntax: https://lodash.com/docs#flow
Nelo, that is function composition. While it's a very useful concept, it isn't quite the same thing; you have to first create the composed function before using it. What I'm proposing is an operator that allows ad-hoc chained invocations, with a primary goal of having the input read first.
Nelo, that is function composition. While it's a very useful concept, it isn't quite the same thing; you have to first create the composed function before using it. What I'm proposing is an operator that allows ad-hoc chained invocations, with a primary goal of having the input read first. On Tue, Nov 10, 2015 at 2:12 PM, Nelo Mitranim <me at mitranim.com> wrote: > Seems pointless. Functions can be trivially composed to form a “pipeline” > without introducing new syntax: https://lodash.com/docs#flow -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20151110/f0fdac82/attachment.html>
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.
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 mindeavor/ES7-pipeline-operator#functions-with-multiple-arguments :// mindeavor/ES7-pipeline-operator#functions-with-multiple-arguments
github.com, mindeavor/ES7-pipeline-operator#functions-with-multiple-arguments / mindeavor/ES7-pipeline-operator#functions-with-multiple-arguments
mindeavor mindeavor/ES7-pipeline-operator#functions-with-multiple-arguments / mindeavor/ES7-pipeline-operator#functions-with-multiple-arguments
ES7-pipeline-operator#functions mindeavor/ES7-pipeline-operator#functions-with-multiple-arguments -with-multiple-arguments 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 keywordthis
: 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 zenparsing/es-function-bind#26 :// zenparsing/es-function-bind#26
github.com, zenparsing/es-function-bind#26 / zenparsing/es-function-bind#26
zenparsing zenparsing/es-function-bind#26 / zenparsing/es-function-bind#26
es-function-bind zenparsing/es-function-bind#26 /issues/26#issuecomment-154130932 zenparsing/es-function-bind#26 (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 mindeavor/ES7-pipeline-operator:// mindeavor/ES7-pipeline-operatorgithub.com, mindeavor/ES7-pipeline-operator/ mindeavor/ES7-pipeline-operatormindeavor mindeavor/ES7-pipeline-operator/ mindeavor/ES7-pipeline-operatorES7-pipeline-operator 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 mail.mozilla.org/listinfo/es-discuss:// mail.mozilla.org/listinfo/es-discussmail.mozilla.org, mail.mozilla.org/listinfo/es-discuss/ mail.mozilla.org/listinfo/es-discusslistinfo mail.mozilla.org/listinfo/es-discuss/ mail.mozilla.org/listinfo/es-discusses-discuss mail.mozilla.org/listinfo/es-discuss
-- Isiah Meadows
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/20151110/f52e084b/attachment.html>
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:
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:
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.
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/20151110/57769d92/attachment-0001.html>
Status update: The JS community has shown lots of excitement for the idea of this proposal, but the syntax is still being debated. I outlined two alternatives in this GitHub issue, 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:
//
// 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)
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>
These examples only make this language extension look like a confusing and horrible thing. How is this an improvement, in any way?
These examples only make this language extension look like a confusing and horrible thing. How is this an improvement, in any way? > On Dec 6, 2015, at 3:13 PM, Gilbert B Garza <gilbertbgarza at gmail.com> wrote: > > Status update: The JS community has shown [lots of excitement](https://twitter.com/markdalgleish/status/673581814028492800 <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 <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 <mailto: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 <mailto: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 <mailto: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 <mailto:isiahmeadows at gmail.com>> wrote: > > Inline > > On Tue, Nov 10, 2015 at 12:52 PM, Kevin Smith <zenparsing at gmail.com <mailto: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 <mailto: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 > > > > > _______________________________________________ > 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/20151206/0e098529/attachment-0001.html> -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 842 bytes Desc: Message signed with OpenPGP using GPGMail URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20151206/0e098529/attachment-0001.sig>
Confusing and horrible are subjective, but I do agree that it's not as nice as the original proposal. Although I prefer the original, it's also important to discuss objections that people bring up, as well as the alternatives that might solve said objections :)
Gilbert
Confusing and horrible are subjective, but I do agree that it's not as nice as the original proposal. Although I prefer the original, it's also important to discuss objections that people bring up, as well as the alternatives that might solve said objections :) Gilbert On Sun, Dec 6, 2015 at 2:18 PM, Caitlin Potter <caitpotter88 at gmail.com> wrote: > These examples only make this language extension look like a confusing and > horrible thing. How is this an improvement, in any way? > > On Dec 6, 2015, at 3:13 PM, Gilbert B Garza <gilbertbgarza at gmail.com> > wrote: > > 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 >>> >>> >>> >>> >> > _______________________________________________ > 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/20151206/ab2c82cb/attachment.html>
Why not just have a rule that the pipeline operator consumes unary functions, and reuse existing bind idioms, or a future bind syntax? That seems like a proper separation of concerns to me.
As with those future bind syntax proposals, the idea of just sticking a token somewhere within an expression to turn it into a lambda is not ideal due to the various, obvious ambiguities that can arise. c.f. arrow functions where the argument is given an explicit name.
Why not just have a rule that the pipeline operator consumes unary functions, and reuse existing bind idioms, or a future bind syntax? That seems like a proper separation of concerns to me. As with those future bind syntax proposals, the idea of just sticking a token somewhere within an expression to turn it into a lambda is not ideal due to the various, obvious ambiguities that can arise. c.f. arrow functions where the argument is given an explicit name. On Sunday, 6 December 2015, Caitlin Potter <caitpotter88 at gmail.com> wrote: > These examples only make this language extension look like a confusing and > horrible thing. How is this an improvement, in any way? > > On Dec 6, 2015, at 3:13 PM, Gilbert B Garza <gilbertbgarza at gmail.com > <javascript:_e(%7B%7D,'cvml','gilbertbgarza at gmail.com');>> wrote: > > 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 > <javascript:_e(%7B%7D,'cvml','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 >> <javascript:_e(%7B%7D,'cvml','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 >>> <javascript:_e(%7B%7D,'cvml','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 >>> <javascript:_e(%7B%7D,'cvml','isiahmeadows at gmail.com');>> wrote: >>> >>> Inline >>> >>> On Tue, Nov 10, 2015 at 12:52 PM, Kevin Smith <zenparsing at gmail.com >>> <javascript:_e(%7B%7D,'cvml','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 >>> <javascript:_e(%7B%7D,'cvml','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 >>> >>> >>> >>> >> > _______________________________________________ > es-discuss mailing list > es-discuss at mozilla.org > <javascript:_e(%7B%7D,'cvml','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/20151206/6989b729/attachment-0001.html>
On Dec 6, 2015, at 4:51 PM, Gilbert B Garza <gilbertbgarza at gmail.com> wrote:
Confusing and horrible are subjective, but I do agree that it's not as nice as the original proposal. Although I prefer the original, it's also important to discuss objections that people bring up, as well as the alternatives that might solve said objections :)
Even with the original solution, it just creates a new (and less obvious) way of writing something that is already possible in the language, and easier to understand. There is a narrow scope of times where it even makes sense to use the original (or enhanced) version of the proposal, and this requires authors to be vigilante about knowing when to pick one form over the other. It also requires code reviewers to be vigilante in knowing when to say “know, this is a bad idea, stop”.
It doesn’t look like there is any redeeming quality about this change, it doesn’t introduce convenience, and does introduce new pain points for authors. Anything involving “placeholders arguments” is especially bad because it introduces an extra thing to reason about, but the issue with introducing a new syntax to pick and be aware of for limited gains is also problematic, growing the language and increasing complexity for a less than substantial reason.
The bind operator may at least have the benefit of providing some out of the box support for classic FP style, so it’s got that going for it (but really, the language doesn’t need three distinct syntaxes/idioms for this pattern, the complexity budget is already running thin)
>On Dec 6, 2015, at 4:51 PM, Gilbert B Garza <gilbertbgarza at gmail.com> wrote: > >Confusing and horrible are subjective, but I do agree that it's not as nice as the original proposal. >Although I prefer the original, it's also important to discuss objections that people bring up, as well as >the alternatives that might solve said objections :) Even with the original solution, it just creates a new (and less obvious) way of writing something that is already possible in the language, and easier to understand. There is a narrow scope of times where it even makes sense to use the original (or enhanced) version of the proposal, and this requires authors to be vigilante about knowing when to pick one form over the other. It also requires code reviewers to be vigilante in knowing when to say “know, this is a bad idea, stop”. It doesn’t look like there is any redeeming quality about this change, it doesn’t introduce convenience, and does introduce new pain points for authors. Anything involving “placeholders arguments” is especially bad because it introduces an extra thing to reason about, but the issue with introducing a new syntax to pick and be aware of for limited gains is also problematic, growing the language and increasing complexity for a less than substantial reason. The bind operator may at least have the benefit of providing some out of the box support for classic FP style, so it’s got that going for it (but really, the language doesn’t need three distinct syntaxes/idioms for this pattern, the complexity budget is already running thin) > > Gilbert > > On Sun, Dec 6, 2015 at 2:18 PM, Caitlin Potter <caitpotter88 at gmail.com <mailto:caitpotter88 at gmail.com>> wrote: > These examples only make this language extension look like a confusing and horrible thing. How is this an improvement, in any way? > >> On Dec 6, 2015, at 3:13 PM, Gilbert B Garza <gilbertbgarza at gmail.com <mailto:gilbertbgarza at gmail.com>> wrote: >> >> Status update: The JS community has shown [lots of excitement](https://twitter.com/markdalgleish/status/673581814028492800 <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 <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 <mailto: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 <mailto: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 <mailto: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 <mailto:isiahmeadows at gmail.com>> wrote: >> >> Inline >> >> On Tue, Nov 10, 2015 at 12:52 PM, Kevin Smith <zenparsing at gmail.com <mailto: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 <mailto: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 >> >> >> >> >> _______________________________________________ >> es-discuss mailing list >> es-discuss at mozilla.org <mailto:es-discuss at mozilla.org> >> https://mail.mozilla.org/listinfo/es-discuss <https://mail.mozilla.org/listinfo/es-discuss> > > -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20151206/f54e5f49/attachment-0001.html> -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 842 bytes Desc: Message signed with OpenPGP using GPGMail URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20151206/f54e5f49/attachment-0001.sig>
It doesn’t look like there is any redeeming quality about this change, it
doesn’t introduce convenience
I think you may have missed the GitHub repo [1]; it outlines benefits and convenience about the change. Also see this user's comment [2] on its significance.
[1] mindeavor/es-pipeline-operator [2] news.ycombinator.com/item?id=10686596
I argue that the syntax transformation is so simple that it would not introduce any pain points for JavaScript authors. It is arguably more intuitive than its alternative. JS programmers who are partial to FP certainly agree [3][4].
[3] twitter.com/markdalgleish/status/673581814028492800 [4] www.reddit.com/r/javascript/comments/3vox7x/es7_proposal_the_pipeline_operator
Anything involving “placeholders arguments” is especially bad because it
introduces an extra thing to reason about
I agree; I still prefer the original proposal.
The bind operator may at least have the benefit of providing some out of
the box support for classic FP style
It does not, unfortunately. FP devs avoid the keyword this
, but the bind
operator requires its use. If I'm not mistaken, the "chaining" part of the
bind operator is only a minor point, and isn't the main purpose of the
proposal.
> It doesn’t look like there is any redeeming quality about this change, it doesn’t introduce convenience I think you may have missed the GitHub repo [1]; it outlines benefits and convenience about the change. Also see this user's comment [2] on its significance. [1] https://github.com/mindeavor/es-pipeline-operator [2] https://news.ycombinator.com/item?id=10686596 I argue that the syntax transformation is so simple that it would not introduce any pain points for JavaScript authors. It is arguably more intuitive than its alternative. JS programmers who are partial to FP certainly agree [3][4]. [3] https://twitter.com/markdalgleish/status/673581814028492800 [4] https://www.reddit.com/r/javascript/comments/3vox7x/es7_proposal_the_pipeline_operator/ > Anything involving “placeholders arguments” is especially bad because it introduces an extra thing to reason about I agree; I still prefer the original proposal. > The bind operator may at least have the benefit of providing some out of the box support for classic FP style It does not, unfortunately. FP devs avoid the keyword `this`, but the bind operator requires its use. If I'm not mistaken, the "chaining" part of the bind operator is only a minor point, and isn't the main purpose of the proposal. On Sun, Dec 6, 2015 at 4:56 PM, Caitlin Potter <caitpotter88 at gmail.com> wrote: > > >On Dec 6, 2015, at 4:51 PM, Gilbert B Garza <gilbertbgarza at gmail.com> > wrote: > > > >Confusing and horrible are subjective, but I do agree that it's not as > nice as the original proposal. > >Although I prefer the original, it's also important to discuss objections > that people bring up, as well as > >the alternatives that might solve said objections :) > > Even with the original solution, it just creates a new (and less obvious) > way of writing something that is already possible in the language, > and easier to understand. There is a narrow scope of times where it even > makes sense to use the original (or enhanced) version of the > proposal, and this requires authors to be vigilante about knowing when to > pick one form over the other. It also requires code reviewers > to be vigilante in knowing when to say “know, this is a bad idea, stop”. > > It doesn’t look like there is any redeeming quality about this change, it > doesn’t introduce convenience, and does introduce new pain points > for authors. Anything involving “placeholders arguments” is especially bad > because it introduces an extra thing to reason about, but the issue > with introducing a new syntax to pick and be aware of for limited gains is > also problematic, growing the language and increasing complexity > for a less than substantial reason. > > The bind operator may at least have the benefit of providing some out of > the box support for classic FP style, so it’s got that going for it (but > really, > the language doesn’t need three distinct syntaxes/idioms for this pattern, > the complexity budget is already running thin) > > > Gilbert > > On Sun, Dec 6, 2015 at 2:18 PM, Caitlin Potter <caitpotter88 at gmail.com> > wrote: > >> These examples only make this language extension look like a confusing >> and horrible thing. How is this an improvement, in any way? >> >> On Dec 6, 2015, at 3:13 PM, Gilbert B Garza <gilbertbgarza at gmail.com> >> wrote: >> >> 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 >>>> >>>> >>>> >>>> >>> >> _______________________________________________ >> 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/20151206/4fe51eeb/attachment-0001.html>
Has anyone tried writing grammar for this? The "|>" token requires a a
lookahead to disambiguate the bit wise OR operator |
Has anyone tried writing grammar for this? The "|>" token requires a a lookahead to disambiguate the bit wise OR operator `|` - Rick On Sun, Dec 6, 2015 at 6:38 PM Gilbert B Garza <gilbertbgarza at gmail.com> wrote: > > It doesn’t look like there is any redeeming quality about this change, > it doesn’t introduce convenience > > I think you may have missed the GitHub repo [1]; it outlines benefits and > convenience about the change. Also see this user's comment [2] on its > significance. > > [1] https://github.com/mindeavor/es-pipeline-operator > [2] https://news.ycombinator.com/item?id=10686596 > > I argue that the syntax transformation is so simple that it would not > introduce any pain points for JavaScript authors. It is arguably more > intuitive than its alternative. JS programmers who are partial to FP > certainly agree [3][4]. > > [3] https://twitter.com/markdalgleish/status/673581814028492800 > [4] > https://www.reddit.com/r/javascript/comments/3vox7x/es7_proposal_the_pipeline_operator/ > > > Anything involving “placeholders arguments” is especially bad because it > introduces an extra thing to reason about > > I agree; I still prefer the original proposal. > > > The bind operator may at least have the benefit of providing some out of > the box support for classic FP style > > It does not, unfortunately. FP devs avoid the keyword `this`, but the bind > operator requires its use. If I'm not mistaken, the "chaining" part of the > bind operator is only a minor point, and isn't the main purpose of the > proposal. > > > > On Sun, Dec 6, 2015 at 4:56 PM, Caitlin Potter <caitpotter88 at gmail.com> > wrote: > >> >> >On Dec 6, 2015, at 4:51 PM, Gilbert B Garza <gilbertbgarza at gmail.com> >> wrote: >> > >> >Confusing and horrible are subjective, but I do agree that it's not as >> nice as the original proposal. >> >Although I prefer the original, it's also important to discuss >> objections that people bring up, as well as >> >the alternatives that might solve said objections :) >> >> Even with the original solution, it just creates a new (and less obvious) >> way of writing something that is already possible in the language, >> and easier to understand. There is a narrow scope of times where it even >> makes sense to use the original (or enhanced) version of the >> proposal, and this requires authors to be vigilante about knowing when to >> pick one form over the other. It also requires code reviewers >> to be vigilante in knowing when to say “know, this is a bad idea, stop”. >> >> It doesn’t look like there is any redeeming quality about this change, it >> doesn’t introduce convenience, and does introduce new pain points >> for authors. Anything involving “placeholders arguments” is especially >> bad because it introduces an extra thing to reason about, but the issue >> with introducing a new syntax to pick and be aware of for limited gains >> is also problematic, growing the language and increasing complexity >> for a less than substantial reason. >> >> The bind operator may at least have the benefit of providing some out of >> the box support for classic FP style, so it’s got that going for it (but >> really, >> the language doesn’t need three distinct syntaxes/idioms for this >> pattern, the complexity budget is already running thin) >> >> >> Gilbert >> >> On Sun, Dec 6, 2015 at 2:18 PM, Caitlin Potter <caitpotter88 at gmail.com> >> wrote: >> >>> These examples only make this language extension look like a confusing >>> and horrible thing. How is this an improvement, in any way? >>> >>> On Dec 6, 2015, at 3:13 PM, Gilbert B Garza <gilbertbgarza at gmail.com> >>> wrote: >>> >>> 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 >>>>> >>>>> >>>>> >>>>> >>>> >>> _______________________________________________ >>> es-discuss mailing list >>> es-discuss at mozilla.org >>> https://mail.mozilla.org/listinfo/es-discuss >>> >>> >>> >> >> > _______________________________________________ > 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/20151211/28831be6/attachment-0001.html>
What about a backslash instead? Like escaping a function call, such as:
foo("some string")\bar\baz;
Or
some ${data}
\ foo \ bar \ console.log;
What about a backslash instead? Like escaping a function call, such as: foo("some string")\bar\baz; Or `some ${data}` \ foo \ bar \ console.log; On Fri, Dec 11, 2015 at 12:07 PM, Rick Waldron <waldron.rick at gmail.com> wrote: > Has anyone tried writing grammar for this? The "|>" token requires a a > lookahead to disambiguate the bit wise OR operator `|` > > > - Rick > > > > > On Sun, Dec 6, 2015 at 6:38 PM Gilbert B Garza <gilbertbgarza at gmail.com> > wrote: > >> > It doesn’t look like there is any redeeming quality about this change, >> it doesn’t introduce convenience >> >> I think you may have missed the GitHub repo [1]; it outlines benefits and >> convenience about the change. Also see this user's comment [2] on its >> significance. >> >> [1] https://github.com/mindeavor/es-pipeline-operator >> [2] https://news.ycombinator.com/item?id=10686596 >> >> I argue that the syntax transformation is so simple that it would not >> introduce any pain points for JavaScript authors. It is arguably more >> intuitive than its alternative. JS programmers who are partial to FP >> certainly agree [3][4]. >> >> [3] https://twitter.com/markdalgleish/status/673581814028492800 >> [4] >> https://www.reddit.com/r/javascript/comments/3vox7x/es7_proposal_the_pipeline_operator/ >> >> > Anything involving “placeholders arguments” is especially bad because >> it introduces an extra thing to reason about >> >> I agree; I still prefer the original proposal. >> >> > The bind operator may at least have the benefit of providing some out >> of the box support for classic FP style >> >> It does not, unfortunately. FP devs avoid the keyword `this`, but the >> bind operator requires its use. If I'm not mistaken, the "chaining" part of >> the bind operator is only a minor point, and isn't the main purpose of the >> proposal. >> >> >> >> On Sun, Dec 6, 2015 at 4:56 PM, Caitlin Potter <caitpotter88 at gmail.com> >> wrote: >> >>> >>> >On Dec 6, 2015, at 4:51 PM, Gilbert B Garza <gilbertbgarza at gmail.com> >>> wrote: >>> > >>> >Confusing and horrible are subjective, but I do agree that it's not as >>> nice as the original proposal. >>> >Although I prefer the original, it's also important to discuss >>> objections that people bring up, as well as >>> >the alternatives that might solve said objections :) >>> >>> Even with the original solution, it just creates a new (and less >>> obvious) way of writing something that is already possible in the language, >>> and easier to understand. There is a narrow scope of times where it even >>> makes sense to use the original (or enhanced) version of the >>> proposal, and this requires authors to be vigilante about knowing when >>> to pick one form over the other. It also requires code reviewers >>> to be vigilante in knowing when to say “know, this is a bad idea, stop”. >>> >>> It doesn’t look like there is any redeeming quality about this change, >>> it doesn’t introduce convenience, and does introduce new pain points >>> for authors. Anything involving “placeholders arguments” is especially >>> bad because it introduces an extra thing to reason about, but the issue >>> with introducing a new syntax to pick and be aware of for limited gains >>> is also problematic, growing the language and increasing complexity >>> for a less than substantial reason. >>> >>> The bind operator may at least have the benefit of providing some out of >>> the box support for classic FP style, so it’s got that going for it (but >>> really, >>> the language doesn’t need three distinct syntaxes/idioms for this >>> pattern, the complexity budget is already running thin) >>> >>> >>> Gilbert >>> >>> On Sun, Dec 6, 2015 at 2:18 PM, Caitlin Potter <caitpotter88 at gmail.com> >>> wrote: >>> >>>> These examples only make this language extension look like a confusing >>>> and horrible thing. How is this an improvement, in any way? >>>> >>>> On Dec 6, 2015, at 3:13 PM, Gilbert B Garza <gilbertbgarza at gmail.com> >>>> wrote: >>>> >>>> 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 >>>>>> >>>>>> >>>>>> >>>>>> >>>>> >>>> _______________________________________________ >>>> es-discuss mailing list >>>> es-discuss at mozilla.org >>>> https://mail.mozilla.org/listinfo/es-discuss >>>> >>>> >>>> >>> >>> >> _______________________________________________ >> es-discuss mailing list >> es-discuss at mozilla.org >> https://mail.mozilla.org/listinfo/es-discuss >> > > _______________________________________________ > es-discuss mailing list > es-discuss at mozilla.org > https://mail.mozilla.org/listinfo/es-discuss > > -- *Felipe N. Moura* Senior Web Developer and System Analyst. Website: http://felipenmoura.com Twitter: @felipenmoura <http://twitter.com/felipenmoura> LinkedIn: http://goo.gl/qGmq Meet some of my projects: BrazilJS Conference <http://braziljs.com.br/> | BrazilJS Foundation <http://braziljs.org> --------------------------------- *Changing the world* is the least I expect from myself! -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20151211/68e35d71/attachment-0001.html>
Rick: I would imagine some sort of lookahead is already in the parser,
considering JavaScript supports both bitwise OR |
and boolean OR ||
–
unless this is accomplished some other way?
Gilbert
Rick: I would imagine some sort of lookahead is already in the parser, considering JavaScript supports both bitwise OR `|` and boolean OR `||` – unless this is accomplished some other way? Gilbert On Fri, Dec 11, 2015 at 8:52 AM, Felipe Nascimento de Moura < felipenmoura at gmail.com> wrote: > What about a backslash instead? > Like escaping a function call, such as: > > foo("some string")\bar\baz; > > Or > > `some ${data}` \ foo \ bar \ console.log; > > > > > On Fri, Dec 11, 2015 at 12:07 PM, Rick Waldron <waldron.rick at gmail.com> > wrote: > >> Has anyone tried writing grammar for this? The "|>" token requires a a >> lookahead to disambiguate the bit wise OR operator `|` >> >> >> - Rick >> >> >> >> >> On Sun, Dec 6, 2015 at 6:38 PM Gilbert B Garza <gilbertbgarza at gmail.com> >> wrote: >> >>> > It doesn’t look like there is any redeeming quality about this >>> change, it doesn’t introduce convenience >>> >>> I think you may have missed the GitHub repo [1]; it outlines benefits >>> and convenience about the change. Also see this user's comment [2] on its >>> significance. >>> >>> [1] https://github.com/mindeavor/es-pipeline-operator >>> [2] https://news.ycombinator.com/item?id=10686596 >>> >>> I argue that the syntax transformation is so simple that it would not >>> introduce any pain points for JavaScript authors. It is arguably more >>> intuitive than its alternative. JS programmers who are partial to FP >>> certainly agree [3][4]. >>> >>> [3] https://twitter.com/markdalgleish/status/673581814028492800 >>> [4] >>> https://www.reddit.com/r/javascript/comments/3vox7x/es7_proposal_the_pipeline_operator/ >>> >>> > Anything involving “placeholders arguments” is especially bad because >>> it introduces an extra thing to reason about >>> >>> I agree; I still prefer the original proposal. >>> >>> > The bind operator may at least have the benefit of providing some out >>> of the box support for classic FP style >>> >>> It does not, unfortunately. FP devs avoid the keyword `this`, but the >>> bind operator requires its use. If I'm not mistaken, the "chaining" part of >>> the bind operator is only a minor point, and isn't the main purpose of the >>> proposal. >>> >>> >>> >>> On Sun, Dec 6, 2015 at 4:56 PM, Caitlin Potter <caitpotter88 at gmail.com> >>> wrote: >>> >>>> >>>> >On Dec 6, 2015, at 4:51 PM, Gilbert B Garza <gilbertbgarza at gmail.com> >>>> wrote: >>>> > >>>> >Confusing and horrible are subjective, but I do agree that it's not as >>>> nice as the original proposal. >>>> >Although I prefer the original, it's also important to discuss >>>> objections that people bring up, as well as >>>> >the alternatives that might solve said objections :) >>>> >>>> Even with the original solution, it just creates a new (and less >>>> obvious) way of writing something that is already possible in the language, >>>> and easier to understand. There is a narrow scope of times where it >>>> even makes sense to use the original (or enhanced) version of the >>>> proposal, and this requires authors to be vigilante about knowing when >>>> to pick one form over the other. It also requires code reviewers >>>> to be vigilante in knowing when to say “know, this is a bad idea, stop”. >>>> >>>> It doesn’t look like there is any redeeming quality about this change, >>>> it doesn’t introduce convenience, and does introduce new pain points >>>> for authors. Anything involving “placeholders arguments” is especially >>>> bad because it introduces an extra thing to reason about, but the issue >>>> with introducing a new syntax to pick and be aware of for limited gains >>>> is also problematic, growing the language and increasing complexity >>>> for a less than substantial reason. >>>> >>>> The bind operator may at least have the benefit of providing some out >>>> of the box support for classic FP style, so it’s got that going for it (but >>>> really, >>>> the language doesn’t need three distinct syntaxes/idioms for this >>>> pattern, the complexity budget is already running thin) >>>> >>>> >>>> Gilbert >>>> >>>> On Sun, Dec 6, 2015 at 2:18 PM, Caitlin Potter <caitpotter88 at gmail.com> >>>> wrote: >>>> >>>>> These examples only make this language extension look like a confusing >>>>> and horrible thing. How is this an improvement, in any way? >>>>> >>>>> On Dec 6, 2015, at 3:13 PM, Gilbert B Garza <gilbertbgarza at gmail.com> >>>>> wrote: >>>>> >>>>> 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 >>>>>>> >>>>>>> >>>>>>> >>>>>>> >>>>>> >>>>> _______________________________________________ >>>>> es-discuss mailing list >>>>> es-discuss at mozilla.org >>>>> https://mail.mozilla.org/listinfo/es-discuss >>>>> >>>>> >>>>> >>>> >>>> >>> _______________________________________________ >>> es-discuss mailing list >>> es-discuss at mozilla.org >>> https://mail.mozilla.org/listinfo/es-discuss >>> >> >> _______________________________________________ >> es-discuss mailing list >> es-discuss at mozilla.org >> https://mail.mozilla.org/listinfo/es-discuss >> >> > > > -- > *Felipe N. Moura* > Senior Web Developer and System Analyst. > > Website: http://felipenmoura.com > Twitter: @felipenmoura <http://twitter.com/felipenmoura> > LinkedIn: http://goo.gl/qGmq > > Meet some of my projects: > BrazilJS Conference <http://braziljs.com.br/> | BrazilJS Foundation > <http://braziljs.org> > --------------------------------- > *Changing the world* is the least I expect from myself! > -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20151211/3dfb3ccf/attachment-0001.html>
I wonder whether we've reach that point in the language where trying to reuse the same old tokens over and over again in new combinations is getting untenable. It's a long road to APL...
I wonder whether we've reach that point in the language where trying to reuse the same old tokens over and over again in new combinations is getting untenable. It's a long road to APL... On 11 December 2015 at 15:23, Gilbert B Garza <gilbertbgarza at gmail.com> wrote: > Rick: I would imagine some sort of lookahead is already in the parser, > considering JavaScript supports both bitwise OR `|` and boolean OR `||` – > unless this is accomplished some other way? > > Gilbert > > On Fri, Dec 11, 2015 at 8:52 AM, Felipe Nascimento de Moura < > felipenmoura at gmail.com> wrote: > >> What about a backslash instead? >> Like escaping a function call, such as: >> >> foo("some string")\bar\baz; >> >> Or >> >> `some ${data}` \ foo \ bar \ console.log; >> >> >> >> >> On Fri, Dec 11, 2015 at 12:07 PM, Rick Waldron <waldron.rick at gmail.com> >> wrote: >> >>> Has anyone tried writing grammar for this? The "|>" token requires a a >>> lookahead to disambiguate the bit wise OR operator `|` >>> >>> >>> - Rick >>> >>> >>> >>> >>> On Sun, Dec 6, 2015 at 6:38 PM Gilbert B Garza <gilbertbgarza at gmail.com> >>> wrote: >>> >>>> > It doesn’t look like there is any redeeming quality about this >>>> change, it doesn’t introduce convenience >>>> >>>> I think you may have missed the GitHub repo [1]; it outlines benefits >>>> and convenience about the change. Also see this user's comment [2] on its >>>> significance. >>>> >>>> [1] https://github.com/mindeavor/es-pipeline-operator >>>> [2] https://news.ycombinator.com/item?id=10686596 >>>> >>>> I argue that the syntax transformation is so simple that it would not >>>> introduce any pain points for JavaScript authors. It is arguably more >>>> intuitive than its alternative. JS programmers who are partial to FP >>>> certainly agree [3][4]. >>>> >>>> [3] https://twitter.com/markdalgleish/status/673581814028492800 >>>> [4] >>>> https://www.reddit.com/r/javascript/comments/3vox7x/es7_proposal_the_pipeline_operator/ >>>> >>>> > Anything involving “placeholders arguments” is especially bad because >>>> it introduces an extra thing to reason about >>>> >>>> I agree; I still prefer the original proposal. >>>> >>>> > The bind operator may at least have the benefit of providing some out >>>> of the box support for classic FP style >>>> >>>> It does not, unfortunately. FP devs avoid the keyword `this`, but the >>>> bind operator requires its use. If I'm not mistaken, the "chaining" part of >>>> the bind operator is only a minor point, and isn't the main purpose of the >>>> proposal. >>>> >>>> >>>> >>>> On Sun, Dec 6, 2015 at 4:56 PM, Caitlin Potter <caitpotter88 at gmail.com> >>>> wrote: >>>> >>>>> >>>>> >On Dec 6, 2015, at 4:51 PM, Gilbert B Garza <gilbertbgarza at gmail.com> >>>>> wrote: >>>>> > >>>>> >Confusing and horrible are subjective, but I do agree that it's not >>>>> as nice as the original proposal. >>>>> >Although I prefer the original, it's also important to discuss >>>>> objections that people bring up, as well as >>>>> >the alternatives that might solve said objections :) >>>>> >>>>> Even with the original solution, it just creates a new (and less >>>>> obvious) way of writing something that is already possible in the language, >>>>> and easier to understand. There is a narrow scope of times where it >>>>> even makes sense to use the original (or enhanced) version of the >>>>> proposal, and this requires authors to be vigilante about knowing when >>>>> to pick one form over the other. It also requires code reviewers >>>>> to be vigilante in knowing when to say “know, this is a bad idea, >>>>> stop”. >>>>> >>>>> It doesn’t look like there is any redeeming quality about this change, >>>>> it doesn’t introduce convenience, and does introduce new pain points >>>>> for authors. Anything involving “placeholders arguments” is especially >>>>> bad because it introduces an extra thing to reason about, but the issue >>>>> with introducing a new syntax to pick and be aware of for limited >>>>> gains is also problematic, growing the language and increasing complexity >>>>> for a less than substantial reason. >>>>> >>>>> The bind operator may at least have the benefit of providing some out >>>>> of the box support for classic FP style, so it’s got that going for it (but >>>>> really, >>>>> the language doesn’t need three distinct syntaxes/idioms for this >>>>> pattern, the complexity budget is already running thin) >>>>> >>>>> >>>>> Gilbert >>>>> >>>>> On Sun, Dec 6, 2015 at 2:18 PM, Caitlin Potter <caitpotter88 at gmail.com >>>>> > wrote: >>>>> >>>>>> These examples only make this language extension look like a >>>>>> confusing and horrible thing. How is this an improvement, in any way? >>>>>> >>>>>> On Dec 6, 2015, at 3:13 PM, Gilbert B Garza <gilbertbgarza at gmail.com> >>>>>> wrote: >>>>>> >>>>>> 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 >>>>>>>> >>>>>>>> >>>>>>>> >>>>>>>> >>>>>>> >>>>>> _______________________________________________ >>>>>> es-discuss mailing list >>>>>> es-discuss at mozilla.org >>>>>> https://mail.mozilla.org/listinfo/es-discuss >>>>>> >>>>>> >>>>>> >>>>> >>>>> >>>> _______________________________________________ >>>> es-discuss mailing list >>>> es-discuss at mozilla.org >>>> https://mail.mozilla.org/listinfo/es-discuss >>>> >>> >>> _______________________________________________ >>> es-discuss mailing list >>> es-discuss at mozilla.org >>> https://mail.mozilla.org/listinfo/es-discuss >>> >>> >> >> >> -- >> *Felipe N. Moura* >> Senior Web Developer and System Analyst. >> >> Website: http://felipenmoura.com >> Twitter: @felipenmoura <http://twitter.com/felipenmoura> >> LinkedIn: http://goo.gl/qGmq >> >> Meet some of my projects: >> BrazilJS Conference <http://braziljs.com.br/> | BrazilJS Foundation >> <http://braziljs.org> >> --------------------------------- >> *Changing the world* is the least I expect from myself! >> > > > _______________________________________________ > 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/20151211/bec42bdc/attachment-0001.html>
Correcting myself: this would be a Punctuator
Correcting myself: this would be a Punctuator Rick On Fri, Dec 11, 2015 at 9:07 AM Rick Waldron <waldron.rick at gmail.com> wrote: > Has anyone tried writing grammar for this? The "|>" token requires a a > lookahead to disambiguate the bit wise OR operator `|` > > > - Rick > > > > On Sun, Dec 6, 2015 at 6:38 PM Gilbert B Garza <gilbertbgarza at gmail.com> > wrote: > >> > It doesn’t look like there is any redeeming quality about this change, >> it doesn’t introduce convenience >> >> I think you may have missed the GitHub repo [1]; it outlines benefits and >> convenience about the change. Also see this user's comment [2] on its >> significance. >> >> [1] https://github.com/mindeavor/es-pipeline-operator >> [2] https://news.ycombinator.com/item?id=10686596 >> >> I argue that the syntax transformation is so simple that it would not >> introduce any pain points for JavaScript authors. It is arguably more >> intuitive than its alternative. JS programmers who are partial to FP >> certainly agree [3][4]. >> >> [3] https://twitter.com/markdalgleish/status/673581814028492800 >> [4] >> https://www.reddit.com/r/javascript/comments/3vox7x/es7_proposal_the_pipeline_operator/ >> >> > Anything involving “placeholders arguments” is especially bad because >> it introduces an extra thing to reason about >> >> I agree; I still prefer the original proposal. >> >> > The bind operator may at least have the benefit of providing some out >> of the box support for classic FP style >> >> It does not, unfortunately. FP devs avoid the keyword `this`, but the >> bind operator requires its use. If I'm not mistaken, the "chaining" part of >> the bind operator is only a minor point, and isn't the main purpose of the >> proposal. >> >> >> >> On Sun, Dec 6, 2015 at 4:56 PM, Caitlin Potter <caitpotter88 at gmail.com> >> wrote: >> >>> >>> >On Dec 6, 2015, at 4:51 PM, Gilbert B Garza <gilbertbgarza at gmail.com> >>> wrote: >>> > >>> >Confusing and horrible are subjective, but I do agree that it's not as >>> nice as the original proposal. >>> >Although I prefer the original, it's also important to discuss >>> objections that people bring up, as well as >>> >the alternatives that might solve said objections :) >>> >>> Even with the original solution, it just creates a new (and less >>> obvious) way of writing something that is already possible in the language, >>> and easier to understand. There is a narrow scope of times where it even >>> makes sense to use the original (or enhanced) version of the >>> proposal, and this requires authors to be vigilante about knowing when >>> to pick one form over the other. It also requires code reviewers >>> to be vigilante in knowing when to say “know, this is a bad idea, stop”. >>> >>> It doesn’t look like there is any redeeming quality about this change, >>> it doesn’t introduce convenience, and does introduce new pain points >>> for authors. Anything involving “placeholders arguments” is especially >>> bad because it introduces an extra thing to reason about, but the issue >>> with introducing a new syntax to pick and be aware of for limited gains >>> is also problematic, growing the language and increasing complexity >>> for a less than substantial reason. >>> >>> The bind operator may at least have the benefit of providing some out of >>> the box support for classic FP style, so it’s got that going for it (but >>> really, >>> the language doesn’t need three distinct syntaxes/idioms for this >>> pattern, the complexity budget is already running thin) >>> >>> >>> Gilbert >>> >>> On Sun, Dec 6, 2015 at 2:18 PM, Caitlin Potter <caitpotter88 at gmail.com> >>> wrote: >>> >>>> These examples only make this language extension look like a confusing >>>> and horrible thing. How is this an improvement, in any way? >>>> >>>> On Dec 6, 2015, at 3:13 PM, Gilbert B Garza <gilbertbgarza at gmail.com> >>>> wrote: >>>> >>>> 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 >>>>>> >>>>>> >>>>>> >>>>>> >>>>> >>>> _______________________________________________ >>>> es-discuss mailing list >>>> es-discuss at mozilla.org >>>> https://mail.mozilla.org/listinfo/es-discuss >>>> >>>> >>>> >>> >>> >> _______________________________________________ >> 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/20151211/b5932b2a/attachment-0001.html>
Update: Another great use case has been discovered for the pipeline op – usage with async / await:
// Assume fs.readFile is an `async` function
async function runTask () {
'./index.txt'
|> await fs.readFile
|> file => file
.split('\n')
.map(fs.readFile)
|> await Promise.all
|> all => all.join("\n")
|> console.log
}
Update: Another great use case has been discovered for the pipeline op – usage with async / await: ```js // Assume fs.readFile is an `async` function async function runTask () { './index.txt' |> await fs.readFile |> file => file .split('\n') .map(fs.readFile) |> await Promise.all |> all => all.join("\n") |> console.log } ``` On Fri, Dec 11, 2015 at 10:26 AM, Rick Waldron <waldron.rick at gmail.com> wrote: > Correcting myself: this would be a Punctuator > > Rick > > > On Fri, Dec 11, 2015 at 9:07 AM Rick Waldron <waldron.rick at gmail.com> > wrote: > >> Has anyone tried writing grammar for this? The "|>" token requires a a >> lookahead to disambiguate the bit wise OR operator `|` >> >> >> - Rick >> >> >> >> On Sun, Dec 6, 2015 at 6:38 PM Gilbert B Garza <gilbertbgarza at gmail.com> >> wrote: >> >>> > It doesn’t look like there is any redeeming quality about this >>> change, it doesn’t introduce convenience >>> >>> I think you may have missed the GitHub repo [1]; it outlines benefits >>> and convenience about the change. Also see this user's comment [2] on its >>> significance. >>> >>> [1] https://github.com/mindeavor/es-pipeline-operator >>> [2] https://news.ycombinator.com/item?id=10686596 >>> >>> I argue that the syntax transformation is so simple that it would not >>> introduce any pain points for JavaScript authors. It is arguably more >>> intuitive than its alternative. JS programmers who are partial to FP >>> certainly agree [3][4]. >>> >>> [3] https://twitter.com/markdalgleish/status/673581814028492800 >>> [4] >>> https://www.reddit.com/r/javascript/comments/3vox7x/es7_proposal_the_pipeline_operator/ >>> >>> > Anything involving “placeholders arguments” is especially bad because >>> it introduces an extra thing to reason about >>> >>> I agree; I still prefer the original proposal. >>> >>> > The bind operator may at least have the benefit of providing some out >>> of the box support for classic FP style >>> >>> It does not, unfortunately. FP devs avoid the keyword `this`, but the >>> bind operator requires its use. If I'm not mistaken, the "chaining" part of >>> the bind operator is only a minor point, and isn't the main purpose of the >>> proposal. >>> >>> >>> >>> On Sun, Dec 6, 2015 at 4:56 PM, Caitlin Potter <caitpotter88 at gmail.com> >>> wrote: >>> >>>> >>>> >On Dec 6, 2015, at 4:51 PM, Gilbert B Garza <gilbertbgarza at gmail.com> >>>> wrote: >>>> > >>>> >Confusing and horrible are subjective, but I do agree that it's not as >>>> nice as the original proposal. >>>> >Although I prefer the original, it's also important to discuss >>>> objections that people bring up, as well as >>>> >the alternatives that might solve said objections :) >>>> >>>> Even with the original solution, it just creates a new (and less >>>> obvious) way of writing something that is already possible in the language, >>>> and easier to understand. There is a narrow scope of times where it >>>> even makes sense to use the original (or enhanced) version of the >>>> proposal, and this requires authors to be vigilante about knowing when >>>> to pick one form over the other. It also requires code reviewers >>>> to be vigilante in knowing when to say “know, this is a bad idea, stop”. >>>> >>>> It doesn’t look like there is any redeeming quality about this change, >>>> it doesn’t introduce convenience, and does introduce new pain points >>>> for authors. Anything involving “placeholders arguments” is especially >>>> bad because it introduces an extra thing to reason about, but the issue >>>> with introducing a new syntax to pick and be aware of for limited gains >>>> is also problematic, growing the language and increasing complexity >>>> for a less than substantial reason. >>>> >>>> The bind operator may at least have the benefit of providing some out >>>> of the box support for classic FP style, so it’s got that going for it (but >>>> really, >>>> the language doesn’t need three distinct syntaxes/idioms for this >>>> pattern, the complexity budget is already running thin) >>>> >>>> >>>> Gilbert >>>> >>>> On Sun, Dec 6, 2015 at 2:18 PM, Caitlin Potter <caitpotter88 at gmail.com> >>>> wrote: >>>> >>>>> These examples only make this language extension look like a confusing >>>>> and horrible thing. How is this an improvement, in any way? >>>>> >>>>> On Dec 6, 2015, at 3:13 PM, Gilbert B Garza <gilbertbgarza at gmail.com> >>>>> wrote: >>>>> >>>>> 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 >>>>>>> >>>>>>> >>>>>>> >>>>>>> >>>>>> >>>>> _______________________________________________ >>>>> es-discuss mailing list >>>>> es-discuss at mozilla.org >>>>> https://mail.mozilla.org/listinfo/es-discuss >>>>> >>>>> >>>>> >>>> >>>> >>> _______________________________________________ >>> 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/20151211/9a0fe904/attachment-0001.html>
// Assume fs.readFile is an `async` function
async function runTask () {
'./index.txt'
|> await fs.readFile
|> file => file
.split('\n')
.map(fs.readFile)
|> await Promise.all
|> all => all.join("\n")
|> console.log
}
This doesn't work unless you special case the semantics of await
expressions. With the current semantics, await fs.readFile
will just
await fs.readFile
not the result of applying it.
> > ```js > // Assume fs.readFile is an `async` function > async function runTask () { > './index.txt' > |> await fs.readFile > |> file => file > .split('\n') > .map(fs.readFile) > |> await Promise.all > |> all => all.join("\n") > |> console.log > } > ``` > This doesn't work unless you special case the semantics of await expressions. With the current semantics, `await fs.readFile` will just await `fs.readFile` not the result of applying it. -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20151212/6099b4c1/attachment.html>
Ah yes, you are correct, it would need to be a special case as I wrote it. This version should work instead:
// Assume fs.readFile is an `async` function
async function runTask () {
fs.readFile('./index.txt')
|> await
|> file => file
.split('\n')
.map(fs.readFile)
|> Promise.all
|> await
|> all => all.join("\n")
|> console.log
}
Ah yes, you are correct, it would need to be a special case as I wrote it. This version should work instead: ```js // Assume fs.readFile is an `async` function async function runTask () { fs.readFile('./index.txt') |> await |> file => file .split('\n') .map(fs.readFile) |> Promise.all |> await |> all => all.join("\n") |> console.log } ``` On Fri, Dec 11, 2015 at 7:08 PM, Kevin Smith <zenparsing at gmail.com> wrote: > ```js >> // Assume fs.readFile is an `async` function >> async function runTask () { >> './index.txt' >> |> await fs.readFile >> |> file => file >> .split('\n') >> .map(fs.readFile) >> |> await Promise.all >> |> all => all.join("\n") >> |> console.log >> } >> ``` >> > > This doesn't work unless you special case the semantics of await > expressions. With the current semantics, `await fs.readFile` will just > await `fs.readFile` not the result of applying it. > > -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20151212/35050673/attachment.html>
Question: does x |> f(y)
desugar to f(x, y)
, f(y, x)
, or f(y)(x)
?
Question: does `x |> f(y)` desugar to `f(x, y)`, `f(y, x)`, or `f(y)(x)`? On Sat, Dec 12, 2015, 12:17 Gilbert B Garza <gilbertbgarza at gmail.com> wrote: > Ah yes, you are correct, it would need to be a special case as I wrote it. > This version should work instead: > > ```js > // Assume fs.readFile is an `async` function > async function runTask () { > fs.readFile('./index.txt') > |> await > |> file => file > .split('\n') > .map(fs.readFile) > |> Promise.all > |> await > |> all => all.join("\n") > |> console.log > } > ``` > > On Fri, Dec 11, 2015 at 7:08 PM, Kevin Smith <zenparsing at gmail.com> wrote: > >> ```js >>> // Assume fs.readFile is an `async` function >>> async function runTask () { >>> './index.txt' >>> |> await fs.readFile >>> |> file => file >>> .split('\n') >>> .map(fs.readFile) >>> |> await Promise.all >>> |> all => all.join("\n") >>> |> console.log >>> } >>> ``` >>> >> >> This doesn't work unless you special case the semantics of await >> expressions. With the current semantics, `await fs.readFile` will just >> await `fs.readFile` not the result of applying it. >> >> > _______________________________________________ > 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/20151212/6f344605/attachment.html>
x |> f(y)
desugars to f(y)(x)
`x |> f(y)` desugars to `f(y)(x)` On Sat, Dec 12, 2015 at 2:55 PM, Isiah Meadows <isiahmeadows at gmail.com> wrote: > Question: does `x |> f(y)` desugar to `f(x, y)`, `f(y, x)`, or `f(y)(x)`? > > On Sat, Dec 12, 2015, 12:17 Gilbert B Garza <gilbertbgarza at gmail.com> > wrote: > >> Ah yes, you are correct, it would need to be a special case as I wrote >> it. This version should work instead: >> >> ```js >> // Assume fs.readFile is an `async` function >> async function runTask () { >> fs.readFile('./index.txt') >> |> await >> |> file => file >> .split('\n') >> .map(fs.readFile) >> |> Promise.all >> |> await >> |> all => all.join("\n") >> |> console.log >> } >> ``` >> >> On Fri, Dec 11, 2015 at 7:08 PM, Kevin Smith <zenparsing at gmail.com> >> wrote: >> >>> ```js >>>> // Assume fs.readFile is an `async` function >>>> async function runTask () { >>>> './index.txt' >>>> |> await fs.readFile >>>> |> file => file >>>> .split('\n') >>>> .map(fs.readFile) >>>> |> await Promise.all >>>> |> all => all.join("\n") >>>> |> console.log >>>> } >>>> ``` >>>> >>> >>> This doesn't work unless you special case the semantics of await >>> expressions. With the current semantics, `await fs.readFile` will just >>> await `fs.readFile` not the result of applying it. >>> >>> >> _______________________________________________ >> 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/20151212/40bb3829/attachment.html>
Is there a reason why it couldn't desugar to f(x, y)
or f(y, x)
? I
think it would be more performant with mostly the same benefits, and it
would work better with existing libraries, as a compliment to the function
bind proposal.
Is there a reason why it couldn't desugar to `f(x, y)` or `f(y, x)`? I think it would be more performant with mostly the same benefits, and it would work better with existing libraries, as a compliment to the function bind proposal. On Sat, Dec 12, 2015, 16:01 Gilbert B Garza <gilbertbgarza at gmail.com> wrote: > `x |> f(y)` desugars to `f(y)(x)` > > On Sat, Dec 12, 2015 at 2:55 PM, Isiah Meadows <isiahmeadows at gmail.com> > wrote: > >> Question: does `x |> f(y)` desugar to `f(x, y)`, `f(y, x)`, or `f(y)(x)`? >> >> On Sat, Dec 12, 2015, 12:17 Gilbert B Garza <gilbertbgarza at gmail.com> >> wrote: >> >>> Ah yes, you are correct, it would need to be a special case as I wrote >>> it. This version should work instead: >>> >>> ```js >>> // Assume fs.readFile is an `async` function >>> async function runTask () { >>> fs.readFile('./index.txt') >>> |> await >>> |> file => file >>> .split('\n') >>> .map(fs.readFile) >>> |> Promise.all >>> |> await >>> |> all => all.join("\n") >>> |> console.log >>> } >>> ``` >>> >>> On Fri, Dec 11, 2015 at 7:08 PM, Kevin Smith <zenparsing at gmail.com> >>> wrote: >>> >>>> ```js >>>>> // Assume fs.readFile is an `async` function >>>>> async function runTask () { >>>>> './index.txt' >>>>> |> await fs.readFile >>>>> |> file => file >>>>> .split('\n') >>>>> .map(fs.readFile) >>>>> |> await Promise.all >>>>> |> all => all.join("\n") >>>>> |> console.log >>>>> } >>>>> ``` >>>>> >>>> >>>> This doesn't work unless you special case the semantics of await >>>> expressions. With the current semantics, `await fs.readFile` will just >>>> await `fs.readFile` not the result of applying it. >>>> >>>> >>> _______________________________________________ >>> 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/20151212/eb16ebea/attachment-0001.html>
I also thought as much, but after a long discussion we determined the current proposal is better – it's simple and doesn't change any semantics of invocation. Also, arrow functions are a fine solution to working with functions that take multiple arguments, esp. since they can be optimized out by the compiler (as I do in my babel plugin).
I also thought as much, but after a [long discussion]( https://github.com/mindeavor/es-pipeline-operator/issues/20) we determined the current proposal is better – it's simple and doesn't change any semantics of invocation. Also, arrow functions are a fine solution to working with functions that take multiple arguments, esp. since they can be optimized out by the compiler (as I do in my [babel plugin]( https://github.com/babel/babel/pull/3159)). On Sat, Dec 12, 2015 at 3:21 PM, Isiah Meadows <isiahmeadows at gmail.com> wrote: > Is there a reason why it couldn't desugar to `f(x, y)` or `f(y, x)`? I > think it would be more performant with mostly the same benefits, and it > would work better with existing libraries, as a compliment to the function > bind proposal. > > On Sat, Dec 12, 2015, 16:01 Gilbert B Garza <gilbertbgarza at gmail.com> > wrote: > >> `x |> f(y)` desugars to `f(y)(x)` >> >> On Sat, Dec 12, 2015 at 2:55 PM, Isiah Meadows <isiahmeadows at gmail.com> >> wrote: >> >>> Question: does `x |> f(y)` desugar to `f(x, y)`, `f(y, x)`, or `f(y)(x)`? >>> >>> On Sat, Dec 12, 2015, 12:17 Gilbert B Garza <gilbertbgarza at gmail.com> >>> wrote: >>> >>>> Ah yes, you are correct, it would need to be a special case as I wrote >>>> it. This version should work instead: >>>> >>>> ```js >>>> // Assume fs.readFile is an `async` function >>>> async function runTask () { >>>> fs.readFile('./index.txt') >>>> |> await >>>> |> file => file >>>> .split('\n') >>>> .map(fs.readFile) >>>> |> Promise.all >>>> |> await >>>> |> all => all.join("\n") >>>> |> console.log >>>> } >>>> ``` >>>> >>>> On Fri, Dec 11, 2015 at 7:08 PM, Kevin Smith <zenparsing at gmail.com> >>>> wrote: >>>> >>>>> ```js >>>>>> // Assume fs.readFile is an `async` function >>>>>> async function runTask () { >>>>>> './index.txt' >>>>>> |> await fs.readFile >>>>>> |> file => file >>>>>> .split('\n') >>>>>> .map(fs.readFile) >>>>>> |> await Promise.all >>>>>> |> all => all.join("\n") >>>>>> |> console.log >>>>>> } >>>>>> ``` >>>>>> >>>>> >>>>> This doesn't work unless you special case the semantics of await >>>>> expressions. With the current semantics, `await fs.readFile` will just >>>>> await `fs.readFile` not the result of applying it. >>>>> >>>>> >>>> _______________________________________________ >>>> 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/20151212/8e9cd572/attachment.html>
This is a terrible example. It looks a lot better with what's already available:
async function runTask () {
const file = await fs.readFile('./index.txt');
const all = await* file
.split('\n')
.map(fs.readFile);
console.log(all.join('\n'));
}
Also how do you explain this feature to a newbie? This operator is supposed
to call the function at the RHS with the value at the LHS and now it also
has a special case when there is await
at the RHS. How more complicated
will this proposal get for the sake of making it look useful?
This proposal's aim should basically be turning this:
myFunc(myVar);
into this:
myVar |> myFunc;
If it is not useful by just doing that then it should simply be rejected.
About the usefulness of this proposal, this one conflicts with the function bind syntax and assuming FBS is all rainbows and unicorns and everyone should use it, then this proposal makes no sense since the original example should be written like this (and it's already good enough):
function doubleSay () {
return this + ', ' + this;
}
function capitalize () {
return this[0].toUpperCase() + this.substring(1);
}
function exclaim () {
return this + '!';
}
const result = 'hello'
::doubleSay()
::capitalize()
::exclaim(); // "Hello, hello!"
It's also weird that how the RHS of PO become weird when the function takes extra parameters. You can see how the code becomes polluted:
// Have fbFunc) with 0 parameters
citizen::fbsFunc();
// Add a parameter to fbsFunc()
citizen::fbsFunc(param);
// Have opFunc() with 0 parameters
citizen |> opFunc;
// Add a parameter to opFunc()
citizen |> _ => opFunc(_, param);
So we would be lying if we said the PO syntax is param |> func
.
The reality is:
// FBS syntax:
param1::fbsFunc(param2);
// PO syntax:
param1 |> _ => opFunc(_, param2);
This is no good.
This is a terrible example. It looks a lot better with what's already available: ```javascript async function runTask () { const file = await fs.readFile('./index.txt'); const all = await* file .split('\n') .map(fs.readFile); console.log(all.join('\n')); } ``` Also how do you explain this feature to a newbie? This operator is supposed to call the function at the RHS with the value at the LHS and now it also has a special case when there is `await` at the RHS. How more complicated will this proposal get for the sake of making it look useful? This proposal's aim should basically be turning this: ```javascript myFunc(myVar); ``` into this: ```javascript myVar |> myFunc; ``` If it is not useful by just doing that then it should simply be rejected. --- About the usefulness of this proposal, this one conflicts with the function bind syntax and assuming FBS is all rainbows and unicorns and everyone should use it, then this proposal makes no sense since the original example should be written like this (and it's already good enough): ```javascript function doubleSay () { return this + ', ' + this; } function capitalize () { return this[0].toUpperCase() + this.substring(1); } function exclaim () { return this + '!'; } const result = 'hello' ::doubleSay() ::capitalize() ::exclaim(); // "Hello, hello!" ``` It's also weird that how the RHS of PO become weird when the function takes extra parameters. You can see how the code becomes polluted: ```javascript // Have fbFunc) with 0 parameters citizen::fbsFunc(); // Add a parameter to fbsFunc() citizen::fbsFunc(param); // Have opFunc() with 0 parameters citizen |> opFunc; // Add a parameter to opFunc() citizen |> _ => opFunc(_, param); ``` So we would be lying if we said the PO syntax is `param |> func`. The reality is: ```javascript // FBS syntax: param1::fbsFunc(param2); // PO syntax: param1 |> _ => opFunc(_, param2); ``` This is no good. -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20151213/74f19dec/attachment.html>
I can confirm that function bind syntax is all rainbows and unicorns.
: p
I can confirm that function bind syntax is all rainbows and unicorns. : p On 9:49PM, Sat, Dec 12, 2015 Alican Çubukçuoğlu <alicancubukcuoglu at gmail.com> wrote: > This is a terrible example. It looks a lot better with what's already > available: > ```javascript > async function runTask () { > const file = await fs.readFile('./index.txt'); > > const all = await* file > .split('\n') > .map(fs.readFile); > > console.log(all.join('\n')); > } > ``` > > Also how do you explain this feature to a newbie? This operator is > supposed to call the function at the RHS with the value at the LHS and now > it also has a special case when there is `await` at the RHS. How more > complicated will this proposal get for the sake of making it look useful? > > This proposal's aim should basically be turning this: > ```javascript > myFunc(myVar); > ``` > into this: > ```javascript > myVar |> myFunc; > ``` > > If it is not useful by just doing that then it should simply be rejected. > > --- > > About the usefulness of this proposal, this one conflicts with the > function bind syntax and assuming FBS is all rainbows and unicorns and > everyone should use it, then this proposal makes no sense since the > original example should be written like this (and it's already good enough): > ```javascript > function doubleSay () { > return this + ', ' + this; > } > function capitalize () { > return this[0].toUpperCase() + this.substring(1); > } > function exclaim () { > return this + '!'; > } > > const result = 'hello' > ::doubleSay() > ::capitalize() > ::exclaim(); // "Hello, hello!" > ``` > > It's also weird that how the RHS of PO become weird when the function > takes extra parameters. You can see how the code becomes polluted: > ```javascript > // Have fbFunc) with 0 parameters > citizen::fbsFunc(); > > // Add a parameter to fbsFunc() > citizen::fbsFunc(param); > > // Have opFunc() with 0 parameters > citizen |> opFunc; > > // Add a parameter to opFunc() > citizen |> _ => opFunc(_, param); > ``` > > So we would be lying if we said the PO syntax is `param |> func`. > > The reality is: > ```javascript > // FBS syntax: > param1::fbsFunc(param2); > > // PO syntax: > param1 |> _ => opFunc(_, param2); > ``` > > This is no good. > _______________________________________________ > 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/20151213/88d848d0/attachment-0001.html>
Alican, I am one to find brainstorming useful. I appreciate your feedback (you make good points about await), but your tone might be taken as not constructive.
I think you may be misunderstanding how the PO works. Specifically your example here:
// Have opFunc() with 0 parameters
citizen |> opFunc;
That would be equivalent to opFunc(citizen)
, which has one parameter.
To be clear, I don't think the PO conflicts with the bind operator. The
undeniable fact is that there are going to be functions that receive their
subject as a parameter, and – far fewer, I might add – functions that
receive their subject as the keyword this
. Both are valid and useful
approaches, and I don't see them as conflicting with one another.
As mentioned in many other discussions, dealing with functions that take multiple parameters is actually a separate issue – partial application. Even so, functional programmers find good ways around the lack of built-in partial application in JavaScript:
let add = (x, y) => x + y;
let addCurried = x => y => x + y;
// "papp" stands for "partial application"
Function.prototype.papp = ...;
var result = 10
|> add.papp(20)
|> addCurried(30)
;
result //=> 60
In fact, if papp
were built into the language, it would be simple for
compilers to optimize away an extra function call.
But I digress. My main point is that support for partial application is a separate issue. The fact that the pipeline operator works without it is a good thing (at least, as I see it).
Alican, I am one to find brainstorming useful. I appreciate your feedback (you make good points about await), but your tone might be taken as not constructive. I think you may be misunderstanding how the PO works. Specifically your example here: // Have opFunc() with 0 parameters citizen |> opFunc; That would be equivalent to `opFunc(citizen)`, which has one parameter. To be clear, I don't think the PO conflicts with the bind operator. The undeniable fact is that there are going to be functions that receive their subject as a parameter, and – far fewer, I might add – functions that receive their subject as the keyword `this`. Both are valid and useful approaches, and I don't see them as conflicting with one another. As mentioned in many other discussions, dealing with functions that take multiple parameters is actually a separate issue – partial application. Even so, functional programmers find good ways around the lack of built-in partial application in JavaScript: ```js let add = (x, y) => x + y; let addCurried = x => y => x + y; // "papp" stands for "partial application" Function.prototype.papp = ...; var result = 10 |> add.papp(20) |> addCurried(30) ; result //=> 60 ``` In fact, if `papp` were built into the language, it would be simple for compilers to optimize away an extra function call. But I digress. My main point is that support for partial application is a separate issue. The fact that the pipeline operator works without it is a good thing (at least, as I see it). On Sat, Dec 12, 2015 at 8:49 PM, Alican Çubukçuoğlu < alicancubukcuoglu at gmail.com> wrote: > This is a terrible example. It looks a lot better with what's already > available: > ```javascript > async function runTask () { > const file = await fs.readFile('./index.txt'); > > const all = await* file > .split('\n') > .map(fs.readFile); > > console.log(all.join('\n')); > } > ``` > > Also how do you explain this feature to a newbie? This operator is > supposed to call the function at the RHS with the value at the LHS and now > it also has a special case when there is `await` at the RHS. How more > complicated will this proposal get for the sake of making it look useful? > > This proposal's aim should basically be turning this: > ```javascript > myFunc(myVar); > ``` > into this: > ```javascript > myVar |> myFunc; > ``` > > If it is not useful by just doing that then it should simply be rejected. > > --- > > About the usefulness of this proposal, this one conflicts with the > function bind syntax and assuming FBS is all rainbows and unicorns and > everyone should use it, then this proposal makes no sense since the > original example should be written like this (and it's already good enough): > ```javascript > function doubleSay () { > return this + ', ' + this; > } > function capitalize () { > return this[0].toUpperCase() + this.substring(1); > } > function exclaim () { > return this + '!'; > } > > const result = 'hello' > ::doubleSay() > ::capitalize() > ::exclaim(); // "Hello, hello!" > ``` > > It's also weird that how the RHS of PO become weird when the function > takes extra parameters. You can see how the code becomes polluted: > ```javascript > // Have fbFunc) with 0 parameters > citizen::fbsFunc(); > > // Add a parameter to fbsFunc() > citizen::fbsFunc(param); > > // Have opFunc() with 0 parameters > citizen |> opFunc; > > // Add a parameter to opFunc() > citizen |> _ => opFunc(_, param); > ``` > > So we would be lying if we said the PO syntax is `param |> func`. > > The reality is: > ```javascript > // FBS syntax: > param1::fbsFunc(param2); > > // PO syntax: > param1 |> _ => opFunc(_, param2); > ``` > > This is no good. > > _______________________________________________ > 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/20151212/62cc25be/attachment.html>
I think you may be misunderstanding how the PO works. Specifically your
example here:
Just a typo. Let me list my concerns:
- Supporting await makes things unnecessarily complicated.
- Calling functions with more than one parameter is weird.
- Looks like use cases are already covered by FBS.
> I think you may be misunderstanding how the PO works. Specifically your example here: Just a typo. Let me list my concerns: - Supporting await makes things unnecessarily complicated. - Calling functions with more than one parameter is weird. - Looks like use cases are already covered by FBS. -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20151213/0d322c00/attachment.html>
my 50 cents.
I think it is interesting to be added I think this should not really concern to await implementations (would, indeed, get weirder and more complicated)! I don't think this has anything to do with bind! No "this" is touched with that! I don't think it has anything to do with chaining either.
How I see it:
// consider:
function getUserName () { /* ... */ }
function capitalize (str) { /* ... */ }
function trim (str) { /* ... */ }
function splitBySpaces (str) { /* ... */ }
// Using PO:
console.log( getUserName() |> capitalize |> trim |> splitBySpaces );
// NOT using PO:
let name = getUserName();
name = capitalize(name);
name = trim(name);
console.log( splitBySpaces(name) );
// OR
console.log( splitBySpaces( trim( capitalize( getUserName() ) ) ) );
This is not related with "this", nor with chaining(once it can be used with any function, even when, as in this case, returning strings). This is not like "then" either, once it is not temporal, but way easier to read and understand!
Therefore...I don't think this should be consider to work with await. I don't they belong to the same realm!
Although, I believe this would work too:
// imagine getUserName and trim are async
console.log(await getUserName() |> capitalize |> await trim |>
splitBySpaces );
Thanks for your time :)
my 50 cents. I think it is interesting to be added I think this should not really concern to await implementations (would, indeed, get weirder and more complicated)! I don't think this has *anything* to do with bind! No "this" is touched with that! I don't think it has anything to do with chaining either. How I see it: ```js // consider: function getUserName () { /* ... */ } function capitalize (str) { /* ... */ } function trim (str) { /* ... */ } function splitBySpaces (str) { /* ... */ } ``` ```js // Using PO: console.log( getUserName() |> capitalize |> trim |> splitBySpaces ); ``` ```js // NOT using PO: let name = getUserName(); name = capitalize(name); name = trim(name); console.log( splitBySpaces(name) ); // OR console.log( splitBySpaces( trim( capitalize( getUserName() ) ) ) ); ``` This is not related with "this", nor with chaining(once it can be used with any function, even when, as in this case, returning strings). This is not like "then" either, once it is not temporal, but way easier to read and understand! Therefore...I don't think this should be consider to work with await. I don't they belong to the same realm! Although, I believe this would work too: ```js // imagine getUserName and trim are async console.log(await getUserName() |> capitalize |> await trim |> splitBySpaces ); ``` Thanks for your time :) On Sun, Dec 13, 2015 at 5:39 AM, Alican Çubukçuoğlu < alicancubukcuoglu at gmail.com> wrote: > > I think you may be misunderstanding how the PO works. Specifically your > example here: > > Just a typo. Let me list my concerns: > - Supporting await makes things unnecessarily complicated. > - Calling functions with more than one parameter is weird. > - Looks like use cases are already covered by FBS. > > > _______________________________________________ > es-discuss mailing list > es-discuss at mozilla.org > https://mail.mozilla.org/listinfo/es-discuss > > -- *Felipe N. Moura* Senior Web Developer and System Analyst. Website: http://felipenmoura.com Twitter: @felipenmoura <http://twitter.com/felipenmoura> LinkedIn: http://goo.gl/qGmq Meet some of my projects: BrazilJS Conference <http://braziljs.com.br/> | BrazilJS Foundation <http://braziljs.org> --------------------------------- *Changing the world* is the least I expect from myself! -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20151214/11db3fb9/attachment.html>
So these are your example utility functions:
function capitalize (str) { /* ... */ }
function trim (str) { /* ... */ }
function splitBySpaces (str) { /* ... */ }
What makes you think that utility functions should be coded like that? Take these for an example:
// Using "this"
function trim(characters) {
// this...
return capitalizedString;
}
// Using a parameter
function trim(string, characters) {
// string...
return capitalizedString;
}
What is the best practice when coding functions like this? Using this
is
a clear winner since that's how the native and user utility methods for the
.prototype
s of String, Array and such work. More importantly, that's how
polyfills are done. Plus FBS, which allows very easy consumption of
functions coded like this, is already at stage 0.
When the functions in the PO examples should be coded with this
anyway,
then where is the need for PO?
Also, you shouldn't make your examples this simple. It's almost like you are deliberately trying to hide the truth.
This is the reality of current PO syntax:
console.log(getSomething() |> _ => trim(_, '-') |> _ => words(_, /[^, ]+/g)
|> _ => pad(_, 20, '-'));
Even if there is a need for PO, the syntax should change:
param1 |> func(param2, param3)
console.log(getSomething() |> trim('-') |> words(/[^, ]+/g) |> pad(20,
'-'));
Then it becomes something very close to FBS and doesn't look weird when it's used with it everything else:
'something'
::trim('-')
.concat('asd')
|>repeat(3);
So these are your example utility functions: ```javascript function capitalize (str) { /* ... */ } function trim (str) { /* ... */ } function splitBySpaces (str) { /* ... */ } ``` What makes you think that utility functions should be coded like that? Take these for an example: ```javascript // Using "this" function trim(characters) { // this... return capitalizedString; } // Using a parameter function trim(string, characters) { // string... return capitalizedString; } ``` What is the best practice when coding functions like this? Using `this` is a clear winner since that's how the native and user utility methods for the `.prototype`s of String, Array and such work. More importantly, that's how polyfills are done. Plus FBS, which allows very easy consumption of functions coded like this, is already at stage 0. When the functions in the PO examples should be coded with `this` anyway, then where is the need for PO? --- Also, you shouldn't make your examples this simple. It's almost like you are deliberately trying to hide the truth. This is the reality of current PO syntax: ```javascript console.log(getSomething() |> _ => trim(_, '-') |> _ => words(_, /[^, ]+/g) |> _ => pad(_, 20, '-')); ``` Even if there is a need for PO, the syntax should change: ```javascript param1 |> func(param2, param3) console.log(getSomething() |> trim('-') |> words(/[^, ]+/g) |> pad(20, '-')); ``` Then it becomes something very close to FBS and doesn't look weird when it's used with it everything else: ```javascript 'something' ::trim('-') .concat('asd') |>repeat(3); ``` -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20151214/9a45baa6/attachment.html>
It also seems like the current proposal for PO makes it awkward when mixing methods and piped calls in a chain.
(someArray .filter(...) .map(...) |> someOtherArrayOp ).forEach(...)
Note the extra parens before the "forEach" invocation.
It also seems like the current proposal for PO makes it awkward when mixing methods and piped calls in a chain. (someArray .filter(...) .map(...) |> someOtherArrayOp ).forEach(...) Note the extra parens before the "forEach" invocation. Kevin -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20151214/d6626d85/attachment.html>
On Sun, Dec 13, 2015 at 10:32 PM, Kevin Smith <zenparsing at gmail.com> wrote:
(someArray .filter(...) .map(...) |> someOtherArrayOp ).forEach(...)
Note the extra parens before the "forEach" invocation.
For the record I think a pipe operator is silly - I wish | were available because that is the only operator I will ever think of as a pipe.
That said, if you want to get silly - you could have a pipe operator
which uses the current this
, and one that compiles to use
.call(lhs_argument, ...).
<> (uses the left-hand-side value as this
for the next function)
|> (simply passes the left-hand-side value to the right preserving this)
Yes. I"m using the spaceship operator for this because why not, I already think this is silly.
[ 'a', 'b', 'c' ] <> filter(...) <> map(...) |> someOtherNonArrayFunc
<> forEach(...)
On Sun, Dec 13, 2015 at 10:32 PM, Kevin Smith <zenparsing at gmail.com> wrote: > (someArray > .filter(...) > .map(...) > |> someOtherArrayOp > ).forEach(...) > > Note the extra parens before the "forEach" invocation. For the record I think a pipe operator is silly - I wish | were available because that is the only operator I will ever think of as a pipe. That said, if you want to get silly - you could have a pipe operator which uses the current `this`, and one that compiles to use .call(lhs_argument, ...). <> (uses the left-hand-side value as `this` for the next function) |> (simply passes the left-hand-side value to the right preserving this) Yes. I"m using the spaceship operator for this because why not, I already think this is silly. ```javascript [ 'a', 'b', 'c' ] <> filter(...) <> map(...) |> someOtherNonArrayFunc <> forEach(...) ```
await
could be handled by with contextual lexing: handling |> await
as a single keyword.
Another solution would be to collapse the two into a variant of the
pipeline operator: |await>
, |!>
, ...
This could be an opportunity to revive the syntax sugar that was proposed in strawman:concurrency
// concurrency strawman
lines = fs.readFile!('./index.txt').split('\n');
// pipeline operator
lines = './index.txt' |!> fs.readFile |> str => str.split('\n')
`await` could be handled by with contextual lexing: handling `|> await` as a single keyword. Another solution would be to collapse the two into a variant of the pipeline operator: `|await>`, `|!>`, ... This could be an opportunity to revive the syntax sugar that was proposed in http://wiki.ecmascript.org/doku.php?id=strawman:concurrency ```js // concurrency strawman lines = fs.readFile!('./index.txt').split('\n'); // pipeline operator lines = './index.txt' |!> fs.readFile |> str => str.split('\n') ``` -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20151214/b33c57c3/attachment.html>
Do we really need to add support for await in a pipeline syntax sugar when
there already is a piping support in .then()
? If you need to await
something in that chain, then just use .then()
.
let result = await fs.readFile('index.txt')
.then(aSingleParamFunction)
.then(anotherSingleParamFunction)
.then(x => multiParamFunction(x, 10));
I really don't see much gain in adding this syntax when there is already a
FBS proposal that covers most of the cases. The pipe operator only supports
single param functions. With multiple params you either need to use
fat-arrow (while FBS handles multiple params) or you need a special
function that is curryable. So now we either need functions that is
curryable (for |>) or a function that relies on the this
value (for FBS),
so libraries will probably need to be specially written for whichever proposal is added to the spec. It looks to me like FBS adds a lot more value than |> does.
Do we really need to add support for await in a pipeline syntax sugar when there already is a piping support in `.then()`? If you need to await something in that chain, then just use `.then()`. ```js let result = await fs.readFile('index.txt') .then(aSingleParamFunction) .then(anotherSingleParamFunction) .then(x => multiParamFunction(x, 10)); ``` I really don't see much gain in adding this syntax when there is already a FBS proposal that covers most of the cases. The pipe operator only supports single param functions. With multiple params you either need to use fat-arrow (while FBS handles multiple params) or you need a special function that is curryable. So now we either need functions that is curryable (for |>) or a function that relies on the `this` value (for FBS), so libraries will probably need to be specially written for whichever proposal is added to the spec. It looks to me like FBS adds a lot more value than |> does. On Mon, Dec 14, 2015 at 2:05 PM, Bruno Jouhier <bjouhier at gmail.com> wrote: > `await` could be handled by with contextual lexing: handling `|> await` as > a single keyword. > > Another solution would be to collapse the two into a variant of the > pipeline operator: `|await>`, `|!>`, ... > > This could be an opportunity to revive the syntax sugar that was proposed > in http://wiki.ecmascript.org/doku.php?id=strawman:concurrency > > ```js > // concurrency strawman > lines = fs.readFile!('./index.txt').split('\n'); > // pipeline operator > lines = './index.txt' |!> fs.readFile |> str => str.split('\n') > ``` > > _______________________________________________ > 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/20151214/e5df99f5/attachment.html>
Sidebar: thanks to Isiah Meadows, the FBS proposal now also supports
constructor wrapping via the ::new
syntax:
let factory = SomeClass::new;
Sidebar: thanks to Isiah Meadows, the FBS proposal now also supports constructor wrapping via the `::new` syntax: let factory = SomeClass::new; On Mon, Dec 14, 2015 at 9:00 AM Marius Gundersen <gundersen at gmail.com> wrote: > Do we really need to add support for await in a pipeline syntax sugar when > there already is a piping support in `.then()`? If you need to await > something in that chain, then just use `.then()`. > > ```js > let result = await fs.readFile('index.txt') > .then(aSingleParamFunction) > .then(anotherSingleParamFunction) > .then(x => multiParamFunction(x, 10)); > ``` > > I really don't see much gain in adding this syntax when there is already a > FBS proposal that covers most of the cases. The pipe operator only supports > single param functions. With multiple params you either need to use > fat-arrow (while FBS handles multiple params) or you need a special > function that is curryable. So now we either need functions that is > curryable (for |>) or a function that relies on the `this` value (for FBS), > so libraries will probably need to be specially written for whichever > proposal is added to the spec. It looks to me like FBS adds a lot more > value than |> does. > > > On Mon, Dec 14, 2015 at 2:05 PM, Bruno Jouhier <bjouhier at gmail.com> wrote: > >> `await` could be handled by with contextual lexing: handling `|> await` >> as a single keyword. >> >> Another solution would be to collapse the two into a variant of the >> pipeline operator: `|await>`, `|!>`, ... >> >> This could be an opportunity to revive the syntax sugar that was proposed >> in http://wiki.ecmascript.org/doku.php?id=strawman:concurrency >> >> ```js >> // concurrency strawman >> lines = fs.readFile!('./index.txt').split('\n'); >> // pipeline operator >> lines = './index.txt' |!> fs.readFile |> str => str.split('\n') >> ``` >> >> _______________________________________________ >> es-discuss mailing list >> es-discuss at mozilla.org >> https://mail.mozilla.org/listinfo/es-discuss >> >> > _______________________________________________ > 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/20151214/e30bda44/attachment.html>
Correct me if I'm wrong but doesn't your example here result in extra turns of the run-loop, even for synchronous functions?
This whole thing feels a bit unilateral to me and at risk of over-engineering a solution we'd maybe do well to consider what other languages are doing, e.g. en.wikibooks.org/wiki/Haskell/do_notation
Correct me if I'm wrong but doesn't your example here result in extra turns of the run-loop, even for synchronous functions? This whole thing feels a bit unilateral to me and at risk of over-engineering a solution we'd maybe do well to consider what other languages are doing, e.g. https://en.wikibooks.org/wiki/Haskell/do_notation On Monday, 14 December 2015, Marius Gundersen <gundersen at gmail.com> wrote: > Do we really need to add support for await in a pipeline syntax sugar when > there already is a piping support in `.then()`? If you need to await > something in that chain, then just use `.then()`. > > ```js > let result = await fs.readFile('index.txt') > .then(aSingleParamFunction) > .then(anotherSingleParamFunction) > .then(x => multiParamFunction(x, 10)); > ``` > > I really don't see much gain in adding this syntax when there is already a > FBS proposal that covers most of the cases. The pipe operator only supports > single param functions. With multiple params you either need to use > fat-arrow (while FBS handles multiple params) or you need a special > function that is curryable. So now we either need functions that is > curryable (for |>) or a function that relies on the `this` value (for FBS), > so libraries will probably need to be specially written for whichever > proposal is added to the spec. It looks to me like FBS adds a lot more > value than |> does. > > > On Mon, Dec 14, 2015 at 2:05 PM, Bruno Jouhier <bjouhier at gmail.com> wrote: > >> `await` could be handled by with contextual lexing: handling `|> await` >> as a single keyword. >> >> Another solution would be to collapse the two into a variant of the >> pipeline operator: `|await>`, `|!>`, ... >> >> This could be an opportunity to revive the syntax sugar that was proposed >> in http://wiki.ecmascript.org/doku.php?id=strawman:concurrency >> >> ```js >> // concurrency strawman >> lines = fs.readFile!('./index.txt').split('\n'); >> // pipeline operator >> lines = './index.txt' |!> fs.readFile |> str => str.split('\n') >> ``` >> >> _______________________________________________ >> 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/20151214/11103f02/attachment-0001.html>
Or at least something that can come next iteration. At least the spec is written :)
All that's left is the endless bikeshedding over the syntax :D (Hasn't it been like a few months people have been debating syntax?)
Or at least something that can come next iteration. At least the spec is written :) All that's left is the endless bikeshedding over the syntax :D (Hasn't it been like a few months people have been debating syntax?) On Mon, Dec 14, 2015, 11:13 Kevin Smith <zenparsing at gmail.com> wrote: > Sidebar: thanks to Isiah Meadows, the FBS proposal now also supports > constructor wrapping via the `::new` syntax: > > let factory = SomeClass::new; > > > > On Mon, Dec 14, 2015 at 9:00 AM Marius Gundersen <gundersen at gmail.com> > wrote: > >> Do we really need to add support for await in a pipeline syntax sugar >> when there already is a piping support in `.then()`? If you need to await >> something in that chain, then just use `.then()`. >> >> ```js >> let result = await fs.readFile('index.txt') >> .then(aSingleParamFunction) >> .then(anotherSingleParamFunction) >> .then(x => multiParamFunction(x, 10)); >> ``` >> >> I really don't see much gain in adding this syntax when there is already >> a FBS proposal that covers most of the cases. The pipe operator only >> supports single param functions. With multiple params you either need to >> use fat-arrow (while FBS handles multiple params) or you need a special >> function that is curryable. So now we either need functions that is >> curryable (for |>) or a function that relies on the `this` value (for FBS), >> so libraries will probably need to be specially written for whichever >> proposal is added to the spec. It looks to me like FBS adds a lot more >> value than |> does. >> >> >> On Mon, Dec 14, 2015 at 2:05 PM, Bruno Jouhier <bjouhier at gmail.com> >> wrote: >> >>> `await` could be handled by with contextual lexing: handling `|> await` >>> as a single keyword. >>> >>> Another solution would be to collapse the two into a variant of the >>> pipeline operator: `|await>`, `|!>`, ... >>> >>> This could be an opportunity to revive the syntax sugar that was >>> proposed in http://wiki.ecmascript.org/doku.php?id=strawman:concurrency >>> >>> ```js >>> // concurrency strawman >>> lines = fs.readFile!('./index.txt').split('\n'); >>> // pipeline operator >>> lines = './index.txt' |!> fs.readFile |> str => str.split('\n') >>> ``` >>> >>> _______________________________________________ >>> es-discuss mailing list >>> es-discuss at mozilla.org >>> https://mail.mozilla.org/listinfo/es-discuss >>> >>> >> _______________________________________________ >> es-discuss mailing list >> es-discuss at mozilla.org >> https://mail.mozilla.org/listinfo/es-discuss >> > _______________________________________________ > 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/20151215/a6113c51/attachment.html>
Hello, I'm a JavaScript programmer and instructor who loves functional programming and writing concise, readable code. I think in general JavaScript supports programming in a functional style quite well. However, there is one small missing piece that I miss from other FP languages: the simple-yet-useful pipeline operator.
Similar to F#, Elixir, Elm, and other FP languages, the pipeline operator |> helps make multiple function invocations more readable. Basically,
sqrt(64)
is equivalent to64 |> sqrt
. For example, given the followingfunctions:
function doubleSay (str) { return str + ", " + str; } function capitalize (str) { return str[0].toUpperCase() + str.substring(1); } function exclaim (str) { return str + '!'; }
you could use the pipeline operator to expand your invocations for readability:
// old way: // var result = exclaim(capitalize(doubleSay("hello"))); // new way: var result = "hello" |> doubleSay |> capitalize |> exclaim; // or, if you like one-liners: var result = "hello" |> doubleSay |> capitalize |> exclaim result //=> "Hello, hello!"
You can see a few more examples, including an advanced example with Promises, here: mindeavor/ES7-pipeline-operator
I'm inclined to think this feature is small and straight-forward to implement. Other than the operator, there are no new semantics. The syntax transformation is simple, and all existing code would remain unaffected.
Although small, this feature increases the expressiveness of JavaScript significantly by opening more API design possibilities. You can see this in the link I included above.
Thanks for reading. Any thoughts or comments?