Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This PR makes the operators
|>
and<|
into primitives recognized by the parser and desugarer, which are interpreted as applications, just with different associativity and precedence.This is good (IMO) since:
1- We get "effect polymorphism" for free: these are just applications, while if we define the operators must choose an effect
2- Base files in the compiler get a bit of cleanup, since they had these definitions
3- The generated OCaml looks simpler
4- SMT queries may be simpler
5- One does not inadvertedly lose equations if using an effectful
<|
or|>
, when both the function and arguments are total. This actually led to a regression in everparse, where the snippetwas now failing, I suppose since
print_binders
andprint_args
now have SMT definitions and that was too much (but I didn't dig deep into it..). Annotating them asML string
fixes the issue here. I'd argue this is generally a good thing, though..?Disadvantages:
1- The operators cannot be redefined (hence the patch in DoublyLinkedList)
2- The use of the operators is currently lost after desugaring, so it won't be printed by
--dump_module
(but--print
works). This could be fixed by keeping some meta_desugared info.(paragraph edited, got confused)
Note that F# has these operators too, where both of them associate to left. So
|>
behaves the same, but one can writef <| X <| Y <| Z
to getf (X) (Y) (Z)
. F* also had this behavior, so we are changing that by changing the associativity of<|
, but we think the symmetry is nicer. A pipeline of passingx
though functionsf
,g
andh
in that order can then be writtenx |> f |> g |> h
orh <| g <| f <| x
.In the parser, I made
<|
have more precedence that|>
, see tests here. This is totally arbitrary, not sure if it's the right thing.OCaml did something similar, also giving
|>
and@@
(our<|
) special handling as an application: see ocaml/ocaml#10081.As a follow up I want to change the precedence rules to allow snippets like (slightly edited):
be written in this form:
which is a common (I think) style in OCaml. This requires some deeper parser surgery, so I'm not bundling it here.