I propose allowing for empty blocks in most settings. We already support them in functions, and case/when/pattern matching. This PR adds them to all loops, if/else, and for symmetry, do blocks and comptime.
CoffeeScript supports this in if/else expressions that have both if and else: both empty, empty if. I think this hints at why it is useful:
Suppose you have code with an if/else construct, and you comment out the then or else block. Currently, that makes a parse error. Commenting out the else block is not too bad: just comment out the else keyword too. But commenting out the if block is hard: you need to comment out the if line, the else keyword, and dedent the else block. This makes for a lot of code changes if you want to debug removing some code (e.g. to isolate a bug).
This is exacerbated by comments not counting as a block. So you can't do e.g.
if empty
// don't need to do anything in this case
else
doStuff()
I've wanted to write code like this at times. Currently it's a parse error in Civet.
Related, as you're typing lines in VSCode, I feel like it's less likely that you have code with parse errors, so you keep the useful feedback in more situations.
My guess is that CoffeeScript couldn't handle empty if blocks without else, and loop blocks, because they are somewhat ambiguous with postfix if/loops. But a little work on the "ExpressionizedStatement" code made it easy to not expressionize in this case of empty blocks.
For example, this fixes #1162: the surprising behavior was the loop becoming a postfix after a semicolon, but when it can be an infinite loop by itself, the behavior is intuitive (though not very useful). Similarly, @bbrk24 mentioned x := comptime loop being counterintuitive: it used to give an infinite array of comptime identifiers, but now it gives the more natural but not very useful behavior of adding an infinite loop to a comptime function.
Funny enough, I encountered #1162 for the exact reason you mentioned about commenting out code. Frankly I don't find either interpretation of comptime loop "useful", but the new way is more intuitive.
I propose allowing for empty blocks in most settings. We already support them in
function
s, andcase
/when
/pattern matching. This PR adds them to all loops, if/else, and for symmetry, do blocks and comptime.CoffeeScript supports this in
if/else
expressions that have bothif
andelse
: both empty, empty if. I think this hints at why it is useful:else
keyword too. But commenting out the if block is hard: you need to comment out theif
line, theelse
keyword, and dedent the else block. This makes for a lot of code changes if you want to debug removing some code (e.g. to isolate a bug).I've wanted to write code like this at times. Currently it's a parse error in Civet.
My guess is that CoffeeScript couldn't handle empty
if
blocks withoutelse
, and loop blocks, because they are somewhat ambiguous with postfix if/loops. But a little work on the "ExpressionizedStatement" code made it easy to not expressionize in this case of empty blocks.For example, this fixes #1162: the surprising behavior was the
loop
becoming a postfix after a semicolon, but when it can be an infinite loop by itself, the behavior is intuitive (though not very useful). Similarly, @bbrk24 mentionedx := comptime loop
being counterintuitive: it used to give an infinite array ofcomptime
identifiers, but now it gives the more natural but not very useful behavior of adding an infinite loop to a comptime function.