-
-
Notifications
You must be signed in to change notification settings - Fork 36
Require variable names to be globally unique #402
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
bc6be29
to
77f2e6c
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I oppose banning redefinitions so don't want to merge this at all. I have a couple of technical comments about that.
Most comments below, however, are with my chair hat on and pertain to formatting and normative language.
spec/formatting.md
Outdated
|
||
It is an error for a local variable definition to | ||
refer to a local variable that's defined after it in the message. | ||
It is an error for the right-hand side of a local variable declaration to |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the right and left hand sides have names in the ABNF. You should use those. In this case it should be something like:
It is an error for the right-hand side of a local variable declaration to | |
The `expression` part of a `declaration` MUST NOT refer to a `variable` that is declared after it in the `message`. |
(Technically we could just say "an expression
MUST NOT refer to a variable
that has not been assigned in a previous declaration
or passed in...")
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1 to Addison's phrasing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I made an attempt to rephrase this.
This would be much easier to specify if, in the grammar, declaration
and operand
were changed:
declaration = let s variable-definition [s] "=" [s] expression
operand = literal / variable-reference
option = name [s] "=" [s] operand
variable-definition = variable
variable-reference = variable
If this change were made, then I'd be able to write something like:
"The variable of any variable-reference must be preceded by a full declaration whose variable-definition has the same variable."
and could avoid referring to the enclosing context of "the operand".
spec/formatting.md
Outdated
It is an error for the right-hand side of a local variable declaration to | ||
refer to a local variable that's declared after it in the message. | ||
|
||
Variable names are required to be globally unique. That is, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use normative language.
Variable names are required to be globally unique. That is, | |
Each `variable` MUST be unique within a message. It is a (what type?) error if a `declaration` uses a name assigned by a previous `declaration`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
in the spirit of the generic comment I left on this PR, I suggest we use "constants" everywhere in this PR (and const
keyword). (of course not for the passed-in ones)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mihnita Note that I'm using production names from the ABNF. If we decided to make the variables
constant then we should change the name of the production at the same time.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rewrote this; for now I'll defer the const
vs. let
question and try to focus on making the language precise.
spec/formatting.md
Outdated
for any local variable declaration of the form `let $v = e`: | ||
* It is an error if `v` is the left-hand side of a local variable declaration | ||
that appears before `let $v = e` in the message. | ||
* It is also an error if `v` is an externally defined variable. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We discussed this briefly in the recent call (talking about changing the sigil for external values). I think this is bad because it is easy for code to suddenly produce an error when the input data (which is dynamic) collides with a declaration.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nitpick: let $v = e
=> let $v = {$e}
(everywhere)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@aphillips I agree that it would be preferable to change the sigil for externally-defined variables. If that change lands before this PR does (i.e. if #403 is resolved), then I'll update this PR to reflect that.
@mihnita I think my rewrites that I just pushed eliminate metavariables anyway, but if I end up re-adding any I'll keep that in mind.
spec/formatting.md
Outdated
|
||
When there are multiple _declarations_ for the same _variable_, | ||
the fallback string is formatted based on the _expression_ of | ||
the first declaration of that _variable_. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what about if var
were externally defined? And why is this a good fallback string?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When there are multiple declarations for the same variable,
That would be an error.
If we disallow redefinition
const $_foo = {|horse|}
const $_foo = {|dog|} // ERROR
And if we also force names starting with _
on local consts, and disallow names starting with _
in passed variables, then multiple declarations are errors.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what about if
var
were externally defined?
Rewrote to include that case as well.
And why is this a good fallback string?
See https://github.com/unicode-org/message-format-wg/blob/main/spec/formatting.md?plain=1#L208
I wanted to be as consistent as possible with the existing spec, which says that fallback values should be formatted based on the RHS of a declaration. I thought the most consistent thing if there are multiple declarations is to pick one of them. Do you have another suggestion?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When there are multiple declarations for the same variable,
That would be an error.
@mihnita I'm not sure what you mean -- doesn't there have to be a fallback string to replace any expression that resolves to an error?
I think it would be good to use I also had a meeting with Stas last week, and he would really like to see something that mitigates the shadowing between these "local variables" (consts :-) and the "externally defined variables" (edv :-) or "arguments" I proposed another sigil, but he would rather avoid that, and proposed either
One of the added benefits (in addition to shadowing) is that we can do better static checking. I am fine with |
A small correction:
I suggested the HTML approach of requiring a dash I don't think this is the right place to discuss this, however. I'll file a new issue. |
> let $var = {|horse|} | ||
> {The value is {$var}.} | ||
> ``` | ||
|
||
- **Unknown Function errors** occur when an _expression_ includes |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nitpick: would be good to have a code example with a function here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you mean a function in the declaration of $var
, or a function in the expression that uses $var
, or both?
Thank you for the correction. (Personally I am not a fan of |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think disallowing value re-definitions is a good idea.
For an alternative approach, could we consider changing the let
keyword to be set
, and for references to declarations to be changed to definitions or assignments? This might make it easier to consider them as assignments rather than initializations.
I do not think using const
would be a good idea, esp. as many such "constants" would be variable depending on the formatting call arguments.
77f2e6c
to
8c2aecb
Compare
0e19f21
to
05ba489
Compare
0f55fa6
to
8c8acad
Compare
Co-authored-by: Addison Phillips <addisonI18N@gmail.com>
…dd an example of that
I would be fine with that change, but perhaps if we get to the point where everyone is OK with this PR as-is, then renaming |
I filed a new issue for this: #413 |
As discussed during the last MFWG call, changes to how we handle variable names probably needs a design document. |
I think this pull request is made obsolete by 5065a51 . |
See #310