7 ms·
The two on here that stand out as things I agree with but don't see called out much are: > allowing semicolons to be omitted after some expressions, like match
by stormbrew 4y ago
The two on here that stand out as things I agree with but don't see called out much are:
> allowing semicolons to be omitted after some expressions, like match, if/else, and if
This drives me up the wall. I know a lot of rust's aesthetic is there to make C++ programmers comfortable (I'm a recovering C++ programmer myself), but it would have been so much better if semicolons had been left out.
It seems like we put a semicolon on every line (except the ones mentioned above! But only if they're not subexpressions!) just to make the whole "you don't need to say return in the last statement" look clever.
> Confusion about whether to use kebab-case or snake_case for crate names I now lean to the former, but it's impossible to import snake case crates using kebab case, leading to an ugly mix in my Cargo.toml file.
I'm so tired of guessing which one I need every time I import a crate in Cargo.toml. Never mind that this is a blatant opportunity to make supply-chain attacks. I don't know why these are treated as distinct names in crate names, and if there are any conflicting crates out there in the wild right now they should probably all be forced to rename.
My personal pet peeve that doesn't come up much is the way magic impls around From/TryFrom/Into/TryInto conspire to make incredibly obtuse error messages about implementing TryFrom<T, Error=Infallible> or the like. I'm not entirely convinced having these 'helpful' impls is really worth it, at least not the way they were implemented.
- gpm 4y agoSomeone correct me if I'm wrong, but I think the semi-colons main purpose is to make error messages better. It makes it easy to say "well, the previous malformed statement definitely finishes by here".
- jhugo 4y agoAnd to avoid all the horrible edge-cases that can arise when the parser has to work out whether the next line is a continuation of the same statement or not. For example in JS: var x = y.z [a, b, c].forEach(doIt) parses to: var x = y.z[a, b, c].forEach(doIt) rather than the two statements that were clearly intended.
- xigoi 4y agoJavaScript's algorithm for this is dumb. There are better ways to do it, as seen in Python, Ruby, Nim, …
- stormbrew 4y agoThere are a bunch of reasons why this is more of an issue in JavaScript than it is or would be in most languages. The early incarnations of the language practically leaned into bad parsing logic and it's permanently stuck with them now. But in particular any strongly typed language is gonna need some really convoluted code to produce similar ambiguities that actually make it to linking. I think the most likely "bad" outcome of semicolon-less rust would be losing the hanging dot function chaining people do so much in rust, but even that's not a guarantee.
- srcreigh 4y agoThis was almost prevented from the get go. Brendan Eich tried to implement scheme in the browser. But the business people asked him to make it look like Java. :(
- littlestymaar 4y ago> But in particular any strongly typed language is gonna need some really convoluted code to produce similar ambiguities that actually make it to linking. Even if it's a compiler error, what are you supposed to do when the compiler returns the error from the snippet above?
- stormbrew 4y agoI think you'll need to come up with an example that exploits a weakness in rust's grammar for me to answer that? The above js example I don't think it would make sense to have rust erase the newline to begin with.. I think the main way that people hang syntax like this in rust is with chained .methods, and since . at the start of a statement isn't valid rust to begin with it could probably be unambiguously be allowed anyways. But I wouldn't expect: a [1] To be considered valid specifically because of the potential ambiguity of a single term array and a suffix index. It's also not really common right now anyways, afaik. JavaScript tries to be way too damn clever here and no one is ever going to seriously suggest anything try to replicate "automatic semicolon insertion". Just don't allow line joins when it makes the next line ambiguous. Interestingly it would be possible to come up with a straw man parser that makes semicolons optional and then run it through the whole "recompile every crate" thing the rust project has to see if it would cause new failures. It would be an interesting project tbh.
- stormbrew 4y agoBecause not all statements in a block have to end in a semicolon, and most things at module scope don't, rust fails at this anyways imo. Without an editor's help I'm pretty frequently lost finding the missing balancer for an open brace or parenthesis.
- Gigachad 4y agoI feel like cargo should have gone further and made it borderline impossible to write out the package name from a guess and require you to look it up and copy/paste the name so its always right. They should have required all packages to be scoped under an org name like NPM is moving towards. That would have stopped typo squatting much better than making names insensitive to all kinds of weird conventions.
- maxbond 4y agoI think it would've been sufficient to namespace package names, something like `dtolnay::syn = "1"` (this is terrible syntax, just an example). Perhaps also allow Cargo to be configured to fail if any of the packages were outside of an allowlist of trusted namespaces. I think this is a good compromise between allowing people to experiment quickly and allowing established projects to lock themselves down.
- hobofan 4y agoThere is some promising work going towards bringing namespaces to Cargo: https://github.com/rust-lang/rfcs/pull/3243 https://github.com/rust-lang/rfcs/pull/3243
- shadowofneptune 4y ago> It seems like we put a semicolon on every line just to make the whole "you don't need to say return in the last statement" look clever. This has been my own finding when designing a language. Freestanding expressions can in most cases be turned into statements. Even for things like Rust's if...else expressions, a 'be' keyword could work.
- LegionMammal978 4y ago> Never mind that this is a blatant opportunity to make supply-chain attacks. I don't know why these are treated as distinct names in crate names, and if there are any conflicting crates out there in the wild right now they should probably all be forced to rename. crates.io already disallows crates differing only in underscore/hyphen choice. I can't easily find documentation to this effect, but users have reported it returning an error (e.g., [0]). [0] https://github.com/rust-lang/crates.io/issues/166 https://github.com/rust-lang/crates.io/issues/166
- stormbrew 4y agoI suppose it must be a thing that while crates.io does disallow this, there's a possibility that there's a private registry out there that does allow it. That's the only reason I can think of for why they haven't just made it treat them as interchangeable in Cargo.toml files.
- LoveMortuus 4y agoIs it Stockholm syndrome if I prefer semicolons over no semicolons? It gives me warm fuzzies in the belly knowing that as long as I've placed the semicolon it doesn't matter if I indented correctly or used the new line correctly. I'm even one those weirdos that put the first squiggly bracket right after the statement( if ( ... ) { . . . }
- eslaught 4y agoThere are languages like Lua that do not require semicolons and are also whitespace (and newline) insensitive. That comes with other tradeoffs, the main one being that Lua is forced to maintain a pretty restrictive grammar to remain unambiguous. There are only very limited expression statements, for example. But anyway, it exists and it addresses the points you specifically made in your comment.
- isitmadeofglass 4y agoMaybe. Is it Stockholm syndrome that I prefer indentation? It gives me warm fuzzies in the belly knowing that as long as I’ve indented correctly it doesn’t matter If I placed the semicolon.
- LoveMortuus 4y agoNice, but ... Can you write an entire program in one line? (Obviously a joke. I've never written a program in one line, but I do respect the art of 5he craft.)
- alpaca128 4y ago> just to make the whole "you don't need to say return in the last statement" look clever. I sure prefer `let x = if foo { 0 } else { 1 };` over `let x = if foo { return 0; } else { return 1; };`. Which raises another potential dilemma: do you break consistency and allow returning values without `return` in if-blocks, or do you make it impossible to return from a function early within them, instead making the returns exit the if-expression early for ultimate confusion? No, please don't take away my semicolons unless you provide an actual alternative, even if it's just a Lisp-like flood of parentheses.
- xigoi 4y agoWhy not do it like Ruby, where blocks always return the result of the last statement (and the return keyword returns from the nearest enclosing function)?
- FullyFunctional 4y agoI think the alternative style of semicolons are as separators which makes more sense from the grammar and is what many languages that are C-like do. Rust tries to be both and unsurprisingly ends up with complicated and IMO fragile rules.
- stormbrew 4y agoIt's not clear to me why it even needs to be treated as a special case. In particular, the biggest other example of a language that has this "return or hanging last expr" I'm aware of is ruby, where the problem with it is that accidentally returning a value from a block might affect escape analysis for GC, but rust doesn't have that problem. In your example, the if is in expression position, so it's fine if it treats its bodies as expressions. I'm definitely not saying I want to pepper my code with returns, I'm just unconvinced semicolons help with avoiding that.
- foerbert 4y agoThere are other options out there. Ada, for example, has extended return statements and - more directly - expression functions.
- specialist 4y ago> ...would have been so much better if semicolons had been left out. FWIW, I created a DSL where comma and semicolon are treated as whitespace. > ...kebab-case or snake_case... Crate names are case insensitive, right? Maybe treat underscore and hyphen as different cases of the same delimiter?