12 ms·
Completely off topic but, after doing python for ages, recently started writing Rust and semicolon does seems useless. We are doing the indentation and new line
by zuj 5y ago
Completely off topic but, after doing python for ages, recently started writing Rust and semicolon does seems useless. We are doing the indentation and new lines anyway, why not just make them as default language construct as python does.
(autodidact developer here, feel free to ELI5 and enlighten me)
- Tyr42 5y agoWell, have you ever run into the x = some_long_expression + another_long_expression problem? In Python you need to be careful to wrap that in () or use a \ before the newline to avoid it parsing as two lines, e.g. x = some_long_expression; + another_long_expression; In particular, if you have a builder expressions let x = someBuilder() .setVal(x) .build() You'd need to wrap the entire thing in () to avoid it getting mad, right? So if you're going to terminate expressions with ), and start them with (, why not just terminate them with ; instead? Javascript is a "Semicolons Optional" language, but it's actually the worst of both worlds, as you have to be very careful not to wrap lines like function() { some stuff; return really_long_named_thing; } As it'll just insert a ; on the return, returning undefined for you.
- zuj 5y agoLove the examples, thanks for ELI5.
- PhineasRex 5y agoTo be fair, that's really more of a python-specific deficiency than a general problem with significant whitespace. Haskell for example interprets further-indented lines as a continuation of the current expression, only ending the expression when it sees a new line of the same or lesser indentation.
- ReleaseCandidat 5y agoAs I wrote, you have to do similar things when using Haskell (or F# or OCaml) in the REPL. Python just doesn't have a special 'non-REPL' syntax.
- ReleaseCandidat 5y ago> In Python you need to be careful to wrap that in () or use a \ I guess that's because in the REPL Python need's to know whether the line has finished yet or not. OCaml and F# uses two semicolons ';;' for that purpose, but only in the REPL. In Haskell you can use braces and semicolons or '{:' and ':}' in the REPL.
- Tyr42 5y agoIt's not just in the repl.
- emmelaich 5y agoAt least Python will give you a diagnostic. Ruby is worse; even with parentheses ... salary = 100500 newsalary = (salary * 0.02 + salary) newsalary will the same as salary. There are no diagnostics. Yes, you can fix it by moving the + up a line but this should be a purely style thing, not semantics.
- igorkraw 5y agoBecause then there'd be ambiguity between a function ending and returning unit (nothing) or returning whatever the last line expression returns. You could change things around this, but Rust has a goal of unambiguous syntax, hence also the turbofish::<>
- vvillena 5y agoRust uses the semicolon to distinguish between statements and expressions.
- zuj 5y agoYes, coming from python it took a while for me to wrap my head around this.
- vlmutolo 5y agoIt's a lot easier to format code arbitrarily when a language is whitespace-independent. For example, to do method chaining across multiple lines, Python requires parentheses around the whole chain. That's a quirk of being a whitespace-dependent language. In general, I think people who advocate for braces and semicolons just find it easier to reason about the code when they know that the formatting doesn't matter. All the flow is done via visible glyphs.
- gnufx 5y agoHaskell has an alternative parens-and-braces syntax to the offside rule; that was meant particularly for machine-generated code if I remember correctly. Edit: I meant to add: you need to decide whether ";" is terminates or joins statements if you have statements in the language.
- Denvercoder9 5y agoIt's a trade-off. You can either assume all statements end at the end of the line, and require a continuation character (backslash in Python) if that isn't the case; or you can require a statement terminator (semicolon/closing brace in Rust) for all statements. The downside of assuming statements end at the end of the line is that you need to have special rules for when that isn't the case (such as Python's implicit statement continuation inside braces), while always having a terminator is simpler and more consistent (all statements end with a semicolon) at the cost of extra characters.
- zuj 5y agoThanks, this makes perfect sense. Python we are using \n instead of ; as the statement terminator. Just didn't got what you mean by "python's implicit statement continuation inside braces" ?
- comeonseriously 5y agoThere are people who hate python because of the forced indentation. They indent their code in their language of choice, they just don't want something FORCING them to do it. I'm always flabbergasted at this argument.
- seoaeu 5y agoI don’t indent my code, my autoformatter does. It is way less effort to get the braces right and then have the indent level inferred automatically
- comeonseriously 5y agoAutomated tools get in my way of thinking. I turn off intellisense, auto-formatters, etc... I'll run auto tools during check-in, but not during coding sessions.
- soledades 5y agoNo find and replace, either? ;)
- comeonseriously 5y agoI use those. But how would those be automated exactly? How would they know what I want to find and replace?
- gpm 5y agoBy understanding the language, so it can do magic things like "rename this field (including uses of it)" without changing other uses of the same string. As a separate operation from general find and replace, of course.
- soledades 5y agoYou tell it what you want to find and replace with and then it automates the rest. My point being that where you draw the line between what you consider automated vs not is pretty arbitrary.
- post-it 5y agoIn Rust, a block that ends with an expression without a semicolon returns that expression. It lets you write terse things like let x = if y { a } else { b }
- NoSorryCannot 5y agoKotlin does the same but without semicolons so it would seem not to be essential.
- the__alchemist 5y agoIn Rust, omitting a semicolon has a special meaning, ie a return from an expression. So, you can't just ditch it. I wouldn't mind Python's whitespace indents in Rust though!
- ReleaseCandidat 5y ago> In Rust, omitting a semicolon has a special meaning, ie a return from an expression. So, you can't just ditch it. Of course you could, because a semicolon-less return doesn't work in the middle of a statement. You can't do bla; a bla bla; b instead of bla; return a; bla bla; b Yes, the code after the `return` isn't reachable and the Rust compiler doesn't like that ;)
- wizzwizz4 5y agoBut that would mean {123 456} + {789} was 1245 instead of 124_245.
- alpaca128 5y agoPython and Rust have two fundamentally different philosophies. Python is all about quick and intuitive programming and it's pretty good at that, though in turn you can get more kinds of bugs and runtime errors that could have been avoided with proper type checking and other measures. Meanwhile Rust avoids any kind of behaviour that isn't clearly visible in the code. That includes unambiguous syntax, like the mandatory curly braces for loops and conditions. And of course the semicolon as a clear separator, which comes in handy when iterators or the builder pattern are used.
- ReleaseCandidat 5y agoThat argument has the flaw of not working with Haskell, OCaml or F# ;) Really, Rust only doesn't look like OCaml because less people would use it if it wouldn't have braces and semicolons. Found this post, for example: https://news.ycombinator.com/item?id=5607912 https://news.ycombinator.com/item?id=5607912
- jbaber 5y agoI'm pretty happy with the choices made in rust and python. Just want to note that the : in Python is just as superfluous (as rubyists will tell you) and kept only for readability, not for parsing.