-
-
Notifications
You must be signed in to change notification settings - Fork 36
Allow to statically analyze messages to detect undefined local variables #403
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
Comments
Thanks @stasm and @mihnita for working on this. I agree that separating arguments from local variables has a number of benefits. I think the best approach to doing this would be to change the sigil for local variables. My next nearest preference would be "special" (I don't mean non-ASCII here) characters just after the I don't agree with the idea of adding a "declaration requirement" for arguments. This would make simple expressions more complex than they need to be:
suddenly has to be:
I think it is important to be as forgiving and simple-to-write as we can in our syntax. We are not a programming, scripting, or even templating language. Note that allowing callers to pass more arguments than the message currently consumes is a feature. I think my proposal would be to change the sigil for local variables. I would be "okay" (not overjoyed, but satisfied) with making local variables immutable if we did this (notice that this would make external arguments immutable too). I'm okay with keeping
Or perhaps:
|
I think we can have these two discussions separately. I propose that we first fix message arguments vs. local variables conflicts; I see it as a more severe issue that I hope we can all rally around. (I still think we may want to allow redeclarations of local variables.) |
@mihnita's original suggestion was to use Also, wrt. the |
How about $$foo for locals? Pretty visible, related but different, easy to type, and doesn't use up another character. |
BTW I agree with "I agree that separating arguments from local variables" |
I think that "declaring" the arguments does not help much ( Without declaration:
It With declaration the above would be reported as a problem at lint time (static), so I add a declaration as proposed:
Now the lint is happy. So the declaration does not solve much. It only tells us that For separation: I'm fine with Also fine to drop the declaration keyword ( Without reading the spec this looks legal, but it is not:
Without reading the spec this looks illegal, and it is:
I still think that we should consider this together with the local variable shadowing. |
I'm not convinced that the core assertion about the current state of affairs holds true:
Generalising a bit, there are two stages at which a message like this is being edited:
In neither of these situations does the message exist in a vacuum. In the first case, the developer is also working with code that formats it; in the second, the source message is also available. Using this contextual information it's possible for static analysis to:
Given this, I would posit that the added value of being able reach a similar conclusion by static analysis without requiring such external context has relatively low value. The preceding discussion here appears to have jumped directly to figuring out solutions for the stated problem, which I would assert isn't significant enough to need fixing. |
It was indeed one of the options that we discussed with @mihnita. I think it makes sense overall, but I have one concern that I'd like to get feedback from others about. Namely, I think some users may read |
We could technically eliminate |
Such warnings require a much more advanced, cross-language static analysis. I expect that not all authoring tools will be able to provide this level of authoring experience. Given how simple our syntax is, I'd like us to strive to make it trivial to analyze and detect as many kinds of errors as possible before resorting to more complex static analysis methods. (Which I also hope will be possible in the future.)
This is a good point to keep in mind, thanks. We can indeed expect most of the translator-oriented use-cases to have access to the original source message. Here again, however, I feel like there's an opportunity to leverage the simplicty of our syntax to allow some use-cases to not even need the source message. For example, linting, pretty-formatting, and certain correctness checks could be performed on translated messages only, without access to the source—simplifying the logic and infrastructure required to run it. |
I agree with this approach in principle, but I find the cost in terms of complexity -- adding a second "variable" prefix -- to be significantly greater than the benefits. |
My thinking evolves as we discuss other topics in parallel. In #310 (comment) I said:
I'd like to expand on this and I choose to do it in this issue because I'm going to argue with myself from a month ago :) The goal of this request is to allow detecting references to undefined local variables. Specifically, under the current syntax, in the following message we have to allow the possibility that
The proposal presented in this issue was to introduce namespacing:
This does indeed allow tooling to detect The real problem is that it's easy to forget to use the local One of the potential solutions discussed in #310 proposes to introduce new syntax for re-annotating variables under the same name, i.e. without introducing a new name into the scope:
This has the benefit of helping ensure that the same annotated It also sidesteps the need to create new local variables in what I think will be the majority of use-cases that we imagined for them. I expect local variables would become rarely used because re-annotations would serve these use-cases well enough. Local variables would still be needed to allow creating new names for new things, and I think we could then drop strict namespacing and rely on conventions:
To summarize:
|
So... much has happened since we last touched this issue, including the creation of I think my question would be: why do we need static analysis of only local variables? What purpose does that serve? Suggest that we close this. @stasm what do you think? |
This is a follow-up to a conversation I had with @mihnita about variable shadowing. See #310 and #402 for context. I think we've been focusing too much on whether local variables should be allowed to shadow other local variables, and that we treated the question of local variables' shadowing of the message argument as derivative. I'm here to argue that we should reverse this and first discuss whether local variables are allowed to shadow message arguments.
Mihai observed that in the current design in which local variables share the namespace with message arguments it's impossible to statically analyze references to local variables. In the following message we can't with certainty detect that
$fooo
is a typo, because it could be a message argument (i.e. a value provided by the developer of the app at the callsite of the MF API).Forbidding such redefinitions is difficult pre-runtime, because the list of message arguments is unknown upfront.
One idea could be to provide a way for message authors to define message argument names in the message itself, for example:
Another solution would be to redefine the syntax for local variables such that it prevents name conflicts with message arguments. This could be done through a new sigil (@mihnita suggested
#foo
) or through an extra requirement to the name, e.g. a dash in the middle of the name:$my-foo
, similar to how HTML allows custom element names.Do others also feel that not being able to do extensive static analysis on variable names is a problem that needs to be fixed?
The text was updated successfully, but these errors were encountered: