Skip to content
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

Add an expression-local declaration (let-expression). #1052

Open
lrhn opened this issue Dec 16, 2015 · 3 comments
Open

Add an expression-local declaration (let-expression). #1052

lrhn opened this issue Dec 16, 2015 · 3 comments
Labels
feature Proposed language feature that solves one or more problems

Comments

@lrhn
Copy link
Member

lrhn commented Dec 16, 2015

There is no way to locally declare a variable in an expression.
In statements, a single statement can be replaced by a block statement that contains local variable declarations, but there is no way to do the same thing in an expression.

Example code (using "let/in" as syntax):

let var tmp = new Something() in new Other(tmp, tmp)

This can be useful in initializer lists where you can need to create a new object and use it in more than one place.

The current alternative, as used by the specification to explain desugaring of some constructs, uses a function literal to bind the new variable, like ((tmp) => new Other (tmp, tmp))(new Something()).
This has the disadvantage of not working well with async operations (if new Other(..) was more complex and contained an await, it would not be a correct rewrite).

The new syntax could be used by the specification to define desugarings, and can be used to make some expressions more readable by reducing the scope of temporary variables.

Alternatively, now that we have definite assignment analysis, we could allow var x = e as an expression.
It would effectively introduce x into the current scope, but the variable cannot be accessed until after the declaration point, even if that is in the middle of an expression. It'll b definitely unassigned before and definitely assigned after, which is something we can already handle.

Then the above example becomes Other(var tmp = Something(), tmp).
It will probably have to use the var or final marker, using a type can potentially be hard to parse: f(x + int y = 2, 2).
The precedence of a declaration would be very low, so the only place it won't need to be parenthesized is if it's at the end of an expression, or it's a collection element or parameter list entry (comma delimited).

@eernstg
Copy link
Member

eernstg commented Dec 16, 2015

Is there a desugaring based specification for this construct? It might correspond to consistently renaming the declared variable to a fresh name, replacing the let.. by its body, and adding a declaration plus initialization of a local variable with the fresh name in the "nearest available location" --- or maybe that doesn't work. But surely it is not much of an improvement if it is rewritten to a literal function. ;)

@lrhn
Copy link
Member Author

lrhn commented Dec 16, 2015

The reason I considered the feature interesting is that there isn't any easy rewrite.
One rewrite of let var x = e1 in e2 could be helper($tmp = e1, e2[$tmp/x]) where helper is helper(x, y) => y; (a sequence operation, basically) and $tmp is a fresh variable declared "somewhere in the surrounding" (basically, just before the current statement).

I'm not absolutely sure you can always insert a variable declaration at the same level as the expression, but it might be possible. (Loop conditions spring to mind, there should be a new variable for each evaluation of the condition, but putting the declaration just before the loop will not do that - and the variable may be captured by a closure).
And initializer lists and variable initializer expressions are only expressions.

@askeksa-google
Copy link

Could still be relevant.

@lrhn lrhn transferred this issue from dart-lang/sdk Jun 29, 2020
@lrhn lrhn added the feature Proposed language feature that solves one or more problems label Jun 29, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature Proposed language feature that solves one or more problems
Projects
None yet
Development

No branches or pull requests

3 participants