Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Inconsistency of type inference of Hack-style pipeline-operator proposal (Stage2) #46101

Closed
ken-okabe opened this issue Sep 27, 2021 · 2 comments
Labels
External Relates to another program, environment, or user action which we cannot control. Unactionable There isn't something we can do with this issue

Comments

@ken-okabe
Copy link

ken-okabe commented Sep 27, 2021

lib Update Request

This report is about tc39/proposal-pipeline-operator and especially TypeScript inference issue:

Unlike the F#-style, the Hack-style is incompatible with the majority of pipeable APIs that already exist—data-last functions in widely used libraries such as RxJS and fp-ts.

Configuration Check

My compilation target is ESNext and my lib is: Babel REPL (which doesn't do any type-checking).
https://babeljs.io/repl#?code_lz=MYewdgzgLgBAZiEMC8MAUBDAXDMBXAWwCMBTAJwBoYid9jyBKFAPhgxgGpqBuAKFEiwiGMinTZchUpWq0pjFmxgAqHv3DQYANwwAbPCTEBGPrz3koaAAa8AJAG8d-wwB9WCEGiNUApEzfUImgATL4MAL529mhOBjABHl5h_qzCZCFhkQ6xrqxoid4wfvGpQaFFDBG8Vgx8QA&presets=stage-1%2Ctypescript

You first need to select "Pipeline proposal > Hack" in the left sidebar, and then either click on evaluate or (since sometimes evaluate doesn't work) copy-paste the output code in the console.

The Babel implementation has been done by @js-choi (one of the champions of the Hack pipes proposal).

( tc39/proposal-pipeline-operator#227 (comment) )

Missing / Incorrect Definition

TC39 proposal Hack Pipeline Operator |> is incompatible with Grouping operator ().

Sample Code

Test Code 1:

const f = a => a * 2;
const g = a => a + 1;

1 |> f(^) |> g(^);
1 |> (f(^) |> g(^));  

Now we made (f(^) |> g(^)) to be evaluated before other expressions with higher priority.

I've investigated with Babel, and the transpiled result is identical, which means:
(f(^) |> g(^)) is NOT evaluated before other expressions with the rule of Grouping operator ( ).

image

The current proposal Hack |> overrides the functionality of Grouping operator that has the highest precedence in JavaScript.

Operator precedence

image

Test Code 2:

Now I have a log function.

const right = a => b => b;
const log = a => right(console.log(a))(a);

This behaves like identity function: a => a which does not affect to the original code but console.log(a) in the process.

Now, we want to know the evaluated value of (f(%) |> g(%))

1 |> (log(f(%) |> g(%)));

This should be totally fine because (f(%) |> g(%)) must have some value of the evaluation according to:

The grouping operator consists of a pair of parentheses around an expression or sub-expression to override the normal operator precedence so that expressions with lower precedence can be evaluated before an expression with higher priority.

File:Some babel code.jpg

The vanilla JS code is:

var _ref, _ref2, _ref3, _ref4;
const id = a => a;
const right = a => b => b;
const log = a => right(console.log(a))(a);
const f = a => a * 2;
const g = a => a + 1;
_ref2 = 1, (_ref = f(_ref2), g(_ref));
_ref4 = 1, log((_ref3 = f(_ref4), g(_ref3)));

and the result is:
3

Therefore,

1 |> (f(%) |> g(%));

where (f(%) |> g(%)) == 3

1 |> (f(%) |> g(%))
==
1 |> 3

???

and the evaluation value of whole 1 |> (f(%) |> g(%)) is 3
therefore,
1 |> 3 == 3

I observer the current TC39 proposal (Stage2) Hack-style pipeline-operator is, since the binary-operator no longer holds mathematical consistency, impossible to infer by TypeScript.

Documentation Link

I explained this anomaly thoroughly here:

TC39/proposal-pipeline-operator Hack-style |> hijacks Grouping operator ( )

@ken-okabe ken-okabe changed the title Concerns regarding type inference of Hack-style pipeline-operator proposal (Stage2) Inconsistency of type inference of Hack-style pipeline-operator proposal (Stage2) Sep 27, 2021
@andrewbranch andrewbranch added the Unactionable There isn't something we can do with this issue label Sep 27, 2021
@andrewbranch andrewbranch added the External Relates to another program, environment, or user action which we cannot control. label Sep 27, 2021
@andrewbranch
Copy link
Member

Please stop using the TypeScript issue tracker for general feedback about TC39 proposals. Rest assured we are thinking about the type inference implications of pipelines and monitoring the discussion on the proposal repo.

@ken-okabe
Copy link
Author

ken-okabe commented Sep 27, 2021

Rest assured we are thinking about the type inference implications of pipelines and monitoring the discussion on the proposal repo.

You should be correct as long as they don't hide issues or delete comments for the purpose of giving wrong impression for externals who watch the issue.

Having said that, I agree to stop here for this matter, thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
External Relates to another program, environment, or user action which we cannot control. Unactionable There isn't something we can do with this issue
Projects
None yet
Development

No branches or pull requests

2 participants