[NB: I agree with Mark that we should not focus too much on concrete
syntax yet, so I'll also plead for people to avoid quibbling with
details of syntax for the moment.]
Instead of "reveal" I'd prefer block expressions with a fixed (but
optional) tail expression:
BlockExpr ::= "{" (Stmt|Decl)* ("=>" Expr)? "}"
The semantics would be like a block statement, but the result value is
the result of the tail expression, or the undefined value if it's
omitted. The tail expression would be in the same scope chain as the
whole block but would be a mandatory tail call.
This would be used for the body of lambdas, and addresses Waldemar's
concern about unintended leakage. It admits an extremely simple
definition of tail position.
Moreover, it could be part of a let expression form:
Expr ::= ... | "let" LetHead BlockExpr
This single form functions as an expression or a statement, without the
need for two separate forms. (MarkM would probably like for the LetHead
to be optional, which is unproblematic but a detail we can postpone
discussing.)
function foo(x) {
// let expression used as an expression
frob(let (y = x + 1) {
print("hello, world!");
=> baz(y)
});
}
function bar(x) {
// let expression used as a statement
let (y = x + 1) {
f(x); g(y); h(x,y);
}
}
To contrast with "reveal": when there's mutable state I'd prefer it to
be explicit. Anything you might do with reveal you could do with let
expressions using a local variable. For example:
lambda(x){ if (p()) reveal(1); else reveal(2); }
could be expressed as
lambda(x) { let tmp; if (p()) tmp = 1; else tmp = 2; => tmp }
As I say, I prefer not to hide the mutation.
Dave
_______________________________________________
Es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss