mirror of
https://github.com/luau-lang/rfcs.git
synced 2025-05-04 10:43:48 +01:00
RFC for trailing commas in calls
This commit is contained in:
parent
4d5453ce33
commit
13e148e005
1 changed files with 120 additions and 0 deletions
120
docs/trailing-commas-in-calls.md
Normal file
120
docs/trailing-commas-in-calls.md
Normal file
|
@ -0,0 +1,120 @@
|
||||||
|
# Trailing comma support in calls and function definitions
|
||||||
|
|
||||||
|
## Summary
|
||||||
|
|
||||||
|
Luau will support trailing commas in the following places:
|
||||||
|
|
||||||
|
```lua
|
||||||
|
local function definition(
|
||||||
|
x: number, -- <-- Here, previously a syntax error
|
||||||
|
)
|
||||||
|
|
||||||
|
call(
|
||||||
|
a,
|
||||||
|
b, -- <-- Here, previously a syntax error
|
||||||
|
)
|
||||||
|
|
||||||
|
type Fn = (
|
||||||
|
x: number,
|
||||||
|
) -> ()
|
||||||
|
```
|
||||||
|
|
||||||
|
## Motivation
|
||||||
|
|
||||||
|
Currently, trailing commas are supported in several places in Luau.
|
||||||
|
|
||||||
|
```lua
|
||||||
|
local t = {
|
||||||
|
a,
|
||||||
|
b,
|
||||||
|
c,
|
||||||
|
}
|
||||||
|
|
||||||
|
-- Which even means...
|
||||||
|
f {
|
||||||
|
a,
|
||||||
|
b,
|
||||||
|
c,
|
||||||
|
}
|
||||||
|
|
||||||
|
type Type = {
|
||||||
|
a: number,
|
||||||
|
b: number,
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
However, they are not supported in function definitions, types, or calls. This is an unintuitive syntax error and it is obvious what the user intended to do.
|
||||||
|
|
||||||
|
## Design
|
||||||
|
|
||||||
|
We will make these adjustments to the grammar:
|
||||||
|
|
||||||
|
```patch
|
||||||
|
funcargs =
|
||||||
|
- '(' [explist] ')'
|
||||||
|
+ '(' {exp ','} [','] ')'
|
||||||
|
| tableconstructor
|
||||||
|
| STRING
|
||||||
|
```
|
||||||
|
|
||||||
|
This allows `f(a, b, c,)`.
|
||||||
|
|
||||||
|
There is no difference between `f(a(),)` and `f(a())`. Meaning, if `a()` returns `1, 2, 3`, then `f(a(),)` will be equivalent to `f(1, 2, 3)`. This is consistent with tables and `{ a(), }`.
|
||||||
|
|
||||||
|
```patch
|
||||||
|
parlist =
|
||||||
|
- bindinglist [',' '...']
|
||||||
|
+ (bindinglist [',' | ',' '...']
|
||||||
|
| '...' [':' (Type | GenericTypePack)]
|
||||||
|
```
|
||||||
|
|
||||||
|
This results in:
|
||||||
|
|
||||||
|
```lua
|
||||||
|
function f(
|
||||||
|
a,
|
||||||
|
b, -- New!
|
||||||
|
) end
|
||||||
|
|
||||||
|
function f(
|
||||||
|
a,
|
||||||
|
... -- The usual
|
||||||
|
) end
|
||||||
|
|
||||||
|
function f(
|
||||||
|
a,
|
||||||
|
..., -- NOT allowed
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
Trailing comma is not allowed after `...` as it is never correct to put more arguments after the ellipsis. This is consistent with:
|
||||||
|
- JavaScript - Supports `function f(a, b,)`, but `function f(...a,) {}` results in "Rest parameter must be last formal parameter".
|
||||||
|
|
||||||
|
Though this is not universally agreed upon:
|
||||||
|
- Rust's unstable C variadics support `unsafe extern "C" fn f(a: u32, ...,) {}`, though this syntax is not finalized.
|
||||||
|
- PHP supports `function f($a, ...$args,) {}`
|
||||||
|
- Go *requires* a trailing comma after every argument, including variadics, if split over multiple lines.
|
||||||
|
|
||||||
|
```patch
|
||||||
|
BoundTypeList =
|
||||||
|
[NAME ':'] Type
|
||||||
|
[',' BoundTypeList]
|
||||||
|
+ [',']
|
||||||
|
| '...' Type
|
||||||
|
```
|
||||||
|
|
||||||
|
This results in:
|
||||||
|
|
||||||
|
```lua
|
||||||
|
type Fn = (x: T,) -> () -- Allowed, new!
|
||||||
|
type Fn = (x: T, ...U) -> () -- Allowed
|
||||||
|
type Fn = (x: T, ...U,) -> () -- Not allowed
|
||||||
|
```
|
||||||
|
|
||||||
|
## Drawbacks
|
||||||
|
|
||||||
|
There are no interesting drawbacks.
|
||||||
|
|
||||||
|
## Alternatives
|
||||||
|
|
||||||
|
Supporting `function f(...,)` is easily doable if the rules seems unintuitive.
|
Loading…
Add table
Reference in a new issue