On 04/25/2013 11:46 AM, John Clements wrote:
Huh? Looks like my first message didn't go through. Perhaps I'm being 
moderated, and I just didn't know it?

Apologies if this appears twice.

Per our meeting today, I'm sending this out to see whether we want to make a 
change.

Currently, our grammar parses

if (true) {3} else {4}  + 10

As a statement followed by a (non-parseable) expression. This is to prevent 
things like

if (true) {3} else {4}
|a| {foo()}

… from being parsed as two uses of the "or" operator, for instance.  The basic 
restriction is that when something that could be a statement occurs in a position where 
it could be a statement, then it should be parsed as a statement and not as an expression.

Keep in mind that you can always force a statement-y thing to be allowable in 
any position by using parens. So, for instance,

(if (true) {3} else {4}) + 10

is a perfectly legitimate expression.

This restriction is the cause of no small ugliness in the grammar.

Simplifying it might concievably avoid certain errors. However, it would 
probably make some people unhappy.

One way to fix it would be simply to lift the restriction entirely. In this 
case,

if (true) {3} else {4}
|a| {foo()}

… would be parsed as

((if (true) {3} else {4}
  |a)
     | {foo()})

… which some people might be surprised by.

Another solution would be to *always* require semicolons, even after blocks. 
This would probably make lots of people immediately unhappy.

Another solution, the "shift the burden to those kooky functional folks", would 
be to say that using a statement as an expression *only* works when it's enclosed in 
parens. This would simplify things a lot. This would not change the behavior of the first 
example at all, but it would for instance rule out
14 + if (true) {3} else {4}
… requiring instead
14 + (if (true) {3} else {4})
But indeed, I think I would probably opt for the latter one as more readable 
anyway.
Another example that would have to change would be changing something like
for foo.each |a| {f(a)}.bar()
into
(for foo.each |a| {f(a)}).bar()
But honestly, that one makes me happier as well.

The more I think about this alternative, the more I like it.

Either way, this ship's gangplank is up and it's straining at its hawsers.  We 
should probably make a decision on this now-ish.


How does this rule impact expressions that occur in the 'tail' expression of a block?

fn foo() -> bool {
    if true { false } else { true }
}

This is a very common place where block expressions are used. Will the parser still know this is an expression?

_______________________________________________
Rust-dev mailing list
[email protected]
https://mail.mozilla.org/listinfo/rust-dev

Reply via email to