block expressions vs. reveal

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

block expressions vs. reveal

Dave Herman-2
[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
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: block expressions vs. reveal

Mark S. Miller-2
On Thu, Jan 8, 2009 at 8:57 AM, Dave Herman <[hidden email]> wrote:
[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)? "}"

In the spririt of postponing concrete syntax issues, I suggest we continue to use placeholder identifiers. In particular, some have advocated "^" for "lambda" and here suggest "=>" for "reveal". To a Scala programmer, "=>" (but infix) is more natural for "lambda". To a Smalltalk programmer, "^" is more natural for "reveal". Since we've got swapped possibilities for the same pair, let's avoid them for now.
 

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.)

Correct. I like all this.
 

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); }

I'm happy to drop my original proposal in favor of yours. I think I like yours better anyway. But for the record, mine was declarative and the above would have been illegal under the "no more than once not nested" restrictions.

 
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.

For this case, that's how you'd have to write it in my proposal as well.


--
   Cheers,
   --MarkM

_______________________________________________
Es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss