4 ms·
Rust has both “essential verbosity” and “accidental verbosity”: (0) Lifetimes have to be represented in the language's syntax somehow, and this can't be avoide
by catnaroek 10y ago
Rust has both “essential verbosity” and “accidental verbosity”:
(0) Lifetimes have to be represented in the language's syntax somehow, and this can't be avoided. Lifetime elision makes this a nonissue, anyway.
(1) Rust's syntax for function declarations is horrendous. In a single place, it does two things that ought to be kept separate: state the type of the function and give names to the function's arguments. This by no means essential, e.g., Haskell does this much better.
(2) The lack of global type inference really hurts when you write functions with syntactically large argument and/or return types. AFAICT, Rust's type system is Haskell's minus HKTs plus higher-ranked lifetimes. Most Rust code doesn't use anything higher-ranked, so Rust could have much more aggressive type inference. The only impediment is the Java-like syntax for method calls: you can't infer nominal object types from how objects are used. This is again purely accidental.
- masklinn 10y ago> This is again purely accidental. WRT 2 and 3, disabling/not doing global type inference was a wilful choice, Rust's designers specifically decided not to do that and to keep type inference local. Not splitting signatures out of function declarations comes from the same place, having removed GTI there was no point in making type signatures and function declarations independent, and it provides for uniform declaration when there's no function/method body ("abstract" trait methods, extern declarations).
- catnaroek 10y agoWillful or not, it makes the language more verbose.
- masklinn 10y agoI don't think it does, other syntactic decisions (e.g. C++/Java-style generic declarations, reference sigils) might, or at least make the language seem noisier, but with respect to function type declarations you'd get the exact same verbosity (in terms of tokens or characters), just split differently e.g. fn class(&mut self, s: &'a bstr) -> u16 versus class :: &mut, &'a bstr -> u16 fn class(self, s) all you get is repeating the function name.
- catnaroek 10y agoThink about `where` clauses.
- masklinn 10y agoWhere clauses don't go away and their verbosity doesn't change.
- catnaroek 10y agoTrait constraints in Rust are syntactically more annoying than type class constraints are in Haskell. This is in spite of the fact that, semantically, both are exactly the same thing.
- valarauca1 10y agoThis is in spite of the fact that, semantically, both are exactly the same thing. Semantics is not practice. Rust is a compiled language. All Types/TypeClasses have to eventually be resolved down to concrete structures/tuples that can be statically or dynamically dispatched too, and in most cases allocated to the heap/stack. Haskell is NOT a compiled language. It compiles to a bytecode that is ran by the RTS (Run Time System) a ball of ~50,000SLOC in C/C++. Haskell TypeClasses are MAGIC managed by the run-time. They are not resolved to actual machine code. A compiled Haskell program is just the bytecode+source code+compiler+RTS bundled into an ELF. Yes some Haskell is translated into pure C, but all of it can't be. The pure C Haskell still depends on the run time heavily. Especially for managing type class dynamic dispatch.
- tome 10y ago> Haskell is NOT a compiled language Yes it is > It compiles to a bytecode that is ran by the RTS Nope, it's compiled to machine code. (We're talking about GHC here, of course)
- 10y ago