Skip to content

Commit 4e9c818

Browse files
authored
Syntax: process uncurried function declarations explicitly in the parser/printer (rescript-lang#5794)
* process uncurried function declarations explicitly in the parser/printer * Update CHANGELOG.md * Remove example that is not idempotent This is not idempotent: let c2 = (. x) => y => x+y * Interpred arity of uncurried explicitly. Interpret the arity of uncurried functions explicitly so this is a unary function: ``` (. x) => y => x+y ``` The parser adds braces to the body to make this explicit. This is a breaking change. And solves the lack of idempotency in rescript-lang#5794 * Update CHANGELOG.md * Interpred arity of uncurried explicitly. Interpret the arity of uncurried functions explicitly so this is a unary function: ``` (. x) => y => x+y ``` The parser adds braces to the body to make this explicit. This is a breaking change. And solves the lack of idempotency in rescript-lang#5794 * Update CHANGELOG.md * snap * Added analogous tests for types. * Update CHANGELOG.md
1 parent 0f3c02b commit 4e9c818

File tree

14 files changed

+647
-496
lines changed

14 files changed

+647
-496
lines changed

CHANGELOG.md

+5
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,15 @@
2020
- Remove obsolete built-in project templates and the "rescript init" functionality. This will be replaced by the create-rescript-app project that is maintained separately.
2121
- Parse the attributes of labelled argument to the pattern attributes of argument instead of function.
2222
- Made pinned dependencies transitive: if *a* is a pinned dependency of *b* and *b* is a pinned dependency of *c*, then *a* is implicitly a pinned dependency of *c*. This change is only breaking if your build process assumes non-transitivity.
23+
- Curried after uncurried is not fused anymore: `(. x) => y => 3` is not equivalent to `(. x, y) => 3` anymore. It's instead equivalent to `(. x) => { y => 3 }`.
24+
Also, `(. int) => string => bool` is not equivalen to `(. int, string) => bool` anymore.
25+
These are only breaking changes for unformatted code.
2326

2427
#### :nail_care: Polish
2528

2629
- Syntax: process uncurried types explicitly in the parser/printer https://github.com/rescript-lang/rescript-compiler/pull/5784
30+
- Syntax: process uncurried function declarations explicitly in the parser/printer https://github.com/rescript-lang/rescript-compiler/pull/5794
31+
2732

2833
# 10.1.0-rc.5
2934

lib/4.06.1/unstable/js_compiler.ml

+87-88
Original file line numberDiff line numberDiff line change
@@ -55712,6 +55712,79 @@ and printIfChain ~customLayout pexp_attributes ifs elseExpr cmtTbl =
5571255712
Doc.concat [printAttributes ~customLayout attrs cmtTbl; ifDocs; elseDoc]
5571355713

5571455714
and printExpression ~customLayout (e : Parsetree.expression) cmtTbl =
55715+
let printArrow ~isUncurried e =
55716+
let attrsOnArrow, parameters, returnExpr = ParsetreeViewer.funExpr e in
55717+
let ParsetreeViewer.{async; uncurried; attributes = attrs} =
55718+
ParsetreeViewer.processFunctionAttributes attrsOnArrow
55719+
in
55720+
let uncurried = uncurried || isUncurried in
55721+
let returnExpr, typConstraint =
55722+
match returnExpr.pexp_desc with
55723+
| Pexp_constraint (expr, typ) ->
55724+
( {
55725+
expr with
55726+
pexp_attributes =
55727+
List.concat [expr.pexp_attributes; returnExpr.pexp_attributes];
55728+
},
55729+
Some typ )
55730+
| _ -> (returnExpr, None)
55731+
in
55732+
let hasConstraint =
55733+
match typConstraint with
55734+
| Some _ -> true
55735+
| None -> false
55736+
in
55737+
let parametersDoc =
55738+
printExprFunParameters ~customLayout ~inCallback:NoCallback ~uncurried
55739+
~async ~hasConstraint parameters cmtTbl
55740+
in
55741+
let returnExprDoc =
55742+
let optBraces, _ = ParsetreeViewer.processBracesAttr returnExpr in
55743+
let shouldInline =
55744+
match (returnExpr.pexp_desc, optBraces) with
55745+
| _, Some _ -> true
55746+
| ( ( Pexp_array _ | Pexp_tuple _
55747+
| Pexp_construct (_, Some _)
55748+
| Pexp_record _ ),
55749+
_ ) ->
55750+
true
55751+
| _ -> false
55752+
in
55753+
let shouldIndent =
55754+
match returnExpr.pexp_desc with
55755+
| Pexp_sequence _ | Pexp_let _ | Pexp_letmodule _ | Pexp_letexception _
55756+
| Pexp_open _ ->
55757+
false
55758+
| _ -> true
55759+
in
55760+
let returnDoc =
55761+
let doc = printExpressionWithComments ~customLayout returnExpr cmtTbl in
55762+
match Parens.expr returnExpr with
55763+
| Parens.Parenthesized -> addParens doc
55764+
| Braced braces -> printBraces doc returnExpr braces
55765+
| Nothing -> doc
55766+
in
55767+
if shouldInline then Doc.concat [Doc.space; returnDoc]
55768+
else
55769+
Doc.group
55770+
(if shouldIndent then Doc.indent (Doc.concat [Doc.line; returnDoc])
55771+
else Doc.concat [Doc.space; returnDoc])
55772+
in
55773+
let typConstraintDoc =
55774+
match typConstraint with
55775+
| Some typ ->
55776+
let typDoc =
55777+
let doc = printTypExpr ~customLayout typ cmtTbl in
55778+
if Parens.arrowReturnTypExpr typ then addParens doc else doc
55779+
in
55780+
Doc.concat [Doc.text ": "; typDoc]
55781+
| _ -> Doc.nil
55782+
in
55783+
let attrs = printAttributes ~customLayout attrs cmtTbl in
55784+
Doc.group
55785+
(Doc.concat
55786+
[attrs; parametersDoc; typConstraintDoc; Doc.text " =>"; returnExprDoc])
55787+
in
5571555788
let printedExpression =
5571655789
match e.pexp_desc with
5571755790
| Parsetree.Pexp_constant c ->
@@ -55967,6 +56040,20 @@ and printExpression ~customLayout (e : Parsetree.expression) cmtTbl =
5596756040
]
5596856041
in
5596956042
Doc.group (Doc.concat [variantName; args])
56043+
| Pexp_fun
56044+
( Nolabel,
56045+
None,
56046+
{ppat_desc = Ppat_var {txt = "__x"}},
56047+
{pexp_desc = Pexp_apply _} ) ->
56048+
(* (__x) => f(a, __x, c) -----> f(a, _, c) *)
56049+
printExpressionWithComments ~customLayout
56050+
(ParsetreeViewer.rewriteUnderscoreApply e)
56051+
cmtTbl
56052+
| Pexp_fun _ | Pexp_newtype _ -> printArrow ~isUncurried:false e
56053+
| Pexp_record
56054+
([({txt = Ldot (Ldot (Lident "Js", "Fn"), name)}, funExpr)], None)
56055+
when String.length name >= 1 && name.[0] = 'I' ->
56056+
printArrow ~isUncurried:true funExpr
5597056057
| Pexp_record (rows, spreadExpr) ->
5597156058
if rows = [] then
5597256059
Doc.concat
@@ -56255,94 +56342,6 @@ and printExpression ~customLayout (e : Parsetree.expression) cmtTbl =
5625556342
| Pexp_sequence _ ->
5625656343
printExpressionBlock ~customLayout ~braces:true e cmtTbl
5625756344
| Pexp_let _ -> printExpressionBlock ~customLayout ~braces:true e cmtTbl
56258-
| Pexp_fun
56259-
( Nolabel,
56260-
None,
56261-
{ppat_desc = Ppat_var {txt = "__x"}},
56262-
{pexp_desc = Pexp_apply _} ) ->
56263-
(* (__x) => f(a, __x, c) -----> f(a, _, c) *)
56264-
printExpressionWithComments ~customLayout
56265-
(ParsetreeViewer.rewriteUnderscoreApply e)
56266-
cmtTbl
56267-
| Pexp_fun _ | Pexp_newtype _ ->
56268-
let attrsOnArrow, parameters, returnExpr = ParsetreeViewer.funExpr e in
56269-
let ParsetreeViewer.{async; uncurried; attributes = attrs} =
56270-
ParsetreeViewer.processFunctionAttributes attrsOnArrow
56271-
in
56272-
let returnExpr, typConstraint =
56273-
match returnExpr.pexp_desc with
56274-
| Pexp_constraint (expr, typ) ->
56275-
( {
56276-
expr with
56277-
pexp_attributes =
56278-
List.concat [expr.pexp_attributes; returnExpr.pexp_attributes];
56279-
},
56280-
Some typ )
56281-
| _ -> (returnExpr, None)
56282-
in
56283-
let hasConstraint =
56284-
match typConstraint with
56285-
| Some _ -> true
56286-
| None -> false
56287-
in
56288-
let parametersDoc =
56289-
printExprFunParameters ~customLayout ~inCallback:NoCallback ~uncurried
56290-
~async ~hasConstraint parameters cmtTbl
56291-
in
56292-
let returnExprDoc =
56293-
let optBraces, _ = ParsetreeViewer.processBracesAttr returnExpr in
56294-
let shouldInline =
56295-
match (returnExpr.pexp_desc, optBraces) with
56296-
| _, Some _ -> true
56297-
| ( ( Pexp_array _ | Pexp_tuple _
56298-
| Pexp_construct (_, Some _)
56299-
| Pexp_record _ ),
56300-
_ ) ->
56301-
true
56302-
| _ -> false
56303-
in
56304-
let shouldIndent =
56305-
match returnExpr.pexp_desc with
56306-
| Pexp_sequence _ | Pexp_let _ | Pexp_letmodule _
56307-
| Pexp_letexception _ | Pexp_open _ ->
56308-
false
56309-
| _ -> true
56310-
in
56311-
let returnDoc =
56312-
let doc =
56313-
printExpressionWithComments ~customLayout returnExpr cmtTbl
56314-
in
56315-
match Parens.expr returnExpr with
56316-
| Parens.Parenthesized -> addParens doc
56317-
| Braced braces -> printBraces doc returnExpr braces
56318-
| Nothing -> doc
56319-
in
56320-
if shouldInline then Doc.concat [Doc.space; returnDoc]
56321-
else
56322-
Doc.group
56323-
(if shouldIndent then Doc.indent (Doc.concat [Doc.line; returnDoc])
56324-
else Doc.concat [Doc.space; returnDoc])
56325-
in
56326-
let typConstraintDoc =
56327-
match typConstraint with
56328-
| Some typ ->
56329-
let typDoc =
56330-
let doc = printTypExpr ~customLayout typ cmtTbl in
56331-
if Parens.arrowReturnTypExpr typ then addParens doc else doc
56332-
in
56333-
Doc.concat [Doc.text ": "; typDoc]
56334-
| _ -> Doc.nil
56335-
in
56336-
let attrs = printAttributes ~customLayout attrs cmtTbl in
56337-
Doc.group
56338-
(Doc.concat
56339-
[
56340-
attrs;
56341-
parametersDoc;
56342-
typConstraintDoc;
56343-
Doc.text " =>";
56344-
returnExprDoc;
56345-
])
5634656345
| Pexp_try (expr, cases) ->
5634756346
let exprDoc =
5634856347
let doc = printExpressionWithComments ~customLayout expr cmtTbl in

0 commit comments

Comments
 (0)