JsLIGO: abstractor generate curried definitions
Motivation and Context
We are interested in solving the tension between curried and uncurried syntax.
Description
This MR tries to make JsLIGO abstractor to generate curried definitions, and explore its limitations.
Changes:
- JsLIGO abstractor (passes/04).
- Build here and there to make
compile contract
work with curried contracts. - Contracts, tests, MD files (CameLIGO/PascaLIGO,
Test.originate
~>Test.originate_uncurried
; JsLIGO, uncurrying certain functions).
There's a considerable number of files updated in this MR, however, most of them are related to tests.
These were issues that got solutions implemented:
-
Contracts need to be written as
let main = ([p, s]: [parameter, storage]) => ...
instead oflet main = (p: parameter, s: storage) => ...
.Implemented solutions:
- Make
compile contract
accept such functions and uncurry them, also for views. -> IMPLEMENTED (contracts now can be in curried form when usingcompile contract
) - A modification/currying op. for
Test.originate
. -> IMPLEMENTED (Test.originate
now takes a curried function, there's aTest.originate_uncurried
)
Other possible solutions:
- These problems might be fixed anyway when we have a first-class
contract
.
- Make
Right now, the main remaining drawbacks:
-
No control of partial applications: if
let f = (x: int, y: int) => x + y
, thenf(4)
is a valid application. This could be only checked atAst_typed
(or during10-checking
?), but at this point we are already in an IR where CameLIGO and JsLIGO are unified?Possible solutions: implement extra fields/cases that keep information about "multiparameter" functions? Need to make the typer aware of these?
-
Possible we close more often over
big_map
/etc.? This is already an existing problem in CameLIGO (we've merged an error reporting thing in !2231 (merged) , but still no proper solution?).
Types of changes
-
Bug fix (non-breaking change which fixes an issue) -
New feature (non-breaking change which adds functionality) -
Breaking change (fix or feature that would cause existing functionality to not work as expected) -
Performance improvement (non-breaking change that improves performance) -
None (change with no changelog)
Changelog
Previously, multiparameter functions in JsLIGO were compiled to a function taking a tuple of parameters.
After this MR, multiparameter functions in JsLIGO are compiled to curried functions.
Contracts do still require taking a tuple (parameter, storage)
(as in Michelson). However, LIGO will transform curried contracts to its uncurried form when using compile contract
. The same is true for views, taking still tuples (argument, storage)
, but curried views will be uncurried automatically as well.
New functions are introduced at top-level:
val curry : ('a -> 'b -> 'c) -> ('a * 'b -> 'c)
val uncurry : ('a * 'b -> 'c) -> 'a -> 'b -> 'c
For testing, Test.originate
will take an curried contract of the form parameter -> storage -> operation list * storage
. The old (uncurried) alternative is still available as Test.originate_uncurried
.
Checklist:
-
Changes follow the existing coding style (use dune @fmt
to check). -
Tests for the changes have been added (for bug fixes / feature). -
Documentation has been updated. -
Changelog description has been added (if appropriate). -
Start titles under ## Changelog
section with #### (if appropriate). -
There is no image or uploaded file in changelog -
Examples in changed behaviour have been added to the changelog (for breaking change / feature).