rescript-compiler icon indicating copy to clipboard operation
rescript-compiler copied to clipboard

Explore uncurried by default

Open cristianoc opened this issue 1 year ago • 4 comments

This issue is about exploring technical changes required to explore how uncurried by default would feel like in practice.

The basic idea is to have an uncurried-by-default mode, to be turned on in some way. Presumably by config to begin with. So that existing projects are not affected and one can turn on by config and start using the new mode. It could be nice to have some support to "convert" between curried and uncurried by default (a syntax change where code is parsed in curried mode and printed in uncurried mode).

  • Syntax swap. The function (x, y) => x+y would be uncurried and (. x, y) => x+y curried.

  • Mixed declarations. The current syntax (x, .y, z) => ... is problematic and at best ambiguous. Probably just drop it.

  • Builtin operators. The expression x+y uses the uncurried operator +. Probably + should become uncurried when uncurried mode is active. And/or require opening an uncurried flavour of pervasives.

  • Optional/default arguments. The critical case is JSX. That is already taken care of in V4, (when V4 is used, only 1 argument is used anyway so it does not really matter whether one uses the uncurried or curried convention). For user space functions other than JSX, the V4 ppx shows already that it is possible to encode default args. A more first-class support can be explored separately, but does not seem like a blocker.

  • Externals are curried and use certain internal mechanisms to make them behave as uncurried. Might need special treatment there.

cristianoc avatar Aug 15 '22 07:08 cristianoc

Syntax swap. The function (x, y) => x+y would be uncurried and (. x, y) => x+y curried.

I could see this swap being confusing if a library does not have the config value flipped and the user is using editor go to definition. I often use that for rescript libraries that do not have documentation websites.

Another idea would be to have the printer re-format if the config value is on:

  • (. x, y) => x + y -> (x, y) => x + y
  • (x, y) => x + y -> (? x, y) => x + y

where ? is an arbitrary character to indicate a curried function

illusionalsagacity avatar Aug 15 '22 19:08 illusionalsagacity

when V4 is used, only 1 argument is used anyway so it does not really matter whether one uses the uncurried or curried convention

There is one minor exception, forwardRef. https://github.com/rescript-lang/syntax/blob/cbc5e69b5abab3e383c022b0d0f1b1e901a34644/tests/ppx/react/expected/forwardRef.res.txt#L77

mununki avatar Aug 17 '22 04:08 mununki

True but that is super hacky and I'm sure it can be equally hacked for uncurried.

cristianoc avatar Aug 17 '22 04:08 cristianoc

Another idea would be to have the printer re-format if the config value is on:

Some flags to decide how to migrate a codebase would be useful, in case you want to keep all curried definitions syntax and when they become uncurried and deal with any compiler errors manually.

  • (. x, y) => x + y -> (x, y) => x + y
  • (x, y) => x + y -> (? x, y) => x + y

where ? is an arbitrary character to indicate a curried function

I'm personally against adding even more syntax, it would be nice if it was possible to apply the currying treatment to the normal curried functions like in JS:

  • (x, y) => x + y -> x => y => x + y

joakin avatar Aug 17 '22 10:08 joakin