8 ms·
I can understand braces (to an extent...). What really confuses me are new languages that still require semicolons at the end of expressions/statements.
by Varriount 2y ago
I can understand braces (to an extent...). What really confuses me are new languages that still require semicolons at the end of expressions/statements.
- IcyWindows 2y agoWhy is that so much more different from requiring '\n' instead of ';'?
- gavindean90 2y agoMaybe I like the ‘\n’ for me and the ‘;’ for the compiler.
- xigoi 2y agoThere should be only one source of truth.
- sodapopcan 2y agoBecause when reading as a human you're typing `\n` anyway which fits in with the whole "Can't the computer just figure out what I'm seeing?" thing. While it's technically correct (the best kind of correct) that it's '\n' vs ';', in practice it's really ';' vs ';\n'. I can only speak to my personal experience but seeing two expression on one line is so rare that I can't even think of an example of the last time I saw it.
- masklinn 2y agoThe problem is not two expressions on one line, it’s one expression on two lines. e.g. foo .bar() now you need to either add syntax to specify that you’re “continuing” (python), play tricks for the parser (Go), or have unreliable magic biting you in the ass half the time (javascript).
- deleted 2y ago[deleted]
- sodapopcan 2y agoI understand it's likely stupid in Python since it's whitespace significant, but are those Go parser tricks really such a big deal or even very tricky?
- arp242 2y agoIt's not that difficult; just place the "." at the end of the line: foo. bar() And that will work fine. At least in Go. You can endlessly argue what location is better for the ".", but it really doesn't really matter. Regardless, you don't really need to do parser tricks.
- masklinn 2y agoThat's exactly what I mean by parser trick. You're relying on the idea that if the parser sees an incomplete expression it won't end the statement then and there. It also looks like shit, because now you have to check the end of the previous line to know whether it's a method call or a function call which was indented in incorrectly.
- arp242 2y agoWith gofmt it's always indented correctly.
- sodapopcan 2y agoSure but that doesn't quite answer my question: is the parser trick really that bad? I do see what you mean, of course, and am aware of the arguments but I've never found lack of non-whitespace expression terminator even remotely confusing. I can clearly see indentation in my periphery signalling that it's multi-line. I can also say that in ~13 of using exclusively using semicolon-less languages, I've never had or even heard of a problem caused by someone misunderstanding where an expression ends. Anyway, this is getting pretty bikesheddy, lol but ya, to each their own, obviously.
- stkdump 2y agoWhat confuses me is languages that can split statements over multiple lines as long as certain conditions are met (such as the break occours inside braces). I rather have a semicolon at the end of the statement to make it more explicit.
- RHSeeger 2y agoThis is where I stand. Semicolons convey intent, much like parens in math equations. Sure, the code makes it clear (if you understand the rules) what "the code does", but having semicolons (and parens) make it clear that "what the code does" and "what the writer intended the code to do" are the same thing. Plus I don't think I've ever seen a case where semicolons made the code harder to read (or write).
- xigoi 2y agoBut why a semicolon? Sentences have been terminated by periods for hundreds of years until programmers decided to be special snowflakes.
- TwentyPosts 2y agoSpeaking from a Rust-perspective, having semicolons at the end of statements makes perfect sense and is a brilliant design decision. Note that I said 'statements', not 'expressions'. A lot of the confusion here (and maybe yours, too) stems from this difference. In Rust, (almost) everything is an expression by default, and you turn it into a statement by adding a semicolon. This allows you (and the type checker) to very neatly distinguish between expressions and statements, which is great. It's a very nice and elegant approach imo.
- Spivak 2y agoDoes the difference ever come up in a meaningful way? Is there a syntax that without the trailing semicolon is ambiguous between the two, and the difference changes the behavior?
- masklinn 2y agoAll the time. A block (in the general sense so that includes function) which ends with an expression will have that expression’s value as its own value (/ return). A `;` converts the trailing expression into a statement, which does not have a value, and thus the block returns `()` (the something representing nothing). Method chaining is also common in Rust, because builders are common, and chains of iterator adapters are common, and chains on monadic structures (option/result) are common, … having every line break implicitly insert a `;` would be horrid.
- notpushkin 2y agoWait, so this is legal: fn five() -> i32 { 5 } and this isn't? fn five() -> i32 { 5; } I can't tell if I'm amazed or terrified.
- deleted 2y ago[deleted]
- jihiggins 2y ago
- voidUpdate 2y agoI like semicolons, because it lets me use the brackets style I prefer (allman) instead of whatever the language devs think I should use. This is a really big issue for me trying to use Go, as they automatically insert a semicolon to the end of every line that doesn't end with a {, so the language forces you to use K&R, which I really dislike reading
- xandrius 2y agoThat's not really true though, I've used golang for years and never had semicolons added automatically.
- voidUpdate 2y agoI don't mean it actually adds them to the file itself, its like it adds virtual ones during compilation. Try placing the { from the func main() { on a new line and it will fail to compile
- xandrius 2y agoOh, I see, that's what you meant. Thanks for clarifying :)
- arp242 2y agoThe Go compiler inserts semi-colons. https://go.dev/ref/spec#Semicolons https://go.dev/ref/spec#Semicolons If you follow those rules, you will see that this: if true; { fmt.Println() } else { fmt.Println() } Will get rewritten to: if true; { fmt.Println(); }; else; { fmt.Println(); }; And that won't work. That's why the braces need to be as "} else {". and "if .. {". It used to be that the compiler gave some pretty confusing errors about semi-colons on this, but it seems that's been improved now. JavaScript has similar semi-colon insertion by the way, but with some different (more confusing) rules.
- xandrius 2y agoThat's really neat, it had escaped me till now. Thanks for the explanation (today I'm one of the lucky 10,000!)
- layer8 2y agoIn general, what helps parsers for disambiguation also tends to help human readers for disambiguation. In addition, some amount of redundancy helps to prevent errors when (for example) two statements were intended but they are parsed as one, or vice versa. Furthermore, consistency helps avoid errors, such as always ending a statement with a semicolon and not only when it would otherwise be ambiguous.