From 74a85c674dd660dcea81b333149467ffa3b68bb9 Mon Sep 17 00:00:00 2001 From: Dev_Ege <98964310+EgeDev003@users.noreply.github.com> Date: Tue, 7 Apr 2026 00:27:24 +0300 Subject: [PATCH 1/3] Create const-binding-forin-loops-and-function-parameters.md const keyword update for bindings --- ...ing-forin-loops-and-function-parameters.md | 59 +++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 docs/const-binding-forin-loops-and-function-parameters.md diff --git a/docs/const-binding-forin-loops-and-function-parameters.md b/docs/const-binding-forin-loops-and-function-parameters.md new file mode 100644 index 00000000..8044531e --- /dev/null +++ b/docs/const-binding-forin-loops-and-function-parameters.md @@ -0,0 +1,59 @@ +# `const` bindings in for-in loops and function parameters + +## Summary + +Extend the existing `const` keyword to support per-binding const declarations in generic `for-in` loops and `function parameters` + +## Motivation + +Luau already supports `const` for local bindings + +```luau +const x = 10 +const function foo() end +``` + +However, there is no way to mark loop variables or function parameters as immutable. This leads to accidental reassignment bugs, especially in generic for loops where key/value pairs should remain unchanged, and in functions where parameters should be treated as read-only + +## Design + +### New syntax + +```luau +-- Generic for-in: per-binding const +for const k, const v in table do end -- both const +for const k, v in table do end -- only k const +for k, const v in table do end -- only v const +``` +```luau + -- Function parameters +function foo(const x, const y) end -- both const +function bar(const x, y) end -- only x const +function baz(const, const x) end -- const is not constant variable name --overwrite const keyword, x const +``` + +## Backward Compatibility + +```luau + for const in x do -- const is not constant variable name --overwrite const keyword -- If you used it this way before, there is no change. + end + + for const const in x do -- const is constant variable name --overwrite const keyword + end + + function foo(const) do -- const is not constant variable name --overwrite const keyword -- If you used it this way before, there is no change. + end + + function foo(const const) do -- const is constant variable name --overwrite const keyword + end +``` + +Rule: `const` is treated as a keyword **only when** the next token is a `Name` (and, in the `for` statement first-binding position, the token after that is not `=`)) + +## Drawbacks + +- **Unusual syntax**: Normally, loops and parameter variables follow the pattern `name`, `name`, etc., but now you can add `const` before them. + +## Alternatives + +- **Do nothing**: Rely on linter rules or code conventions to catch accidental reassignment. This avoids parser complexity but provides no language-level guarantee. From cae2ac9c16bf1012d7712ae2b429f52eb52d04bc Mon Sep 17 00:00:00 2001 From: Dev_Ege <98964310+EgeDev003@users.noreply.github.com> Date: Tue, 7 Apr 2026 00:41:06 +0300 Subject: [PATCH 2/3] Update const-binding-forin-loops-and-function-parameters.md text fixed --- ...inding-forin-loops-and-function-parameters.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/docs/const-binding-forin-loops-and-function-parameters.md b/docs/const-binding-forin-loops-and-function-parameters.md index 8044531e..ab5ae4bc 100644 --- a/docs/const-binding-forin-loops-and-function-parameters.md +++ b/docs/const-binding-forin-loops-and-function-parameters.md @@ -35,17 +35,17 @@ function baz(const, const x) end -- const is not constant variable name -- ## Backward Compatibility ```luau - for const in x do -- const is not constant variable name --overwrite const keyword -- If you used it this way before, there is no change. - end +for const in x do -- const is not constant variable name --overwrite const keyword -- If you used it this way before, there is no change. +end - for const const in x do -- const is constant variable name --overwrite const keyword - end +for const const in x do -- const is constant variable name --overwrite const keyword +end - function foo(const) do -- const is not constant variable name --overwrite const keyword -- If you used it this way before, there is no change. - end +function foo(const) do -- const is not constant variable name --overwrite const keyword -- If you used it this way before, there is no change. +end - function foo(const const) do -- const is constant variable name --overwrite const keyword - end +function foo(const const) do -- const is constant variable name --overwrite const keyword +end ``` Rule: `const` is treated as a keyword **only when** the next token is a `Name` (and, in the `for` statement first-binding position, the token after that is not `=`)) From 8b50e028b18f697f9d15a1f0e4217238a4153e07 Mon Sep 17 00:00:00 2001 From: Dev_Ege <98964310+EgeDev003@users.noreply.github.com> Date: Tue, 7 Apr 2026 18:25:15 +0300 Subject: [PATCH 3/3] Adding numeric loops --- ...ding-for-loops-and-function-parameters.md} | 32 +++++++++++++------ 1 file changed, 23 insertions(+), 9 deletions(-) rename docs/{const-binding-forin-loops-and-function-parameters.md => const-binding-for-loops-and-function-parameters.md} (66%) diff --git a/docs/const-binding-forin-loops-and-function-parameters.md b/docs/const-binding-for-loops-and-function-parameters.md similarity index 66% rename from docs/const-binding-forin-loops-and-function-parameters.md rename to docs/const-binding-for-loops-and-function-parameters.md index ab5ae4bc..95dcf02e 100644 --- a/docs/const-binding-forin-loops-and-function-parameters.md +++ b/docs/const-binding-for-loops-and-function-parameters.md @@ -1,32 +1,44 @@ -# `const` bindings in for-in loops and function parameters +# `const` bindings in for loops and function parameters ## Summary -Extend the existing `const` keyword to support per-binding const declarations in generic `for-in` loops and `function parameters` +Extend the existing `const` keyword to support per-binding const declarations in for loops variables and function parameters. ## Motivation -Luau already supports `const` for local bindings +Luau already supports `const` for local bindings: ```luau const x = 10 const function foo() end ``` -However, there is no way to mark loop variables or function parameters as immutable. This leads to accidental reassignment bugs, especially in generic for loops where key/value pairs should remain unchanged, and in functions where parameters should be treated as read-only +However, there is no way to mark loop variables or function parameters as immutable. This leads to accidental reassignment bugs, especially in generic for loops where key/value pairs should remain unchanged, and in functions where parameters should be treated as read-only. ## Design ### New syntax +Generic loops: + ```luau --- Generic for-in: per-binding const for const k, const v in table do end -- both const for const k, v in table do end -- only k const for k, const v in table do end -- only v const ``` + +Numeric loops: + +```luau +for i = 1,10,1 do end -- normal usage +for const i = 1,10,1 do -- const variable i + i *= 2 -- err +end +for const const = 1,10,1 do end -- const is constant variable --overwrite const keyword +``` + +Function parameters: ```luau - -- Function parameters function foo(const x, const y) end -- both const function bar(const x, y) end -- only x const function baz(const, const x) end -- const is not constant variable name --overwrite const keyword, x const @@ -35,13 +47,15 @@ function baz(const, const x) end -- const is not constant variable name -- ## Backward Compatibility ```luau -for const in x do -- const is not constant variable name --overwrite const keyword -- If you used it this way before, there is no change. +for const in x do -- const is not constant variable --overwrite const keyword -- If you used it this way before, there is no change. end -for const const in x do -- const is constant variable name --overwrite const keyword +for const const in x do -- const is constant variable --overwrite const keyword end -function foo(const) do -- const is not constant variable name --overwrite const keyword -- If you used it this way before, there is no change. +for const = 1,10,1 do end -- if you used it this way before, there is no change + +function foo(const) do -- const is not constant variable --overwrite const keyword -- If you used it this way before, there is no change. end function foo(const const) do -- const is constant variable name --overwrite const keyword