-
Notifications
You must be signed in to change notification settings - Fork 70
RFC: Empty Statement Syntax #146
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
base: master
Are you sure you want to change the base?
RFC: Empty Statement Syntax #146
Conversation
| To solve it, the tool will likely want to insert a semicolon at the beginning, and, to be sure, end of the statement. Doing so would also be dangerous, as a syntax error would occur if the statement already had any surrounding semicolons or no statement was preceding it in the block. Tools need to check the context to skip introducing a semicolon where it'd cause an error, adding unnecessary and probably unexpected complexity. If empty statements were allowed, tools could safely surround statements with semicolons, guarding against ambiguity without having to worry about context. | ||
|
|
||
| This is especially useful for simple "insert-replace" tools that don't perform a syntactic analysis of the code, such as search-and-replace operations in code editors, where currently each replacement would need review to avoid syntax errors. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The tooling argument is compelling, but this argument is not. Using find-and-replace to make your code a horrible mess sounds like an antipattern, and the fact that you today might get parsing errors to correct intentionally actually sounds much better in comparison.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Writing prettier or uglier code with more or fewer semicolons is up to the user. If they insert unnecessary semicolons, they can manually remove them where they see fit or pass the code through a formatter. "Ugly syntax" that is not ambiguous should not be a parsing error, regardless of how ugly it is.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If unnecessary semicolons are too horrendous to pass normally, Luau's linter could add a "DuplicatedSemicolon" lint when two or more semicolons are used in a row without whitespace in between. But this is merely style and imo should be up to an external tool. And hey, maybe someone wants to use double semicolons to be extra explicit about a no-op. They should be able to without errors or lint warnings.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To make a clearer and more reasonable example: in my code, I might have a specific comment that I want to replace with a series of debugging statements when built for debug. For this, I use a simple CLI tool that replaces occurrences of that comment with my statements. If I want to avoid ambiguity, I'd need to either add a preceding semicolon where appropriate to the comments, or use a more sophisticated and unnecessary solution that performs a syntactic analysis. Both unideal for something theoretically dead simple.
| end | ||
| ``` | ||
|
|
||
| This syntax however, unlike with statement blocks, is considerably confusing and unusual, has an unclear purpose, and is very likely a mistake, with little to no practical use cases. In table constructors, a single trailing separator is already allowed. No newline at end of file |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why are these obviously a mistake, but the proposed syntax isn't obviously a mistake? That feels like it needs to be articulated much more crisply.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
f(1, , 3) isn't clear as to whether the intention was to do f(1, nil, 3) or f(1, 3). In my opinion, the most likely thing is the user inserted a comma as placeholder and forgot to insert an actual value later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unlike with statements, an "empty element" in these other list syntaxes does not make sense and needs to either be nil or skipped entirely. I don't believe I can find any benefits to allow "skipping" in those other contexts, and silently defaulting to either of those two solutions would do more harm than good.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not asking you to convince me here, I'm asking you to revise the RFC to be more convincing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just stating it here for documentation and amending with any further observations when I can
| ``` | ||
| > Error:2: Ambiguous syntax: this looks like an argument list for a function call, but could also be a start of new statement; use ';' to separate statements | ||
| To solve it, the tool will likely want to insert a semicolon at the beginning, and, to be sure, end of the statement. Doing so would also be dangerous, as a syntax error would occur if the statement already had any surrounding semicolons or no statement was preceding it in the block. Tools need to check the context to skip introducing a semicolon where it'd cause an error, adding unnecessary and probably unexpected complexity. If empty statements were allowed, tools could safely surround statements with semicolons, guarding against ambiguity without having to worry about context. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the tool will likely want to insert a semicolon at the beginning, and, to be sure, end of the statement
Beginning and end? Why? It's trivial to decide whether a semicolon is necessary by literally just stringifying the next statement, and then see if that string starts with (. If it starts with (, then add a ; to the current line, then \n and then add the indentation and finally, the statement string in question.
Something like this:
function print_block(stmts)
local result = table.create(#stmts)
for i, stmt in stmts do
table.insert(result, print_stmt(stmt))
end
for i, stmt_str in result do
local next_str = result[i + 1]
if next_str == nil then
break
end
local ends_with_semi_colon = string.byte(stmt_str, -1) == string.byte(";")
local starts_with_open_paren = string.byte(next_str, 1) == string.byte("(")
if not ends_with_semi_colon and starts_with_open_paren then
result[i] ..= ";"
end
end
return table.concat(result, "\n")
endYou can avoid an intermediate table if you wish, but I don't care. This argument is weak. Obviously, the specific code I've given you will still generate ; even when it isn't strictly necessary, but you can just replace ends_with_semi_colon with a function that takes some stmt and returns a boolean indicating whether the given stmt fragment ends with an expression and without a semi-colon. Still trivial.
Rendered
Allow empty statements as introduced in Lua 5.2: