dex-lang icon indicating copy to clipboard operation
dex-lang copied to clipboard

Add syntax for "the previous value"

Open axch opened this issue 2 years ago • 6 comments

With @dougalm.

A use-case is when binding a large expression to a name, e.g.

x = case stuff of
  A -> ...
  B -> ...
  C -> ...
  ...
<x only enters scope down here>

Perhaps it would be nicer to write

case stuff of
  A -> ...
  B -> ...
  C -> ...
  ...
x =^

where =^ is a new lexeme meaning "bind to the previous value in the block". There is also precedent in other languages, especially at a REPL, for a magic identifier that means "the previous value".

Reactions? Discuss!

axch avatar Nov 04 '22 20:11 axch

I say let's do it!

dougalm avatar Nov 04 '22 21:11 dougalm

Agreed, we've talked about it a few times already!

apaszke avatar Nov 05 '22 12:11 apaszke

If we're looking to take a leaf from the Common Lisp book, that family of REPLs tends to have a feature that lets you access the kth value back. Are we interested in that, or should we just stick to previous?

Also, this proposal is for a special binder. What do we think about a special expression instead?

x = 2 * ^ + 1

or

x = 2 * it + 1

where ^ or it means "the previous value computed in this block". Pleasant generality or too confusing?

axch avatar Nov 07 '22 16:11 axch

I find it the special expression quite confusing. Plus ^ is potentially useful for exponentiation, so better not to take it up IMO

apaszke avatar Nov 07 '22 17:11 apaszke

Pleasant generality or too confusing?

I was wondering about this too. On the one hand, I could see it being especially useful in a repl setting where you've just evaluated something and you want to do something with the result but you don't want to have to come up with a name for it. But I agree with Adam that the cost isn't worth it. Any syntax of this flavor breaks usually-semantics-preserving transformations, like inserting a pure decl above the line containing ^. But at least with =^ there's not much else going on on that line, so it stands out as a line to be careful with. If we went the it-as-expression route, then it could be buried deep within an expression (including a multi-line one) and it might not be so obvious.

dougalm avatar Nov 07 '22 17:11 dougalm

Here's an implementation plan: we make a new construct at the grouping level, say CDecl = .... | CPrevValue Group, and we desugar CExpr followed by CPrevValue to ULet in AbstractSyntax.hs. At this desugaring stage we throw a syntax error if the decl preceding the CPrevValue is anything other than CExpr.

dougalm avatar Feb 15 '23 18:02 dougalm