Thanks again for the reply, Peter. I’m a little confused by your latest questions, so I’ll try to clarify the questions at a time.
> > [me] To clarify: The way that bare style and topic style are distinguished > > are not by the absence/presence of a topic reference. Bare style has a > > simple and strict syntax: any identifiers, separated by `.`s, optionally > > preceded by `new` or `await`. > > [Peter] So `x['hello']`` would not be valid? Seems pretty inconsistent. I > think that checking for the lexical topic token would be simpler and easier > for developers. `value |> x['hello'](#)` is a valid pipeline, in topic style. `value |> x['hello']` is an invalid pipeline, in order to prevent infinite unrestricted lookahead, therefore simplifying interpretation for both human readers and computer readers. By “simplicity”, I’m referring to [several goals from the proposal explainer][goals]. Particularly relevant here is the goal of [syntactic locality][]. Copying and pasting from there: “The syntax should minimize the parsing lookahead that the compiler must check. If the grammar makes [garden-path syntax][] common, then this increases the dependency that pieces of code have on other code. This long lookahead in turn makes it more likely that the code will exhibit developer-unintended behavior. “This is true particularly for distinguishing between different styles of pipeline body syntax. A pipeline’s meaning would often be ambiguous between these styles – at least without checking the pipeline’s body carefully to see in which style it is written. And the pipeline body may be a very long expression. “By restricting the space of valid bare-style pipeline bodies (that is, without topic references), the rule minimizes garden-path syntax that would otherwise be possible – such as `value |> compose(f, g, h, i, j, k, #)`. Syntax becomes more locally readable. It becomes easier to reason about code without thinking about code elsewhere.” In addition, changing the grammar to depend on containment of a token would make it impossible to parse with a context-free grammar or by introducing a new grammar-production parameter, which multiplies the number of productions in JavaScript’s grammar. The [pipeline syntax grammar][] alone would become considerably considerably more complicated – and this also applies to the grammars for every single other type of expression, all of which would have to be modified with an additional syntactic parameter. At the very beginning, in fact, I actually considered making the grammar to depend on containment of a token – but then I realized many of the disadvantages above that it would bring. The example `value |> x['hello']` seems simple. But the danger of requiring unrestrictedly infinite lookahead is that people will also write things like `value |> compose(x['hello'][symbol].propertyA.key(#).propertyB.propertyC, anotherFunction)`. It is easy for a human reader to miss the `#` in there, yet its presence or absence would completely change the pipeline’s semantics, from the value returned by `compose(…)` to a function call on that value. That’s the consequence of compromising syntactic locality. It means that a reader will have to check distant code in order to determine the style of a pipeline. [Avoiding footguns is a paramount goal][avoid footguns]. And `value |> x['hello'](#)` is still a valid pipeline. [goals]: https://github.com/js-choi/proposal-smart-pipelines/blob/master/readme.md#goals [syntactic locality]: https://github.com/js-choi/proposal-smart-pipelines/blob/master/readme.md#syntactic-locality [garden-path syntax]: https://en.wikipedia.org/wiki/Garden_path_sentence [pipeline syntax grammar]: https://jschoi.org/18/es-smart-pipelines/spec#sec-pipeline-operator [avoid footguns]: https://github.com/js-choi/proposal-smart-pipelines/blob/master/readme.md#dont-shoot-me-in-the-foot *** > > [me] Any pipeline body that does not fulfill that simple and strict syntax > > is in topic style. However, any pipeline body that is in topic style also > > must contain a topic reference, or else it is an early syntax error. x |> > > f() is in topic style; it is also an early syntax error, because it is a > > topic-style pipeline that does not use the topic reference. > > [Peter] This seems to not support auto-currying functions. For instance, > lodash/fp has auto-currying functions which take an iteratee as the first > argument: My apologies – I’m a little confused by what your first sentence here means. By “this”, do you mean that smart pipelines do not support auto-currying functions, or do you mean that the bare style do not support them? Auto-currying functions are indeed supported by smart pipelines, though not necessarily by bare style. The purpose of bare style is merely to optimize a common use case – unary function calls. All other cases are intended to use topic style, which hopefully is still terse, yet explicit enough to avoid ambiguity. In fact, several examples in the readme are drawn from Ramda’s cookbook, several of which, if I recall correctly, involve autocurrying functions ([Ramda examples, part 1][] and [Ramda examples, part 2][]). Your example using Lodash/FP, `['a', null, 'c'] |> fs.filter(Boolean)`, is expressible using `['a', null, 'c'] |> fs.filter(Boolean)(#)`. The latter is a valid topic-style pipeline. In general, `x |> f(a, b)` is visually ambiguous between four reasonable interpretations:\ `x |> f(a, b, #)`, `x |> f(a, #, b)`, `x |> f(#, a, b)`, and `x |> f(a, b)(#)`. The early error forces the writer to specify which of the four reasonable interpretations they mean, also reducing the parsing burden on the human reader. [Ramda examples, part 1]: https://github.com/js-choi/proposal-smart-pipelines/blob/master/readme.md#ramda-core-proposal--additional-feature-bppf [Ramda examples, part 2]: https://github.com/js-choi/proposal-smart-pipelines/blob/master/readme.md#ramda-core-proposal--additional-features-bppfnp *** > > [me] optionally preceded by `new` or `await` > > [Peter] This seems very arbitrary and not forwards-compatible. My apologies again – I am also confused by what you mean here by forwards-compatible. What is there for bare style to be forward compatible with? New prefix operators? If a new operator is commonly used before unary function calls, then they could be added to bare style’s syntax later, but in the meantime topic style can handle them, as well as anything else, simply by appending `(#)`. Bare style is a special syntax, with special evaluation semantics, optimized for one common use case: unary functions. The `new` and `await` tokens are just flags for bare style because unary constructor calls and awaited unary async-function calls are also quite common, as my review of real-world codebases in [Motivation][] shows. But in general, I expect topic style to be used more often, and topic style itself is very terse. In fact, the `new` and `await` flags in bare style were originally not there. The only reason why I added them in the first place was because, during that [review of real-world code][Motivation], I found that unary constructor calls and awaited unary async-function calls are very common. I am still considering removing them from the Core Proposal, into their own separate Additional Features, so that their tradeoffs may be independently considered. [Motivation]: https://github.com/js-choi/proposal-smart-pipelines/blob/master/readme.md#motivation *** > By only allowing identifiers, you're requiring people to create unnecessary > intermittent variables. I propose that you allow any expression on the > right-hand side of the pipe operator, and decide whether it's in topic style > or bare style based on the inclusion of the lexical topic token. Your > argument that making it very restrictive reduced cognitive burden doesn't > make sense to me at all, as remembering what is and isn't allowed is more > difficult than just remembering "if it doesn't have the token, it will call > the function specified by the expression with the argument of the result of > the previous step in the pipeline". Hopefully, the quotation I pasted from the [syntactic locality][] section from above is an adequate response to this paragraph. Bare style’s rules are simple: “”. The rules are simpler than humans and computers having to search a [long pipeline expression][garden-path syntax], such as `value |> compose(f, g, h, i, j, k, #, l, m, n, o)` or `value |> compose(x['hello'][symbol].propertyA.key(#).propertyB.propertyC, anotherFunction)`, for the absence or presence of a single topic reference `#`. In many reasonable cases, parsing would be considerably more complicated, for humans and computers alike. [syntactic locality]: https://github.com/js-choi/proposal-smart-pipelines/blob/master/readme.md#syntactic-locality [garden-path syntax]: https://en.wikipedia.org/wiki/Garden_path_sentence *** Thanks again for the reply. Your `x['hello']`-method example and your Lodash/FP example are both already addressed by the current smart-pipelines proposal. I hope these explanations clarify your understanding of the current proposal. I’ll have only intermittent free time in the next few days, but in the meantime James DiGioia and I will be working on the Babel plugin for both smart pipelines and F-sharp Style Only pipelines. I’ll try to reply to any reply here when I can. Warm regards, J. S. Choi _______________________________________________ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss