8 ms·
The syntax is nicer. Granted, I'm not very familiar with D. I didn't even know it had a borrow checker. Rust took a lot of great features from Haskell, while
by thomastjeffery 6y ago
The syntax is nicer.
Granted, I'm not very familiar with D. I didn't even know it had a borrow checker.
Rust took a lot of great features from Haskell, while keeping itself reasonably approachable from a C/C++/D/Java programmer's perspective.
Rust put type names after variable/function/parameter names, which really cleans up the syntax nicely.
Rust has very nice syntax for pattern matching, monads, and a slew of other really helpful functional language features.
Even if rust didn't have a borrow checker, it would still be a wonderful systems programming language.
- juststeve 6y agoAlso option / result types as well which are super nice
- erik_seaberg 6y agoJudging by https://dlang.org/blog/2019/07/15/ownership-and-borrowing-in-d/ https://dlang.org/blog/2019/07/15/ownership-and-borrowing-in... it's a pretty recent addition.
- tastyminerals2 6y agoOne of the reasons why I haven't approached Rust is its syntax. Subjectively ugly and polluted with punctuation symbols that tell you little about their semantics. D looks cleaner and more readable even for a person not familiar with the language. D's readability is on par with scripting languages. Rust is far away from that. Type names after variable or before? When you think about declaring a variable, do you think about its type of name first? I can't imagine you do the latter because "Hmm, I need an array of doubles to represent my tensor" is double[][] tensor; and not tensor: double[][]. Besides the types after names end up being more verbose in the languages which adopt the scheme (hello Scala). I invite you to get familiar with D syntax to see a wider picture. The borrow checker in D is WIP and given how much stir it created, I don't see it's happening any time soon.
- vvillena 6y agoThe reason behind putting the type after the variable is that the resulting syntax plays way better with type inference. Scala is a clear inspiration for Rust in that regard.
- tastyminerals2 6y ago(Let me nip a little here). Looks like not only Scala inference types but also its compile times too migrated into Rust.
- vvillena 6y agoHahaha, it's true that Rust compile times are slower than its main competitors, due to the amount of work the compiler does. It's the same with Scala: even if some abstractions in both languages are zero- or low-cost during runtime, they still slow down compile times. In any case, as a Scala dev, I wish the compile times were as short as in Rust!
- zucker42 6y ago> When you think about declaring a variable, do you think about its type of name first? I completely disagree with your opinion on this subject, though I recognize that it's mostly subjective. I think types after the variable are completely better except for my muscle memory from C.
- CDSlice 6y agoThe nice thing about Rust is you often don’t have to declare the type of a variable since the compiler will just infer it for you. This is especially nice in an IDE like CLion which will show you the inferred type for each variable. As for the syntax for a type declaration, `variable: Type` is more natural and readable for me than `type variable`. The first one naturally reads as `variable is a Type` while the second reads like Yoda speak (`A Type, variable is`) Since I am not familiar with Scalia, I am not sure why the types after the name would end up being more verbose, as far as I can tell the only difference is the : between the variable and its type. Would you mind expanding on that? Personally although Rust definitely does not have the elegance of Haskell or Python, I definitely would not call it ugly. There aren’t that many symbols and once you actually spend the time to learn the language the semantics for each syntax element are pretty easy to remember. I also have looked at D, but the lack of algebraic data types makes it a non-starter for me.
- thomastjeffery 6y ago> Type names after variable or before? When you think about declaring a variable, do you think about its type of name first? I can't imagine you do the latter because "Hmm, I need an array of doubles to represent my tensor" is double[][] tensor; and not tensor: double[][]. You can just as equally think of it as, "I need my tensor to be an array of doubles". That works much more cleanly with type inference, because the type is more of an annotation, and you can drop it without adding the boilerplate word "auto". > Subjectively ugly and polluted with punctuation symbols that tell you little about their semantics. Like what?
- e_y_ 6y agoFor reading code, which arguably should happen more often than writing code, having the variable name first makes it easier to find, since it's right near the beginning of the line and it's a single word. If the type comes first, I have to scan the line to figure out where the type ends and the variable name begins. Also, having "let" at the beginning of the line makes it immediately clear that it's a variable definition, whereas if it starts with some arbitrary type I haven't seen before I have to spend more time figuring out what's happening. Good syntax highlighting helps, but I think starting with types like C/C++/D is less elegant than starting off with a keyword that clearly identifies what the line does. Similar applies for function definitions. It's nice when the function names are all lined up and not buried halfway across the screen because it has some long return type.
- tastyminerals2 6y agoSubjectively, I see no point in having "val", "var", "let", "def", "fn" symbols which bring only noise to code. Why would you want to explicitly tell that something is a value while all you need to do is write its type and name? double[] arr; bam! Simple and clear. What about functions? It has input, name and output and D nicely presents you with double[] createArray(int size) {...} This is as little typing as you can get while keeping readability. And here is a basic Rust function fn add_one(x: i32) -> i32 {...} What kind of type is i32 btw? oh, there is u32 as well. integer 32bit and unsigned 32bit? What on earth are these? Ah, this is just D's size_t, the same size_t as in C/C++. So that C/C++ ppl have zero overhead reading D code and for Rust they will google. To top that, you have also -> because of the type after the definition scheme. Needless verbosity, same thing in Scala. What about Rust unable to drop parenthesis after a function? self.host_addr.clone() Should I mention Rust's UFCS? But I am nitpicking, right. This doesn't make a language bad in any way. However, as I said, Rust readability is pretty subpar in addition to already steep language learning curve.
- skocznymroczny 6y agoYou are nitpicking. size_t is architecture dependent, on x86 it will usually be 32-bit, on x86_64 it will be usually 64-bit. It's not equivalent to i32, u32 types. Also, I find i32 and u32 types much cleaner than D's "unsigned int" and "int". What is the difference between "unsigned int" and "unsigned long" in D? It's still better than C++, but I'd rather write i32 and i64 rather than "int" and "long".
- blackrock 6y agoThe elementary Rust syntax looks nicer. But once you start to do more intricate thing in Rust, then the syntax starts to look really ugly. I think this is where Rust falls apart. In things like C, more features requires writing more C code. In Rust, more features requires learning more syntax features.
- thomastjeffery 6y agoHow so? My opinion is generally the opposite, that simple decisions like putting type annotations after names, etc. make it so each unavoidable complexity in syntax has its own home, instead of piling together like C++/Java/etc.
- prirun 6y agoThis is one of the things I disliked about Nim. I spent a few weeks with it hoping I'd love it as much as Python. But there are quirks in the type system that seem rather baffling to me, and frankly, ugly. Like having to type integer constants with 23'i32 because 23 is an int and int is not compatible with int32 (nor is it compatible with in64!) There are typed integer constants in many stdlib sources too. In the tutorial, the language looks quite nice, comparable to Python. But in production level code, there are {.pragmas.} in a lot of places and they are not just advice for the compiler that can be ignored: they are important keywords that don't pollute the identifier space. Another beef I had is that slice ranges and for loops are closed intervals by default. This is contrary to both Python and C, and while there is a syntax a..<b to be open on the right, it seems like a bad decision to be different from C and Python by default. It reminded me of Julia arrays starting at 1 by default. I guess I can see that if your audience is Fortran programmers, but arrays haven't started at 1 in a new language for a long time afaik. I wish Nim had a goal of being a typed, compiled Python. But I don't think that ever was a main goal and now it's sort of too late because the language has a very wide scope (my opinion) and has compatibility concerns with all of its previous design choices.
- crazypython 6y agoI was thinking about making a language with Rust syntax that compiled to D. ("Compile your Rust programs 10x faster!") You can replace "let" with "const" to get transitive immutability in D with type inference. As a programmer who first used Python than C++, I don't find types after or before any nicer or worse. As for Monads, you could write a template that wraps a pure function that creates side effects through its arguments into a Monad rather easily. As for pattern matching, you can do that by writing your own template too.