5 ms·
I can accept the braces, but the semicolons were a big letdown for me. We should have learned by now from successful languages that the semicolons is obsolete.
by lobster_johnson 14y ago
I can accept the braces, but the semicolons were a big letdown for me. We should have learned by now from successful languages that the semicolons is obsolete.
If Ruby can do it (and Ruby does it very well with just a few simple rules, even though its lexer admittedly contains parsing logic to deal with the challenge), then Rust can do it.
The other disappointing aspect of Rust is the "line noise" problem. Rust has three types of pointers, and needs a line-noise character for each of them. That, combined with the liberal use of underscore-based identifier names, makes it very noisy. (Ruby also uses underscore-based names, but the relative absence of noise characters keeps it clean.)
In my opinion any new language project ought to have an overriding aesthetics process. Aesthetics is often belittled (as you say, "childish"), but code readability, over time, becomes more important than almost everything else.
I like Rust's design principles, but Go definitely wins the syntax competition for me.
- pcwalton 14y ago> Rust has three types of pointers, and needs a line-noise character for each of them. `~T` and `@T` were felt to be preferable to `std::unique_ptr<T>` and `std::shared_ptr<T>`. You really do type them all the time.
- lobster_johnson 14y agoI understand that. That's not the alternative I want. Go actually gets by with just one type of pointer syntax. Go is what a colleague calls "being stupid simple", which is really its strongest asset at this point. It eschews a lot of complexity by not trying to be clever. The problem with Go's pointers is that no thought has gone into thinking about goroutines as boundaries of data ownership. It's simple to share mutable data between goroutines, and it's impossible to verify (manually or by any kind of analysis) that a program is not a shared-everything pile of spaghetti. This, plus mutable data, makes it impossible to safely implement things like Erlang-style remote task spawning. What I would like in my ideal language is a single pointer type: A pointer into the task heap. However, pointers may only be shared between tasks by copying or by transfering ownership, except for immutable data, which can be shared freely with no overhead other than normal GC/refcounting. With some COW magic you could even make the copying really fast, too. Then all you need is a simple syntax for limited references that cannot be stored, only copied, so that you can actually have functions that work on data efficiently without leaking their pointers anywhere. Maybe I am being naive -- I won't pretend to be a Rust expert. But this model works pretty well for Erlang. I find that while Rust is clever, it falls into the other extreme and becomes too clever; and being too clever is a kind of stupidity. For example, borrowed pointers sound neat on paper, but then you find you have to dick around with declaring pointer lifetimes. That's pretty insane. It results in a kind of syntax that represents everything I hate C++ for. I can understand that it took a while to decide on a syntax for declaring lifetimes. It looks totally weird and arbitrary. (Quotes are for strings, man!) It's also possible that Rust just is not for me. :-)
- pcwalton 14y agoI would also like it if we could just copy everything, but for implementing a competitive browser this gets really hard really fast. Erlang's actors are not really designed to squeeze every cycle out of the hardware. Incidentally, you can get this model with Rust's `flatpipes` module, which allows you to send data across Rust. We experimented with COW designs in the early days. It seemed pretty hard to implement: hardware MMUs operate on page granularity, not on object granularity, so you need (thread-safe!) guards for all objects. That's pretty tough from a performance point of view. Perhaps it can be done, but it seemed less risky to just use uniqueness.
- lobster_johnson 14y agoIndeed, the types of programs I write are very different from a web browser. For what it's worth, I know I speak for at least a couple of other people when I say that we were, for a long time, hoping for a "better Go" -- we are mainly rubyists who want native compilation, a better/safer type system, better concurrent performance, more easily massively parallelizable -- and that Rust's development has been going in a slightly different direction than we were hoping. Perhaps it's time to re-evaluate C++11 or even Haskell.
- kibwen 14y agoAside from the native compilation bit, could Elixir be the language that you're really looking for? http://elixir-lang.org/ http://elixir-lang.org/ Speaking personally for a moment here, I'm a Python/Javascript/PHP dev by day, and the reason that I'm interested in Rust is precisely because of all the new concepts that it's forced me to learn. I could never get into C because I enjoy having two feet, and I could never get into C++ because I know that there's no escape from that stygian pit. For me, Rust is precisely the right balance of low-level/safety/coherence, semicolons be damned.
- lobster_johnson 14y agoElixir is neat, but it's such a leaky abstraction; you still have to deal with a lot of Erlang stuff that Elixir doesn't cover. Also, Erlang is slow. Really really slow. It's faster than Ruby, I think, but not much. And It sucks at a lot of things that should be fast in a functional language, such as file I/O. Erlang itself is also neat, but the syntax is abhorrent (commas and periods instead of semicolons!), performance is awful, and the language has many warts (no Unicode, no structs, etc.). I see where you're coming from. As for me, I am intimately familiar with everything that Rust provides, and it's frustrating because it's close to what I have been waiting for, but it makes a bunch of design choices I disagree with. Same with Go. For now, Go is much closer to what I want than Rust, but performance is pretty awful for many things, so I'm not a happy clam.
- stesch 14y agoThe characters for the different pointer types remind me a little bit of the Hungarian notation. And I thought this is a bad idea.
- kibwen 14y agoIt's not Hungarian notation, the sigils are part of the type. Here's how you'd say the same thing in Rust and C++: Rust: ~T C++: unique_ptr<T>
- lightcatcher 14y agoAre you aware that the semicolon is meaningful in Rust because it indicates returning from a block (as well as separating expressions). mitsuhiko (author of Python's flask, jinja2, etc) wrote about why he loves Rust's semicolons: http://lucumr.pocoo.org/2012/10/18/such-a-little-thing/ http://lucumr.pocoo.org/2012/10/18/such-a-little-thing/
- lobster_johnson 14y agoYes. And I really dislike that there is a difference. The semicolon is so small and what the block returns is so important, it's a really weird thing to love.
- lobster_johnson 14y agoSince I am being downvoted for expressing a technical criticism, let me clarify: I like explicitness, readability and clear, unambiguous syntax. Two small dots at the end of a line completely changing the entire block's meaning is, to me, a violation of those principles.
- kibwen 14y agoMy own immediate reaction upon first reading the Rust tutorial was that significant semicolons were completely brain-dead. However, time went on and I was never able to think of a scenario where the compiler wouldn't immediately detect an errant or missing semicolon. Nowadays I completely adore them (though I still recommend that people use an explicit `return` in any expression of nontrivial length).