DEV Community

Discussion on: How do you feel about braces and semicolons?

Collapse
 
tbroyer profile image
Thomas Broyer

No-semicolons are a problem IFF expressions can be statements (not sure about the terminology here).

For example

foo = bar
  - baz

could be read as either

foo = bar - baz

or

foo = bar;
-baz;

but -baz could be forbidden as a statement (Go rejects it, but neither Kotlin or JavaScript do).

No semicolons also means you sometimes have to end your lines with \ to have them parsed correctly, or make sure you put binary operators at EOL (see above, also applies to . or ->, or logical operators).

Also, braces, definitely! Less typing, and lighter-weight visually than end keywords (or similar, please don't make context-dependent keywords like in shell: if …; then …; fi, while …; do …; done, case … in … ;; esac, etc.), and significant whitespace, well… (nothing against Python, but there must be reasons other mainstream languages didn't copy this facet of it)

Collapse
 
cad97 profile image
Christopher Durham

The way Swift handles this is interesting.

let x = 10
- 1
// is
let x = 10
- 1;

let x = 10
-1
// is
let x = 10;
-1;

let x = 10 - 1
// is
let x = 10 - 1;

let x = 10 -1
// is
let x = 10; -1;
// Error two statements on the same line must be separated by a semicolon

The rule is basically [space][op][space] or [nospace][op][nospace] is an infix operator, [space][op][nospace] is a prefix operator, and [nospace][op][space] is a postfix operator.

Collapse
 
17cupsofcoffee profile image
Joe Clay • Edited

Yeah, that's definitely a problem with parsing languages without semicolons - I quite like the solution that the developer of Wren (who, incidentally, is also the author of Crafting Interpreters) went for:

Newlines (\n) are meaningful in Wren. They are used to separate statements:

// Two statements:
System.print("hi") // Newline.
System.print("bye")

Sometimes, though, a statement doesn’t fit on a single line and jamming a newline in the middle would trip it up. To handle that, Wren has a very simple rule: It ignores a newline following any token that can’t end a statement.

System.print( // Newline here is ignored.
    "hi")

I find that a bit easier to keep in my head than JavaScript/Go's automatic semicolon insertion rules.

Collapse
 
tbroyer profile image
Thomas Broyer

AFAICT, this is basically what Go does too (golang.org/ref/spec#Semicolons, expressed as a whitelist rather than blacklist) except -baz by itself, while a valid expression, is not a valid statement, so code wouldn't compile rather than most probably creating a bug.

Of course, it's not actually equivalent, but the rule is easy. By this rule, the following wouldn't compile, but would be accepted in Wren (Go doesn't have ternary operator either though)

foo(bar
    ? baz : qux)

I suppose the choice also depends whether you want a "lenient" language (like JS) or a stricter one (like Go). It's hard to create subtle bugs in Go due to parsing alone, it's way too easy in JS, which is why people add ESLint or similar to tell them when they likely did it (though it probably cannot detect everything).

Automatic formatting (Prettier) also helps detecting such bugs ("why did it un-indent that -bar?"), but that's still left to the developer to "decide" whether he introduced a bug or not.

I, for one, prefer strictness over "format your code the way you want it". Python is good in this respect if significant whitespace is your thing; otherwise, lean towards Go rather than JS (when it comes to semicolons)