@@ -58,7 +58,6 @@ ECMAScript Stage-0 Proposal. Living Document. J. S. Choi, 2018-02.
58
58
- [ Terse function calls] ( #terse-function-calls )
59
59
- [ Terse composition] ( #terse-composition )
60
60
- [ Terse partial application] ( #terse-partial-application )
61
- - [ Terse method extraction] ( #terse-method-extraction )
62
61
- [ Other Goals] ( #other-goals )
63
62
- [ Conceptual generality] ( #conceptual-generality )
64
63
- [ Human writability] ( #human-writability )
@@ -3134,7 +3133,7 @@ feature – **Pipeline Functions** – would dramatically increase the usefulnes
3134
3133
pipelines. It introduces just one additional operator that solves:\
3135
3134
tacit unary ** functional composition** ,\
3136
3135
tacit unary functional ** partial application** ,\
3137
- and tacit ** method extraction** ,\
3136
+ and many kinds of tacit ** method extraction** ,\
3138
3137
…all at the same time.
3139
3138
3140
3139
And with [ Additional Feature NP] [ ] , this additional feature would * also* solve\
@@ -3608,8 +3607,8 @@ Meadows][isiahmeadows functional composition].
3608
3607
<tr>
3609
3608
<td>
3610
3609
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.\
3613
3612
` + > console .log ` is equivalent to ` (... $ ) => console .log (... $)` …
3614
3613
` ` ` js
3615
3614
Promise .resolve (123 )
@@ -3618,7 +3617,6 @@ Promise.resolve(123)
3618
3617
3619
3618
<td>
3620
3619
3621
- …and ` (... $ ) => console .log (... $)` is equivalent to ` console .log .bind (console )` .
3622
3620
` ` ` js
3623
3621
Promise .resolve (123 )
3624
3622
.then (console .log .bind (console ));
@@ -3642,15 +3640,88 @@ $('.some-link').on('click', ::view.reset);
3642
3640
<tr>
3643
3641
<td>
3644
3642
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
+
3645
3716
` ` ` js
3646
3717
const { hasOwnProperty } =
3647
3718
Object .prototype ;
3648
3719
const x = { key: 5 };
3649
3720
x:: hasOwnProperty;
3650
3721
x:: hasOwnProperty (' key' );
3651
3722
` ` `
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.
3654
3725
3655
3726
<td>
3656
3727
@@ -3661,9 +3732,6 @@ const x = { key: 5 };
3661
3732
x:: hasOwnProperty;
3662
3733
x:: hasOwnProperty (' key' );
3663
3734
` ` `
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.
3667
3735
3668
3736
</table>
3669
3737
@@ -5122,7 +5190,7 @@ for await (const c of stream) {
5122
5190
5123
5191
# Goals
5124
5192
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,
5126
5194
which may be summarized,\
5127
5195
“Don’t break my code,”\
5128
5196
“Don’t make me overthink,”\
@@ -5768,27 +5836,19 @@ versatility] but also n-ary functions, object methods, async functions,
5768
5836
generators, ` if ` ` else ` statements, and so forth – is a goal of smart pipelines.
5769
5837
[Several alternative proposals also address function composition][function
5770
5838
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.
5773
5841
5774
5842
### Terse partial application
5775
5843
Terse partial application of all expressions – [not only functions][expressive
5776
5844
versatility] but also object methods, async functions, generators, ` if ` ` else `
5777
5845
statements, and so forth – is a goal of smart pipelines. [An existing
5778
5846
alternative proposal also addresses partial function application][partial
5779
5847
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.
5792
5852
5793
5853
## Other Goals
5794
5854
Although these have been prioritized last, they are still important.
@@ -5802,8 +5862,8 @@ with [forward compatibility][]).
5802
5862
This proposal’s concept of a **topic reference does not need to be coupled only
5803
5863
to pipelines**. The topic concept is **generalizable to many syntactic forms**,
5804
5864
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.
5807
5867
5808
5868
### Human writability
5809
5869
Writability of code is less important a priority than readability of code. Code
@@ -6066,22 +6126,17 @@ With [existing proposal][ECMAScript function binding]
6066
6126
<tr>
6067
6127
<td>
6068
6128
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(... $)`.
6073
6132
```js
6074
6133
Promise.resolve(123 ).then(+ > console .log );
6075
6134
```
6076
6135
6077
6136
<td>
6078
6137
6079
- …and `$ => console.log($)` is equivalent to `console.log.bind(console )`.
6080
- ```js
6081
- Promise.resolve(123 ).then(console .log .bind (console ));
6082
- ```
6083
6138
```js
6084
- Promise.resolve(123 ).then(:: console .log );
6139
+ Promise.resolve(123 ).then(( ... $ ) => console .log ( ... $) );
6085
6140
```
6086
6141
6087
6142
<tr>
@@ -6100,14 +6155,87 @@ $('.some-link').on('click', ::view.reset);
6100
6155
<tr>
6101
6156
<td>
6102
6157
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
+
6103
6231
```js
6104
6232
const { hasOwnProperty } = Object .prototype ;
6105
6233
const x = { key: 5 };
6106
6234
x:: hasOwnProperty;
6107
6235
x:: hasOwnProperty (' key' );
6108
6236
` ` `
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.
6111
6239
6112
6240
<td>
6113
6241
@@ -6117,9 +6245,6 @@ const x = { key: 5 };
6117
6245
x:: hasOwnProperty;
6118
6246
x:: hasOwnProperty (' key' );
6119
6247
` ` `
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.
6123
6248
6124
6249
<tr>
6125
6250
<td>
@@ -7095,8 +7220,8 @@ function application][terse function calls] but also [terse N-ary function
7095
7220
application][terse function calls], [terse expression application][terse
7096
7221
function calls], [terse function composition][terse composition], [terse
7097
7222
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].
7100
7225
7101
7226
Indeed, the original pipeline proposal was blocked from Stage 2 by TC39 during
7102
7227
its [60th meeting, on September 2017][TC39 60th meeting, pipelines], for similar
@@ -7808,8 +7933,8 @@ The pipeline chain is therefore equivalent to:\
7808
7933
[formal pipeline specification]: https:// jschoi.org/18/es-smart-pipelines/spec
7809
7934
[formal PP]: https:// jschoi.org/18/es-smart-pipelines/spec#sec-additional-feature-pp
7810
7935
[formal TS]: https:// jschoi.org/18/es-smart-pipelines/spec#sec-additional-feature-ts
7811
- [forward compatible]: #forward-compatibility
7812
7936
[forward compatibility]: #forward-compatibility
7937
+ [forward compatible]: #forward-compatibility
7813
7938
[function bind operator `::`]: #function-bind-operator
7814
7939
[function binding]: #function-binding
7815
7940
[function composition]: #function-composition
@@ -7850,6 +7975,7 @@ The pipeline chain is therefore equivalent to:\
7850
7975
[make my code easier to read]: #make-my-code-easier-to-read
7851
7976
[MDN operator precedence]: https:// developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence
7852
7977
[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
7853
7979
[mindeavor]: https:// github.com/gilbert
7854
7980
[mode errors]: https:// en.wikipedia.org/wiki/Mode_(computer_interface)#Mode_errors
7855
7981
[motivation]: #motivation
@@ -7893,6 +8019,7 @@ The pipeline chain is therefore equivalent to:\
7893
8019
[resolving topics]: #resolve-topic
7894
8020
[rest topic]: #additional-feature-np
7895
8021
[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
7896
8023
[Ron Buckton]: https:// github.com/rbuckton
7897
8024
[runtime semantics]: #runtime-semantics
7898
8025
[secondary topic]: #additional-feature-np
0 commit comments