Conversation
This document introduces the `const` keyword for local variable bindings, explaining its syntax, semantics, and potential drawbacks.
|
The motivation is very weak and the drawbacks of breaking backwards compatibility are... bad. The motivation boils down into preventing accidental reassignment, and enabling unspecified implementation optimizations. Accidental reassignments by and large just don't happen. As for the unspecified optimizations, luau today knows if a variable is constant or not, and if it is, it applies optimizations. Checking if a binding is ever reassigned is trivial. I assume the suggestion of breaking backwards compatibility comes with the idea of a tool to allow users to migrate code. This is bad because such a tool is infeasible for the largest user of the language, roblox. The migration tool cannot be run at user's own leisure because roblox forces the latest version of luau, and the tool cannot be run automatically effectively because many users do not use roblox as a source of truth for their code. All in all, this feature opens too many difficult questions for the lack of utility it provides. |
Expand on the motivation for introducing the `const` keyword, emphasizing its role in ensuring stability for exported variables and preventing accidental reassignment. Provide examples illustrating the implications of mutable bindings in module exports.
Clarify the behavior and implications of the 'const' keyword in local declarations, including its contextual usage and potential drawbacks.
I've added more details about this to the RFC.
Instead of reserving I've covered this in the RFC also. |
|
|
||
| ```luau | ||
| const x = 1 | ||
| x = 2 -- error |
There was a problem hiding this comment.
What kind of error? Static(Parsing Error) or dynamic?
Difference is more obvious inside a function definition.
const a = 42
function foo() -- 1
a = 43
end
foo() -- 2
Should we see an error at parsing of 1 or at the call of 2?
JavaScript picks option 2, but honestly I'm not aware of advantage of it. So I would prefer option 1.
There was a problem hiding this comment.
I think it can be implemented as a parsing error but we may want a runtime error as a backstop for cases like loadstring. I would expect the error to be on the line of the actual assignment, in this case a = 43.
There was a problem hiding this comment.
As an aside JavaScript likely picks (2) because it's the line that leads to a being mutated and without it the value remains constant. For sanity, I think we should stick to erroring on a = 43 even if the code is unreachable.
There was a problem hiding this comment.
JS goes crazier here:
const a = 42;
function bar(overrides) {
with (overrides) {
let foo = function() {
console.log(a);
a = 43;
console.log(a);
}
foo();
}
}
bar({ a: 50 }); // prints 50, 43
bar({ b: 50 }); // prints 42 and throws TypeError: Assignment to constant variable.
docs/const-keyword.md
Outdated
There was a problem hiding this comment.
As I mentioned above it is not an issue right now.
But it can be in conflict with developing proposals, like destructive assignment.
Theoretically you can have something like that in you code now:
const {a, b}
and it sould be treated as a call to const with a single param.
Assuming destructive assignment will look like
const {a, b} = x
It can be an issue
There was a problem hiding this comment.
As const variables must always be initialized const {a, b} would be invalid (and therefore treated as a function call) while const {a, b} = x remains unambiguous as this is invalid syntax today. The one downside I see if that this could become a gotcha, so we might want to consider a linter warning for const {a, b}.
There was a problem hiding this comment.
@bradsharp While const {a, b] = x is not ambiguous, it is still not reasonably parsable.
There was a problem hiding this comment.
It almost makes one want for a "Do not add destructuring syntax" RFC
| const x: number = 5 | ||
| const t: { a: number } = { a = 1 } | ||
| ``` | ||
| Multi-assignment is also supported: |
There was a problem hiding this comment.
Probably worth mentioning vararg multi assignment explicitly.
it should be fine from runtime point of view to have something like
function f() return 1 end
const a, b = f()
Because f can return multiple values in last position(same with ...). In that case b should be initialized with nil. But typechecker probably should complain here.
SPY
left a comment
There was a problem hiding this comment.
I think RFC in a good shape and can be merged.
|
There's 9 thumbs down. Shouldn't we wait for more community input? A major problem with this RFC is that it's primarily motivated on fixing a hole caused by the current semantics of the export-by-value RFC. This motivation is entirely speculative and different semantics for export-by-value can and should be chosen to solve this instead. Secondary motivation for safeguarding reassignment is also rather unpopular. Anecdotal experience from myself and others says that accidental local reassignments rarely happen, and more often we want cross-module immutability, which is taken care of with |
|
I'm more concerned on the future compatibility concerns with destructuring syntax, as in, this RFC doesn't leave a path open for destructuring syntax. |
This document introduces the
constkeyword for local variable bindings, explaining its syntax, semantics, and potential drawbacks.Rendered