Thoughts (mine, yours) on the reference's grammar?

The reference does not distinguish in the grammar whether an expression is value or place; take match for example where scrutinee is just an Expression, but actually it's always a place expression so a value is implicitly converted (assigned to a temporary variable).

I understand that —since value<=>place are converted by rust, users can ignore it. However, the reader eventually finds out that "actually it expects place" or ".... expects value". And this is quite confusing (to me anyways!)

Maybe there is a better place to read the grammar? Though wouldn't it be nice to have it distinguish Place vs Value Expr in there?


I'm aware of the page place and value exprs, which doesn't do the best job although I get this is quite hard to explain briefly and correctly.

For example, this paragraph about Temporaries feels hard, mainly because neither place nor value appears explicitly, i.e the grammar does not show it. (this applies to match, for example).

I did notice that a grammar was moved to reference, and the working group is working in a spec GitHub - rust-lang/spec: The Rust specification, which seems good news.

Last commit was last year though, and readme sort of points one back to the reference:

The t-spec team, in consultation with interested parties from the Rust Project, made the decision on a go-forward plan that makes the Rust Reference the source of truth and the specification will be based on that content.

So what I said above applies to reference's grammar imho.

Regarding the general topic:

Note that there hasn't been a formal grammar for approximately ever. A prior effort didn't go anywhere. Hopefully the that changes with the specification work. The reference has been slowly improving in recent months, I think. You could look for T-spec and A-grammar issues/PRs in the repo to get a feel for recent activity.


As for distinguishing places from values in the grammar, I don't think that's completely possible.

First of all, there are place and value expressions, and there are place and value contexts. The match scrutinee is a place context. The code you write there may be a place expression or a value expression.

// Place expression in place context
match self { ... }

// Value expression in place context: a temporary holds the reference
match &self { ... }

Second of all, whether or not an expression is a place expression or value expression requires more context than just grammar.

// Are these place expressions or value expressions (in place context)?
match something { ... }
match SOMETHING { ... }

fn case_1() {
    let something = 0;
    static SOMETHING: usize = 0;
    // Place expressions
    match something { ... }
    match SOMETHING { ... }
}

fn case_2() {
    fn something() {}
    const SOMETHING: usize = 0;
    // Value expressions
    match something { ... }
    match SOMETHING { ... }
}
3 Likes

Yes, so the reference is where the actual work for the grammar and spec happens now.

I think it is possible, unless I misinterpreted. Also, I understand expression contexts as:

  • For place expression context: if we pass a place we are all good, if we pass a value it is either converted (as in the match case) or rejected by the compiler.
  • A similar situation applies to value expression context.

Why not to simply show how and when those conversions happen, and use PlaceExpr and ValueExpr in the grammar, throwing away this extra definition of contexts.

I agree. Ignoring the contexts we would say: match expressions accept a place-expression only —otherwise a temporary variable is created under the hood, which confirms this.

The two value expressions and will be converted to place expressions under the hood; the first two are place expressions, they are well known to be and won't be converted. I don't think anything is missing.

I haven't thought deeply about implicit borrow contexts, so it may or may not be the case that all place-or-value context distinctions can be described at the grammar level today. Though I guess there could be a WillFigureOutLaterExpr too if needed.

Why isn't there? At a guess, because these distinctions are made when lowering to some intermediate representation, after parsing.

One part that's missing is that you can't know if a path is a value expression or place expression without resolving it -- a task outside of the grammar / parsing.

2 Likes

One way to look at this is that place expressions vs. value expressions are a sort of type system on expressions. It's possible to incorporate this typing into the grammar (just as, for example, we could make if 123 {} a syntax error and not just a type error), but we usually keep types as a separate layer instead.

2 Likes

If I get your point correctly it, I agree. In my view --but this somewhat new to me, it would make the language easier to understand at some conceptual level.

So what you said would fit the phrase "place to value" coercion (and the inverse).

But I would insist that this needs to be more explicit or clear as in being part of the grammar.

Maybe I dont see something here.

I can kind of see both sides of this. You want to look at the gammar and see what types of expressions are accepted. From a compiler developer point of view that is not part of the grammar (lexer + parser) but of a later compiler stage such as type checking. Types like i32 vs str are not in the grammar either.

Now, as I user of Rust I don't personally see much use in looking at formal grammars. That is more relevant to implementing and figuring out if something is a bug. Just like I don't think about the formal grammar rules when speaking or writing natural languages unless I'm studying them.[1]

So I don't really see why you are so bullish about this. But people learn differently, so, sure.


  1. Even while learning my third natural language I did not find formal grammars particularly useful: informal rules and examples are better. For my first and second language it has been so long that I don't really remember the process of learning. But eventually you just get a feel for what is correct. ↩︎

So I don't really see why you are so bullish about this. But people learn differently, so, sure.

Titling the post "thoughts", providing sources, and saying "if I get your point" etc. Is not being bullish.

I won't engage with someone calling me things from the start, as that is precisely to be what you denounce, and does not make for good interactions.

(Sorry to butt in here, but to clear up a potential language misunderstanding: “To be bullish on/about something” is an English expression meaning “to think that something will have positive results” – it has no relation to “bullying” or “bull-headed” or any of the other number of negative bull-related terms I’m suddenly realizing we have! It comes from stock-market terminology, where a “bull market” is one where things are going up and a “bear market” is one where things are going down.)

1 Like

That is precisely the meaning at with I responded to.

(Okay! As long as everyone’s understanding what’s going on I have nothing else to add)

It would also make it harder to understand on a different level. When you make difference in grammar that depends on the things that are not purely syntactic you are creating a nightmare. When you ask question is this sequence of characters a valid C++ program and the answer is it depends on whether you compile it for ARM or x86-64… I'm not sure this makes it easier to understand anything.

1 Like

I often see the sentiment among implementations that you generally want implementations and a specification to be as close as you can, enough to be about to label functions and statements with a clause from the specification to compare.

If no implementation would be making a distinction between these expressions at the grammar level I don't see why the specification should either.

One nice property of grammars in the past was that they were one of the few parts of a specification that were actually formally defined, at least to some level. If you're following the more recent approach that the entire specification is defined in a formally defined language, I think there's really no good reason to overload the grammar that much.