links icon indicating copy to clipboard operation
links copied to clipboard

Braces are suspenders

Open dhil opened this issue 3 years ago • 3 comments

Sam and I have discussed several times that we would like to interpret the expression { M } as fun() { M }, since it is useful syntactic sugar for effectful programming in a call-by-value setting. As it stands right now that is not possible because the expression { M } is interpreted as a block, i.e. a local scope for the evaluation of expression M. For example, today one can write

links> var x = { println("hello"); 40 };
hello
x = 40 : Int
links> x + 2;
42 : Int

Here x gets bound to 40 after the string "hello" has been printed. This usage of block expressions do not appear to be widely used (if used at all) in our examples. Thus we can probably dispense of block expressions of this kind without much fuss.

A slightly more useful usage of block expressions happens primarily in handler code:

links> var x = handle({println("hello"); do Ask}) { case Ask(resume) -> 40 };
hello
x = 40 : Int
links> x + 2;
42 : Int

Here the braces are used to turn the sequence println("hello"); do Ask into a single block expression (the same trick can be used for switch rather than handle). We can possibly eliminate the need for braces here by generalising the grammar for handle, switch, etc.

Implementing the suggested changes paves the way for interpreting { M } as a thunked expression. Obviously, this would be a breaking change, however, I doubt it will affect any live Links code outside of the examples/handlers directory.

dhil avatar Jun 24 '21 22:06 dhil

I forgot to remark that some tests under tests/ make use of { M }.

dhil avatar Jun 24 '21 22:06 dhil

I reckon it may be possible to implement this change under a flag initially by slightly modifying the block production in the rule postfix_expression along the lines of

postfix_expression:
...
| block    { if braces_are_suspenders then Thunk (remove_block_tag $1) else $1 }
...

dhil avatar Jun 24 '21 22:06 dhil

At the risk of falling prey to Wadler's Law, this seems like it would be an incredibly confusing design, since in C/Java/JS family languages unaccompanied braces are almost always just block delimiters. Whatever one thinks of this convention it seems unwise to depart from.

What about the alternative of

lazy {block} --> fun () {block}
force(e) -->  e()

? Why not something like this (possibly with more compact syntax (e.g. {{block}} )?

jamescheney avatar Jun 25 '21 05:06 jamescheney