diff --git a/readme.md b/readme.md
index 3a9cbd8..422ef84 100644
--- a/readme.md
+++ b/readme.md
@@ -58,7 +58,6 @@ ECMAScript Stage-0 Proposal. Living Document. J. S. Choi, 2018-02.
- [Terse function calls](#terse-function-calls)
- [Terse composition](#terse-composition)
- [Terse partial application](#terse-partial-application)
- - [Terse method extraction](#terse-method-extraction)
- [Other Goals](#other-goals)
- [Conceptual generality](#conceptual-generality)
- [Human writability](#human-writability)
@@ -3134,7 +3133,7 @@ feature – **Pipeline Functions** – would dramatically increase the usefulnes
pipelines. It introduces just one additional operator that solves:\
tacit unary **functional composition**,\
tacit unary functional **partial application**,\
-and tacit **method extraction**,\
+and many kinds of tacit **method extraction**,\
…all at the same time.
And with [Additional Feature NP][], this additional feature would *also* solve\
@@ -3608,8 +3607,8 @@ Meadows][isiahmeadows functional composition].
-**Method extraction** can be addressed by pipeline functions alone, as a natural
-result of their pipeline-operator-like semantics.\
+Many kinds of **method extraction** can be addressed by pipeline functions
+alone, as a natural result of their pipeline-operator-like semantics.\
`+> console.log` is equivalent to `(...$) => console.log(...$)`…
```js
Promise.resolve(123)
@@ -3618,7 +3617,6 @@ Promise.resolve(123)
|
-…and `(...$) => console.log(...$)` is equivalent to `console.log.bind(console)`.
```js
Promise.resolve(123)
.then(console.log.bind(console));
@@ -3642,6 +3640,79 @@ $('.some-link').on('click', ::view.reset);
|
+Note that this is *not* the same as `console.log.bind(console.log)`, which
+creates an exotic function that always uses whatever value `console.log`
+evaluates into – even if `console.log` is reassigned later.
+```js
+const consoleLog =
+ console.log.bind(console.log);
+const arrayFrom =
+ Array.from.bind(Array.from);
+const arrayMap =
+ Function.bind.call(Function.call,
+ Array.prototype.map);
+…
+input
+|> process
+|> consoleLog;
+input
+|> arrayFrom
+|> arrayMap(#, $ => $ + 1)
+|> consoleLog;
+```
+This [robust method extraction][] is a use case that this proposal leaves to
+another operator, such as prefix `::` or prefix `&`.
+
+ |
+
+```js
+const consoleLog =
+ console.log.bind(console.log);
+const arrayFrom =
+ Array.from.bind(Array.from);
+const arrayMap =
+ Function.bind.call(Function.call, Array.prototype.map);
+…
+consoleLog(
+ process(input));
+consoleLog(
+ arrayMap(arrayFrom(input), $ => $ + 1));
+```
+
+ |
+
+
+```js
+…
+input
+|> process
+|> &console.log;
+input
+|> &Array.from
+|> #::&Array.prototype.map($ => $ + 1)
+|> &console.log;
+```
+Pipeline functions would not preclude adding another operator that addresses
+[robust method extraction][] with [inline caching][method-extraction inline
+caching], such as the hypothetical prefix `&` operators (for cached method
+extraction) and infix `::` operators (for `this` binding) shown here. Such
+hypothetical notations could even be eventually accommodated by a new [bare
+style][] notation, shown here with `… |> &console.log` and `… |> &Array.from`.
+
+ |
+
+```js
+…
+consoleLog(
+ process(input));
+consoleLog(
+ &Array.from(input)
+ ::&Array.prototype.map($ => $ + 1));
+```
+
+ |
+
+
```js
const { hasOwnProperty } =
Object.prototype;
@@ -3649,8 +3720,8 @@ const x = { key: 5 };
x::hasOwnProperty;
x::hasOwnProperty('key');
```
-For terse **method calling/binding**, the infix `::` operator would still be
-required.
+For terse **method calling/binding**, the infix `::` operator would also still
+be required.
|
@@ -3661,9 +3732,6 @@ const x = { key: 5 };
x::hasOwnProperty;
x::hasOwnProperty('key');
```
-But the `::` operator would only need to handle method calls. No operator
-overloading of `::` for method extraction (that is, `::` as a prefix operator)
-would be needed.
@@ -5122,7 +5190,7 @@ for await (const c of stream) {
# Goals
-There are eighteen ordered goals that the smart body syntax tries to fulfill,
+There are seventeen ordered goals that the smart body syntax tries to fulfill,
which may be summarized,\
“Don’t break my code,”\
“Don’t make me overthink,”\
@@ -5768,8 +5836,8 @@ versatility] but also n-ary functions, object methods, async functions,
generators, `if` `else` statements, and so forth – is a goal of smart pipelines.
[Several alternative proposals also address function composition][function
composition], but [Additional Feature PF][] holistically addresses it with
-application, partial application, and method extraction, and not only for unary
-functions but also for expressions of any type.
+application, partial application, and some forms of method extraction, and not
+only for unary functions but also for expressions of any type.
### Terse partial application
Terse partial application of all expressions – [not only functions][expressive
@@ -5777,18 +5845,10 @@ versatility] but also object methods, async functions, generators, `if` `else`
statements, and so forth – is a goal of smart pipelines. [An existing
alternative proposal also addresses partial function application][partial
function application], but [Additional Feature PF][] holistically addresses it
-with application, partial application, and method extraction, and not only for
-unary functions but also for expressions of any type. [Additional Feature NP][]
-extends this ability to N-ary expressions, including variadic expressions.
-
-### Terse method extraction
-Terse method extraction – being able to use a method as a function without
-relying on `Function.prototype.bind`, such as using `console.log` as a callback
-function – is another goal of smart pipelines. Method extraction is also
-addressed by [Additional Feature PF][]. [An existing alternative proposal for
-function binding already addresses method extraction as a special case][function
-binding], but [Additional Feature PF][] holistically addresses method binding
-with composition, application, and partial application.
+with application, partial application, and some forms of method extraction, and
+not only for unary functions but also for expressions of any type. [Additional
+Feature NP][] extends this ability to N-ary expressions, including variadic
+expressions.
## Other Goals
Although these have been prioritized last, they are still important.
@@ -5802,8 +5862,8 @@ with [forward compatibility][]).
This proposal’s concept of a **topic reference does not need to be coupled only
to pipelines**. The topic concept is **generalizable to many syntactic forms**,
as the [additional features][] demonstrate. They together form one unified vision
-of a future in which composition, partial application, method extraction, and
-error handling are all tersely expressible with the same simple concepts.
+of a future in which composition, partial application, and error handling are
+all tersely expressible with the same simple concepts.
### Human writability
Writability of code is less important a priority than readability of code. Code
@@ -6066,22 +6126,17 @@ With [existing proposal][ECMAScript function binding]
|
-**Method extraction** can be addressed by pipeline functions alone, as a natural
-result of their pipeline-operator-like semantics.\
-`+> console.log` is equivalent to `$ => $ |> console.log`, which is a pipeline in
-[bare style][]. This in turn is `$ => console.log($)`…
+**Some** forms of **method extraction** can be addressed by pipeline functions
+alone, as a natural result of their pipeline-operator-like semantics.\
+`+> console.log` is equivalent to `(...$) => console.log(...$)`.
```js
Promise.resolve(123).then(+> console.log);
```
|
-…and `$ => console.log($)` is equivalent to `console.log.bind(console)`.
-```js
-Promise.resolve(123).then(console.log.bind(console));
-```
```js
-Promise.resolve(123).then(::console.log);
+Promise.resolve(123).then((...$) => console.log(...$));
```
|
@@ -6100,14 +6155,87 @@ $('.some-link').on('click', ::view.reset);
+Note that this is *not* the same as `console.log.bind(console.log)`, which
+creates an exotic function that always uses whatever value `console.log`
+evaluates into – even if `console.log` is reassigned later.
+```js
+const consoleLog =
+ console.log.bind(console.log);
+const arrayFrom =
+ Array.from.bind(Array.from);
+const arrayMap =
+ Function.bind.call(Function.call,
+ Array.prototype.map);
+…
+input
+|> process
+|> consoleLog;
+input
+|> arrayFrom
+|> arrayMap(#, $ => $ + 1)
+|> consoleLog;
+```
+This [robust method extraction][] is a use case that this proposal leaves to
+another operator, such as prefix `::` or prefix `&`.
+
+ |
+
+```js
+const consoleLog =
+ console.log.bind(console.log);
+const arrayFrom =
+ Array.from.bind(Array.from);
+const arrayMap =
+ Function.bind.call(Function.call, Array.prototype.map);
+…
+consoleLog(
+ process(input));
+consoleLog(
+ arrayMap(arrayFrom(input), $ => $ + 1));
+```
+
+ |
+
+
+```js
+…
+input
+|> process
+|> &console.log;
+input
+|> &Array.from
+|> #::&Array.prototype.map($ => $ + 1)
+|> &console.log;
+```
+Pipeline functions would not preclude adding another operator that addresses
+[robust method extraction][] with [inline caching][method-extraction inline
+caching], such as the hypothetical prefix `&` operators (for cached method
+extraction) and infix `::` operators (for `this` binding) shown here. Such
+hypothetical notations could even be eventually accommodated by a new [bare
+style][] notation, shown here with `… |> &console.log` and `… |> &Array.from`.
+
+ |
+
+```js
+…
+consoleLog(
+ process(input));
+consoleLog(
+ &Array.from(input)
+ ::&Array.prototype.map($ => $ + 1));
+```
+
+ |
+
+
```js
const { hasOwnProperty } = Object.prototype;
const x = { key: 5 };
x::hasOwnProperty;
x::hasOwnProperty('key');
```
-For terse **method calling/binding**, the infix `::` operator would still be
-required.
+For terse **method calling/binding**, the infix `::` operator would also still
+be required.
|
@@ -6117,9 +6245,6 @@ const x = { key: 5 };
x::hasOwnProperty;
x::hasOwnProperty('key');
```
-But the `::` operator would only need to handle method calls. No operator
-overloading of `::` for method extraction (that is, `::` as a prefix operator)
-would be needed.
|
@@ -7095,8 +7220,8 @@ function application][terse function calls] but also [terse N-ary function
application][terse function calls], [terse expression application][terse
function calls], [terse function composition][terse composition], [terse
expression composition][terse composition], [terse partial application][], and
-[terse method extraction][] – all with a single [cyclomatic simplicity][] and
-unified [general concept][conceptual generality].
+[terse method extraction][] – all with a single [simple][cyclomatic simplicity]
+and unified [general concept][conceptual generality].
Indeed, the original pipeline proposal was blocked from Stage 2 by TC39 during
its [60th meeting, on September 2017][TC39 60th meeting, pipelines], for similar
@@ -7808,8 +7933,8 @@ The pipeline chain is therefore equivalent to:\
[formal pipeline specification]: https://jschoi.org/18/es-smart-pipelines/spec
[formal PP]: https://jschoi.org/18/es-smart-pipelines/spec#sec-additional-feature-pp
[formal TS]: https://jschoi.org/18/es-smart-pipelines/spec#sec-additional-feature-ts
-[forward compatible]: #forward-compatibility
[forward compatibility]: #forward-compatibility
+[forward compatible]: #forward-compatibility
[function bind operator `::`]: #function-bind-operator
[function binding]: #function-binding
[function composition]: #function-composition
@@ -7850,6 +7975,7 @@ The pipeline chain is therefore equivalent to:\
[make my code easier to read]: #make-my-code-easier-to-read
[MDN operator precedence]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence
[MDN operator precedence]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence#Table
+[method-extraction inline caching]: https://github.com/tc39/proposal-bind-operator/issues/46
[mindeavor]: https://github.com/gilbert
[mode errors]: https://en.wikipedia.org/wiki/Mode_(computer_interface)#Mode_errors
[motivation]: #motivation
@@ -7893,6 +8019,7 @@ The pipeline chain is therefore equivalent to:\
[resolving topics]: #resolve-topic
[rest topic]: #additional-feature-np
[reverse Polish notation]: https://en.wikipedia.org/wiki/Reverse_Polish_notation
+[robust method extraction]: https://github.com/tc39/proposal-pipeline-operator/issues/110#issuecomment-374367888
[Ron Buckton]: https://github.com/rbuckton
[runtime semantics]: #runtime-semantics
[secondary topic]: #additional-feature-np
|