> 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`.

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.

> 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.

This seems to not support auto-currying functions. For instance,
**lodash/fp** has auto-currying functions which take an iteratee as the
first argument:

```js
// `lodash/fp/filter` is iteratee-first data-last:
// (iteratee, collection)
var compact = fp.filter(Boolean);
compact(['a', null, 'c']);
// ➜ ['a', 'c']
```

So someone might want to do something like the following to utilize this
behavior:

```js
['a', null, 'c'] |> fs.filter(Boolean)
```

> optionally preceded by `new` or `await`

This seems very arbitrary and _not_ forwards-compatible.

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".

- Peter


On Sun, Mar 11, 2018 at 3:08 PM, "J. S. Choi" <js_c...@icloud.com> wrote:

> Thanks for the feedback, Peter and Naveen.
>
> ***
>
> @Peter:
>
> > It looks like this is different to the existing pipeline proposal in
> essentially only one way, in that it includes the # token (or lexical topic
> as you call it). I like that the proposal addresses await and other unary
> operators by default since it supports any expression on the right-hand
> side given a lexical topic is involved.
>
> 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`.
>
> 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.
>
> > One thing you may consider is automatic binding of unary operators
> similar to the automatic binding of unary functions / methods /
> constructors.
>
> I had considered that, but I decided against it. I want to keep the rules
> of bare style very simple and strict in order to minimize cognitive burden
> on the developer. Topic style is meant to also be terse: `x |> await # |>
> fn`, `await x |> fn`, `x |> typeof # |> fn`, or `typeof x |> fn`. There is
> also the forward-compatibility problem you mention.
>
> Thanks again for the feedback, Peter.
>
> ***
>
> @Naveen:
>
> > Can you explain how it solves the generator / async generator aspect of
> the proposal here: TheNavigateur/proposal-pipeline-operator-for-
> function-composition
>
> For background, the TheNavigateur proposal can rephrase this:
>
>     const doubleThenSquareThenHalf = value =>
>       half(square(double(value)));
>
> …as this:
>
>     const doubleThenSquareThenHalf =
>       double +> square +> half;
>
> The smart-pipeline proposal plus Additional Feature PF would express this
> as:
>
>     const doubleThenSquareThenHalf =
>       +> double |> square |> half;
>
> Likewise this:
>
>     const doubleThenSquareThenHalfAsync = async value =>
>       half(await squareAsync(double(value)));
>
> …may be this in the TheNavigateur proposal:
>
>     const doubleThenSquareThenHalfAsync =
>       double +> squareAsync +> half;
>
> …and this in the smart-pipeline proposal plus Feature PF:
>
>     const doubleThenSquareThenHalfAsync =
>       async +> double |> await squareAsync |> half;
>
> ***
>
> Smart pipelines, including with Additional Feature PF, only address piping
> singular values through expressions, as well as method extraction, partial
> application, and composition on functions on singular values. They do not
> yet address piping plural values such as iterators and generators. This is
> because there are many ways to compose plural values—mapping, reducing,
> filtering, partitioning, and so forth. I do plan to try to address this in
> the futer with Clojure-style transducers. But currently, you would have to
> rely on higher-order helper functions from a library or written by yourself
> to combine plural values.
>
> This:
>
>     const randomBetween0And100Generator = () => * {
>       for (randomBetween0And1Generator())
>         yield |> multiplyBy100;
>     };
>
> …may be this in the TheNavigateur proposal:
>
>     const randomBetween0And100Generator =
>       randomBetween0And1Generator +> multiplyBy100;
>
> …and this in the smart-pipeline proposal plus Feature PF and Feature PP:
>
>     const randomBetween0And100Generator = () => * {
>       for (randomBetween0And1Generator())
>         yield |> multiplyBy100;
>     };
>
> …or this, using some map helper function,
>
>     const randomBetween0And100Generator = () =>
>       randomBetween0And1Generator()
>       |> map(+> multiplyBy100, #);
>
> This is similar to how mapping arrays is not directly addressed by
> pipelines:
>
>     const arrayBetween0And100 =
>       arrayBetween0And1
>         .map(+> multiplyBy100, #);
>
> There are many ways to compose plural values—mapping, reducing, filtering,
> partitioning, and so forth. It is currently out of scope for smart
> pipelines to address them; they are not even well standardized in
> JavaScript in general. I do plan to try to address uniformly composing
> plural-valued functions in the future with a Clojure-style transducer API –
> first as a library, then maybe as as a TC39 proposal if I can find an
> interested TC39 member. See [Transducers.js](https://
> jlongster.com/Transducers.js--A-JavaScript-Library-for-
> Transformation-of-Data) for examples of this idea. But, no, currently,
> you would have to rely on higher-order helper functions from a library or
> written by yourself to combine plural-valued functions.
>
> For now, I’m focusing on the low-hanging fruit that smart pipelines could
> provide, before the next TC39 meeting. This includes a Babel plugin that I
> am creating in cooperation with James DiGioia, who is also working on a
> proposal for Proposal 1: F-sharp Style Only (https://github.com/tc39/
> proposal-pipeline-operator/wiki#proposal-1-f-sharp-style-only). We will
> see what comes of all this in the future.
>
> Warm regards,
> J. S. Choi
>
> _______________________________________________
> es-discuss mailing list
> es-discuss@mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss
>
_______________________________________________
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss

Reply via email to