Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings
J. S. Choi edited this pageMar 18, 2022 ·126 revisions

This is the wiki, which just about anyone can edit.

Please check the sidebar for subpages, such as thetopic-token bikeshedding page andtooling status page.

Other useful documents you may want to read include:

Overview of previous proposals

The following is an archive of a previous wiki home page that summarized our public discussions.

For more detailed information on the history of the pipe proposal, please seeHISTORY.md.


Goals

  • Easy composition of functions for immediate invocation
  • Support for any function arity, not just unary functions
  • Easy composition of other expressions (method calls, math, array/object literals,new object construction, etc.)
  • Able toawait in the middle of a pipeline
  • Method calls without binding
  • Avoiding accidental footguns that would result in runtime errors

Summary of proposals’ behavior

Original expressionProposal 0 (minimal F#)Proposal 1 (F# pipes +await)Proposal 2 (Hack pipes)
o.m(x)x |> o.mx |> o.mx |> o.m(^)
o.m(0, x)x |> y=>o.m(0, y)x |> y=>o.m(0, y)x |> o.m(0, ^)
new o.m(x)x |> y=>new o.m(y)x |> y=>new o.m(y)x |> new o.m(^)
o[x]x |> y=>o[y]x |> y=>o[y]x |> o[^]
x[i]x |> y=>y[i]x |> y=>y[i]x |> ^[i]
x + 1x |> y=>y + 1x |> y=>y + 1x |> ^ + 1
[0, x]x |> y=>[0, y]x |> y=>[0, y]x |> [0, ^]
{ key: x }x |> y=>({ key: y })x |> y=>({ key: y })x |> { key: ^ }
await o.m(x)Not supportedx |> o.m |> awaitx |> await o.m(^)
yield o.m(x)Not supportedNot supportedx |> (yield o.m(^))

Proposal 0: Minimal F# style

Minimal-F#-styleexplainer
Minimal-F#-styleexplainer

The F# (F-sharp / F♯) style|> invokes the right-hand side with the evaluated result of the left. It has also been called “implicit call”, “tacit” and “point-free” style.

  • Unary function calls are very terse
  • Anything else must be wrapped in an arrow function
  • Arrow functions might or might not have to be wrapped in parentheses
  • Cannot handleawait oryield expressions, which are scoped to their innermost function.

Proposal 1: F# style withawait syntax

F#-style-with-awaitexplainer
F#-style-with-awaitspecification

The F# (F-sharp / F♯) style|> invokes the right-hand side with the evaluated result of the left. It has also been called “implicit call”, “tacit” and “point-free” style. Proposal 1 is specifically for F# style only along withspecial extra syntax forawait.Proposal 0 is similarexcept it forbidsawait in its RHS.

  • Unary function calls are very terse
  • Anything else must be wrapped in an arrow function
  • Arrow functions might or might not have to be wrapped in parentheses
  • Handlesawait expressions with special extra syntax (|> await)
  • Cannot handleyield expressions, which are scoped to their innermost function.
// Basic Usagex|>f//-->  f(x)x|>f(y)//-->  f(y)(x)// 2+ Arity Usagex|>(a=>f(a,10))//-->  f(x,10)// Async Solutionx|>f|>await//-->  await f(x)x|>f|>await|>g//-->  g(await f(x))// Other Expressionsf(x)|>(a=>a.data)//-->  f(x).dataf(x)|>(a=>a[a.length-1])//-->  let temp=f(x), temp[temp.length-1]f(x)|>(a=>({result:a}))//-->  { result: f(x) }// Complex exampleanArray=>(anArray|>a=>pickEveryN(a,2)|>a=>a.filter(...)|>makeQuery|>a=>readDB(a,config)|>await|>extractRemoteUrl|>fetch|>await|>parse|>console.log);

Proposal 2: Hack style

Hack-styleexplainer
Hack-stylespecification

The Hack style|> evaluates the left-hand side and assigns it to a temporary binding scoped to the right-hand side. First proposed inissue #84. It has also been called “topic”, “binding”, “placeholder”, and “parameterized” style.

  • Pipe to any expression using an explicit placeholder token^
  • Placeholder token can go where any normal variable can go
  • Placeholder token might be? or^ or@ or# (seeissue #91)
  • No tacit unary function calls, need to add(^) to their ends
  • Handlesawait andyield expressions without special extra syntax
  • Forward compatible with both split mix (Proposal 3) and smart mix (Proposal 4)

Tab Atkins explains why he prefers Hack style.

// Basic Usagex|>f(^)//-->   f(x)x|>f(y)(^)//-->   f(y)(x)x|>f//-->   Syntax Error// 2+ Arity Usagex|>f(^,10)//-->  f(x,10)// Async Solution (Note this would not require special casing)x|>awaitf(^)//-->  await f(x)x|>awaitf(^)|>g(^)//-->  g(await f(x))// Other Expressionsf(x)|>^.data//-->  f(x).dataf(x)|>^[^.length-1]//-->  let temp=f(x), temp[temp.length-1]f(x)|>{result:^}//-->  { result: f(x) }// Complex exampleanArray=>anArray|>pickEveryN(^,2)|>^.filter(...)|>makeQuery(^)|>awaitreadDB(^,config)|>extractRemoteUrl(^)|>awaitfetch(^)|>parse(^)|>console.log(^);

Proposal 3: Split mix

Since both F# and Hack style proposals have desirable properties, it’s worth considering proposals that mix them together in a cohesive manner. Discussed inissue #89; previously discussed inissue #75 andissue #84.

  • Requires browser vendors to agree to implement two similar pipe operators, so nobody is currently backing this proposal
  • One operator for expressions with placeholder tokens (Hack style), e.g.,|> or|:
    • Pipe to any expression using an explicit placeholder token^
    • Placeholder token can go where any normal variable can go
  • Placeholder token might be? or^ or@ or# (seeissue #91)
    • Handlesawait andyield expressions without special extra syntax
  • One operator for tacit unary function calls (F# style), e.g.,|>> or|>
    • Unary function calls are very terse
// Basic Usagex|>>f//-->   f(x)x|>f(^)//-->   f(x)x|>>f(y)//-->   f(y)(x)x|>f(y)(^)//-->   Syntax Error// 2+ Arity Usagex|>f(^,10)//-->  f(x,10)// Async solution (does not require special casing)x|>awaitf(^)//-->  await f(x)x|>awaitf(^)|>g//-->  g(await f(x))// Other expressionsf(x)|>^.data//-->  f(x).dataf(x)|>^[^.length-1]//-->  let temp=f(x), temp[temp.length-1]f(x)|>{result:^}//-->  { result: f(x) }// Complex exampleanArray=>anArray|>pickEveryN(^,2)|>^.filter(...)|>>makeQuery|>awaitreadDB(^,config)|>>extractRemoteUrl|>>awaitfetch(^)|>>parse|>>console.log;

Proposal 4: Smart mix

Smart-mixexplainer
Smart-mixspecification

  • This proposal waswithdrawn in favor of Hack style, which is forward compatible with this proposal
  • Combines features of the two main proposals into a single operator
  • Topic/Hack style:
    • Pipe to any expression using an explicit placeholder token^
    • Placeholder token can go where any normal variable can go
    • Placeholder token might be^ or? or% or@ or# (seeissue #91)
    • Handlesawait andyield expressions without special extra syntax
  • Tacit/bare/F# style:
    • Unary function calls are very terse if a specific syntax
    • The expression must be a “simple” reference: one or more identifiers separated by., likeconsole.log
    • The cannot contain parentheses, brackets, braces, the placeholder token, or other operators
  • Syntax error when body of pipeline does not match either style
    • Ensures easy distinguishability between topic mode and F# mode
    • x |> f(a, b) is invalid and must be disambiguated intox |> f(^, a, b),x |> f(a, ^, b),x |> f(a, b, ^), orx |> f(a, b)(^)
  • If body of pipeline is currently written in F# style, and you realize you want to do something else to it, you must shift it to Hack style;
    it’s a compile-time syntax error if you forget
// Basic Usagex|>f//-->   f(x)x|>f(^)//-->   f(x)// 2+ Arity Usagex|>f(y)//-->   Syntax Errorx|>f(y,^)//-->   f(y, x)x|>f(^,y)//-->   f(x, y)x|>f(y)(^)//-->   f(y)(x)// Async Solution (Note this would not require special casing)x|>awaitf(^)//-->  await f(x)x|>awaitf(^)|>g//-->  g(await f(x))// Arbitrary Expressionsf(x)|>^.data//-->  f(x).dataf(x)|>^[^.length-1]//-->  let temp=f(x), temp[temp.length-1]f(x)|>{result:^}//-->  { result: f(x) }// Complex ExampleanArray=>anArray|>pickEveryN(^,2)|>^.filter($=>$>0)|>makeQuery|>awaitreadDB(^,config)|>extractRemoteUrl|>awaitfetch(^)|>parse|>newUser.Result(^)|>console.log;

[8]ページ先頭

©2009-2025 Movatter.jp