Skip to content
This repository was archived by the owner on Jan 26, 2022. It is now read-only.

Commit 7ce2f9e

Browse files
committed
Readme: Clarify relationship with robust method extraction
See #10.
1 parent 36493fa commit 7ce2f9e

File tree

1 file changed

+171
-44
lines changed

1 file changed

+171
-44
lines changed

readme.md

+171-44
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,6 @@ ECMAScript Stage-0 Proposal. Living Document. J. S. Choi, 2018-02.
5858
- [Terse function calls](#terse-function-calls)
5959
- [Terse composition](#terse-composition)
6060
- [Terse partial application](#terse-partial-application)
61-
- [Terse method extraction](#terse-method-extraction)
6261
- [Other Goals](#other-goals)
6362
- [Conceptual generality](#conceptual-generality)
6463
- [Human writability](#human-writability)
@@ -3134,7 +3133,7 @@ feature – **Pipeline Functions** – would dramatically increase the usefulnes
31343133
pipelines. It introduces just one additional operator that solves:\
31353134
tacit unary **functional composition**,\
31363135
tacit unary functional **partial application**,\
3137-
and tacit **method extraction**,\
3136+
and many kinds of tacit **method extraction**,\
31383137
…all at the same time.
31393138

31403139
And with [Additional Feature NP][], this additional feature would *also* solve\
@@ -3608,8 +3607,8 @@ Meadows][isiahmeadows functional composition].
36083607
<tr>
36093608
<td>
36103609
3611-
**Method extraction** can be addressed by pipeline functions alone, as a natural
3612-
result of their pipeline-operator-like semantics.\
3610+
Many kinds of **method extraction** can be addressed by pipeline functions
3611+
alone, as a natural result of their pipeline-operator-like semantics.\
36133612
`+> console.log` is equivalent to `(...$) => console.log(...$)`
36143613
```js
36153614
Promise.resolve(123)
@@ -3618,7 +3617,6 @@ Promise.resolve(123)
36183617
36193618
<td>
36203619
3621-
…and `(...$) => console.log(...$)` is equivalent to `console.log.bind(console)`.
36223620
```js
36233621
Promise.resolve(123)
36243622
.then(console.log.bind(console));
@@ -3642,15 +3640,88 @@ $('.some-link').on('click', ::view.reset);
36423640
<tr>
36433641
<td>
36443642
3643+
Note that this is *not* the same as `console.log.bind(console.log)`, which
3644+
creates an exotic function that always uses whatever value `console.log`
3645+
evaluates into – even if `console.log` is reassigned later.
3646+
```js
3647+
const consoleLog =
3648+
console.log.bind(console.log);
3649+
const arrayFrom =
3650+
Array.from.bind(Array.from);
3651+
const arrayMap =
3652+
Function.bind.call(Function.call,
3653+
Array.prototype.map);
3654+
3655+
input
3656+
|> process
3657+
|> consoleLog;
3658+
input
3659+
|> arrayFrom
3660+
|> arrayMap(#, $ => $ + 1)
3661+
|> consoleLog;
3662+
```
3663+
This [robust method extraction][] is a use case that this proposal leaves to
3664+
another operator, such as prefix `::` or prefix `&`.
3665+
3666+
<td>
3667+
3668+
```js
3669+
const consoleLog =
3670+
console.log.bind(console.log);
3671+
const arrayFrom =
3672+
Array.from.bind(Array.from);
3673+
const arrayMap =
3674+
Function.bind.call(Function.call, Array.prototype.map);
3675+
3676+
consoleLog(
3677+
process(input));
3678+
consoleLog(
3679+
arrayMap(arrayFrom(input), $ => $ + 1));
3680+
```
3681+
3682+
<tr>
3683+
<td>
3684+
3685+
```js
3686+
3687+
input
3688+
|> process
3689+
|> &console.log;
3690+
input
3691+
|> &Array.from
3692+
|> #::&Array.prototype.map($ => $ + 1)
3693+
|> &console.log;
3694+
```
3695+
Pipeline functions would not preclude adding another operator that addresses
3696+
[robust method extraction][] with [inline caching][method-extraction inline
3697+
caching], such as the hypothetical prefix `&` operators (for cached method
3698+
extraction) and infix `::` operators (for `this` binding) shown here. Such
3699+
hypothetical notations could even be eventually accommodated by a new [bare
3700+
style][] notation, shown here with `|> &console.log` and `|> &Array.from`.
3701+
3702+
<td>
3703+
3704+
```js
3705+
3706+
consoleLog(
3707+
process(input));
3708+
consoleLog(
3709+
&Array.from(input)
3710+
::&Array.prototype.map($ => $ + 1));
3711+
```
3712+
3713+
<tr>
3714+
<td>
3715+
36453716
```js
36463717
const { hasOwnProperty } =
36473718
Object.prototype;
36483719
const x = { key: 5 };
36493720
x::hasOwnProperty;
36503721
x::hasOwnProperty('key');
36513722
```
3652-
For terse **method calling/binding**, the infix `::` operator would still be
3653-
required.
3723+
For terse **method calling/binding**, the infix `::` operator would also still
3724+
be required.
36543725
36553726
<td>
36563727
@@ -3661,9 +3732,6 @@ const x = { key: 5 };
36613732
x::hasOwnProperty;
36623733
x::hasOwnProperty('key');
36633734
```
3664-
But the `::` operator would only need to handle method calls. No operator
3665-
overloading of `::` for method extraction (that is, `::` as a prefix operator)
3666-
would be needed.
36673735
36683736
</table>
36693737
@@ -5122,7 +5190,7 @@ for await (const c of stream) {
51225190
51235191
# Goals
51245192
5125-
There are eighteen ordered goals that the smart body syntax tries to fulfill,
5193+
There are seventeen ordered goals that the smart body syntax tries to fulfill,
51265194
which may be summarized,\
51275195
“Don’t break my code,”\
51285196
“Don’t make me overthink,”\
@@ -5768,27 +5836,19 @@ versatility] but also n-ary functions, object methods, async functions,
57685836
generators, `if` `else` statements, and so forth – is a goal of smart pipelines.
57695837
[Several alternative proposals also address function composition][function
57705838
composition], but [Additional Feature PF][] holistically addresses it with
5771-
application, partial application, and method extraction, and not only for unary
5772-
functions but also for expressions of any type.
5839+
application, partial application, and some forms of method extraction, and not
5840+
only for unary functions but also for expressions of any type.
57735841
57745842
### Terse partial application
57755843
Terse partial application of all expressions – [not only functions][expressive
57765844
versatility] but also object methods, async functions, generators, `if` `else`
57775845
statements, and so forth – is a goal of smart pipelines. [An existing
57785846
alternative proposal also addresses partial function application][partial
57795847
function application], but [Additional Feature PF][] holistically addresses it
5780-
with application, partial application, and method extraction, and not only for
5781-
unary functions but also for expressions of any type. [Additional Feature NP][]
5782-
extends this ability to N-ary expressions, including variadic expressions.
5783-
5784-
### Terse method extraction
5785-
Terse method extraction – being able to use a method as a function without
5786-
relying on `Function.prototype.bind`, such as using `console.log` as a callback
5787-
function – is another goal of smart pipelines. Method extraction is also
5788-
addressed by [Additional Feature PF][]. [An existing alternative proposal for
5789-
function binding already addresses method extraction as a special case][function
5790-
binding], but [Additional Feature PF][] holistically addresses method binding
5791-
with composition, application, and partial application.
5848+
with application, partial application, and some forms of method extraction, and
5849+
not only for unary functions but also for expressions of any type. [Additional
5850+
Feature NP][] extends this ability to N-ary expressions, including variadic
5851+
expressions.
57925852
57935853
## Other Goals
57945854
Although these have been prioritized last, they are still important.
@@ -5802,8 +5862,8 @@ with [forward compatibility][]).
58025862
This proposal’s concept of a **topic reference does not need to be coupled only
58035863
to pipelines**. The topic concept is **generalizable to many syntactic forms**,
58045864
as the [additional features][] demonstrate. They together form one unified vision
5805-
of a future in which composition, partial application, method extraction, and
5806-
error handling are all tersely expressible with the same simple concepts.
5865+
of a future in which composition, partial application, and error handling are
5866+
all tersely expressible with the same simple concepts.
58075867
58085868
### Human writability
58095869
Writability of code is less important a priority than readability of code. Code
@@ -6066,22 +6126,17 @@ With [existing proposal][ECMAScript function binding]
60666126
<tr>
60676127
<td>
60686128

6069-
**Method extraction** can be addressed by pipeline functions alone, as a natural
6070-
result of their pipeline-operator-like semantics.\
6071-
`+> console.log` is equivalent to `$ => $ |> console.log`, which is a pipeline in
6072-
[bare style][]. This in turn is `$ => console.log($)`…
6129+
**Some** forms of **method extraction** can be addressed by pipeline functions
6130+
alone, as a natural result of their pipeline-operator-like semantics.\
6131+
`+> console.log` is equivalent to `(...$) => console.log(...$)`.
60736132
```js
60746133
Promise.resolve(123).then(+> console.log);
60756134
```
60766135

60776136
<td>
60786137

6079-
…and `$ => console.log($)` is equivalent to `console.log.bind(console)`.
6080-
```js
6081-
Promise.resolve(123).then(console.log.bind(console));
6082-
```
60836138
```js
6084-
Promise.resolve(123).then(::console.log);
6139+
Promise.resolve(123).then((...$) => console.log(...$));
60856140
```
60866141

60876142
<tr>
@@ -6100,14 +6155,87 @@ $('.some-link').on('click', ::view.reset);
61006155
<tr>
61016156
<td>
61026157

6158+
Note that this is *not* the same as `console.log.bind(console.log)`, which
6159+
creates an exotic function that always uses whatever value `console.log`
6160+
evaluates into – even if `console.log` is reassigned later.
6161+
```js
6162+
const consoleLog =
6163+
console.log.bind(console.log);
6164+
const arrayFrom =
6165+
Array.from.bind(Array.from);
6166+
const arrayMap =
6167+
Function.bind.call(Function.call,
6168+
Array.prototype.map);
6169+
6170+
input
6171+
|> process
6172+
|> consoleLog;
6173+
input
6174+
|> arrayFrom
6175+
|> arrayMap(#, $ => $ + 1)
6176+
|> consoleLog;
6177+
```
6178+
This [robust method extraction][] is a use case that this proposal leaves to
6179+
another operator, such as prefix `::` or prefix `&`.
6180+
6181+
<td>
6182+
6183+
```js
6184+
const consoleLog =
6185+
console.log.bind(console.log);
6186+
const arrayFrom =
6187+
Array.from.bind(Array.from);
6188+
const arrayMap =
6189+
Function.bind.call(Function.call, Array.prototype.map);
6190+
6191+
consoleLog(
6192+
process(input));
6193+
consoleLog(
6194+
arrayMap(arrayFrom(input), $ => $ + 1));
6195+
```
6196+
6197+
<tr>
6198+
<td>
6199+
6200+
```js
6201+
6202+
input
6203+
|> process
6204+
|> &console.log;
6205+
input
6206+
|> &Array.from
6207+
|> #::&Array.prototype.map($ => $ + 1)
6208+
|> &console.log;
6209+
```
6210+
Pipeline functions would not preclude adding another operator that addresses
6211+
[robust method extraction][] with [inline caching][method-extraction inline
6212+
caching], such as the hypothetical prefix `&` operators (for cached method
6213+
extraction) and infix `::` operators (for `this` binding) shown here. Such
6214+
hypothetical notations could even be eventually accommodated by a new [bare
6215+
style][] notation, shown here with `… |> &console.log` and `… |> &Array.from`.
6216+
6217+
<td>
6218+
6219+
```js
6220+
6221+
consoleLog(
6222+
process(input));
6223+
consoleLog(
6224+
&Array.from(input)
6225+
::&Array.prototype.map($ => $ + 1));
6226+
```
6227+
6228+
<tr>
6229+
<td>
6230+
61036231
```js
61046232
const { hasOwnProperty } = Object.prototype;
61056233
const x = { key: 5 };
61066234
x::hasOwnProperty;
61076235
x::hasOwnProperty('key');
61086236
```
6109-
For terse **method calling/binding**, the infix `::` operator would still be
6110-
required.
6237+
For terse **method calling/binding**, the infix `::` operator would also still
6238+
be required.
61116239
61126240
<td>
61136241
@@ -6117,9 +6245,6 @@ const x = { key: 5 };
61176245
x::hasOwnProperty;
61186246
x::hasOwnProperty('key');
61196247
```
6120-
But the `::` operator would only need to handle method calls. No operator
6121-
overloading of `::` for method extraction (that is, `::` as a prefix operator)
6122-
would be needed.
61236248
61246249
<tr>
61256250
<td>
@@ -7095,8 +7220,8 @@ function application][terse function calls] but also [terse N-ary function
70957220
application][terse function calls], [terse expression application][terse
70967221
function calls], [terse function composition][terse composition], [terse
70977222
expression composition][terse composition], [terse partial application][], and
7098-
[terse method extraction][] – all with a single [cyclomatic simplicity][] and
7099-
unified [general concept][conceptual generality].
7223+
[terse method extraction][] – all with a single [simple][cyclomatic simplicity]
7224+
and unified [general concept][conceptual generality].
71007225
71017226
Indeed, the original pipeline proposal was blocked from Stage 2 by TC39 during
71027227
its [60th meeting, on September 2017][TC39 60th meeting, pipelines], for similar
@@ -7808,8 +7933,8 @@ The pipeline chain is therefore equivalent to:\
78087933
[formal pipeline specification]: https://jschoi.org/18/es-smart-pipelines/spec
78097934
[formal PP]: https://jschoi.org/18/es-smart-pipelines/spec#sec-additional-feature-pp
78107935
[formal TS]: https://jschoi.org/18/es-smart-pipelines/spec#sec-additional-feature-ts
7811-
[forward compatible]: #forward-compatibility
78127936
[forward compatibility]: #forward-compatibility
7937+
[forward compatible]: #forward-compatibility
78137938
[function bind operator `::`]: #function-bind-operator
78147939
[function binding]: #function-binding
78157940
[function composition]: #function-composition
@@ -7850,6 +7975,7 @@ The pipeline chain is therefore equivalent to:\
78507975
[make my code easier to read]: #make-my-code-easier-to-read
78517976
[MDN operator precedence]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence
78527977
[MDN operator precedence]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence#Table
7978+
[method-extraction inline caching]: https://github.com/tc39/proposal-bind-operator/issues/46
78537979
[mindeavor]: https://github.com/gilbert
78547980
[mode errors]: https://en.wikipedia.org/wiki/Mode_(computer_interface)#Mode_errors
78557981
[motivation]: #motivation
@@ -7893,6 +8019,7 @@ The pipeline chain is therefore equivalent to:\
78938019
[resolving topics]: #resolve-topic
78948020
[rest topic]: #additional-feature-np
78958021
[reverse Polish notation]: https://en.wikipedia.org/wiki/Reverse_Polish_notation
8022+
[robust method extraction]: https://github.com/tc39/proposal-pipeline-operator/issues/110#issuecomment-374367888
78968023
[Ron Buckton]: https://github.com/rbuckton
78978024
[runtime semantics]: #runtime-semantics
78988025
[secondary topic]: #additional-feature-np

0 commit comments

Comments
 (0)