|
C++ is a beaut', compared to Perl. It's ugly too, don't get me wrong. I'll be the last one to hold up C++ or PHP as beautiful, but Rust is just too gross to look at, I have NO idea how people program in it. I think the only thing Rust has really brought to the table is the idea that alternative memory schemes like ownership can be valuable. That idea will slowly disseminate into Python/Ruby, and other languages from there, and those of us who appreciate beauty will continue to program with proper tools. I'm actually looking into Ocaml lately. The 5.0 release is really interesting, and the next release of OPAM will have proper Windows support and everything. Rust takes a lot from Ocaml, as I understand the original compiler was written in it, and inspired by it. I think mutable shared state is bad, as you do, but I think so less because of the advantage that a tool like Rust or Erlang brings to the table in handling that state, and moreso because of the programming practices it brings about regardless of the language. Treating a session as stateful, or really treating any io-capable object as mutable is definitely a big mistake. That much is clear. I think as the years go on, more languages will embrace this wisdom and replace Rust's incredibly rigid and unfriendly experience with things like proper object capability systems, effect handling, and whatever instruments would be useful from formal verification methodology. And again, all of that could conceivably land in Python/Ruby eventually, or as extensions, whatever. I guess what I'm saying is that over a long enough timespan, it would seem that ideas are always going to win out and language designers will slowly advance towards that front, while retaining beautiful code. It's interesting that you mention Clojure, because a lot of really cool ideas bouncing around the Ruby/Python sphere originated or at least came to widespread popularity in Clojure. I'd put Erlang up there as equally influential as well. Clojure also shares the feature of highly-writable and highly-readable code, which qualifies it for beautiful, imo. How often do you come across a Clojure function that's just cluttered with {}{}<T><T><<T>RefCell>(); bullshit, to the point where it's not immediately clear what is happening? Now, compare that with Clojure. If ever there's a complicated Clojure function, I'd wager that it either a) deals with Java interop, which, God bless you. or b) is just a highly abstracted function, and can be grokked by walking backwards up the calls one-by-one. Terseness can be daunting, but it's almost always a simple case of gathering context to understand those functions ending in )))))})). Anyhow, I've wasted too many bytes here. Since you've a decade in Ruby, have you tried Crystal at all? I heard about it last year sometime, but was turned off by no Windows support. |
Even everyday decisions like whether to copy an array passed to a constructor can be fraught with danger. Is the caller going to retain a reference and mutate the array after I check invariants? This simple yet intractable problem lurks in every imperative language except Rust.
Channels in Go are another great example. CSP is a sound approach for safe concurrency, yet the Go language offers no assurance that references passed over a channel are exclusive to the receiving goroutine.
I don't see how languages like Ruby or Python or Go could incrementally add a borrow checker. It would break too much. Returning to other programming languages after internalizing Rust compiler warnings is really eye-opening.
I have not tried Crystal. I also haven't written OCaml, though I did dabble in F#. Rust's match expression was definitely inspired by OCaml.