3 ms·
One thing that jumped out at me is you don't need Rust's borrow checker to prevent thread race conditions because data in Clojure is immutable. That's a huge si
by labrador 11mo ago
One thing that jumped out at me is you don't need Rust's borrow checker to prevent thread race conditions because data in Clojure is immutable. That's a huge simplification over Rust. What I hear mostly about Rust is complaints about the borrow checker. I wrote a simple Rust utility and found it frustrating. But again, don't take my word for it because I don't know either language.
- deleted 11mo ago[deleted]
- bmitc 11mo agoI would argue that F# would be the choice of language in place of Rust if you don't want to deal with Rust's type system. F# is immutable by default with good concurrency and a static type system.
- labrador 11mo agoThat's a great suggestion I had forgotten about, which is strange since I'm a C# programmer. Part of me wants to really learn a Lisp to see what it is special about it that I keep hearing about. I tried Racket and Steel Bank Common Lisp but they didn't seem appropriate for the commercial programming I'm used to. Clojure is being used commercially.
- bmitc 11mo agoI also really like Lisps/Schemes. I've always wanted to pick up Clojure but don't like how it thinly sits on top of the JVM compared to F# being deeply integrated. I always had trouble getting Clojure properly installed compared to just downloading .NET and having F# or easily downloading Racket. You should absolutely try out F#. :) It's a great language. Also, if you're looking for the magic of Lisp/Scheme, I think you might really enjoy Elixir/Erlang. Elixir has macros, has purely immutable data (there is _no_ way whatsoever to get mutable data unlike F#, Racket, Clojure, etc.), live code updates, and the BEAM VM, its process framework, and OTP are quite magical. When I first learned Erlang, I felt I had come home. I mainly used Elixir though due to the available packages and jobs.
- labrador 11mo agoThe late great Joe Armstrong is missed! Good suggestion, I will take a look at Elixer/Erlang. It's the least I can do for the laughs Joe gave me in his videos.
- macintux 11mo agoShameless plug if you like videos: I gave a talk about Erlang, building the language (focus on semantics, not syntax) up from the fact that the = sign doubles as a runtime assertion. https://youtu.be/E18shi1qIHU https://youtu.be/E18shi1qIHU Joe was indeed a great guy. I was lucky enough to spend some private time with him when he was visiting Chicago to give a talk, a true renaissance man with wide-ranging interests.
- labrador 11mo agoGood talk! I didn't believe that Go example was real at first. A bit strange. I always think of Alan Kay's message passing objects when listening to descriptions of Erlang and tonight I also thought about Kubernetes pods. The other thought is one you touched on is that some systems are monolithic so you have to handle errors. Thanks, I enjoyed that.
- bmitc 11mo agoThis would be the Elixir talk I'd watch to get excited about it: https://youtu.be/JvBT4XBdoUE https://youtu.be/JvBT4XBdoUE
- asa400 11mo agoAs someone who has gone deep into both functional programming (with Elixir, Clojure, and Scala) and also Rust, they solve the same problem in different ways with different tradeoffs. The problem is that shared mutable state is incredibly hard to get correct, especially when concurrency enters the picture. Elixir and Clojure sidestep the problem by making copying data so cheap that instead of sharing references to mutable data, you make all data immutable and copy it whenever you want to change it in some way. (Which is a classic technique: don’t like the problem? Solve a different problem that sidesteps the original problem in a creative way) So you have a lot of functions of roughly the shape `f -> f` (return a new thing) instead of `f -> ()` (mutate a thing in place). This possible at all by the clever use of some novel data immutable structures like HAMTs that are able to approximate the performance of traditional mutable data structures like hashmaps or arrays while presenting an immutable API. As it turns out, this is a much easier programming model for most of us to get correct in practice (especially in the presence of concurrency) than sharing mutable state in an imperative programming language like C or Java or Python. The tradeoff is that the immutable functional data structures actually do have a some performance overhead. In most domains it's not large enough to matter, but in some domains it is, and in those domains you really do need mutable state to eek out that last bit of performance. Which is where Rust comes in. In Rust's model, data can either mutable or shared, but not both at the same time. The Rust compiler computes the lifetimes of data throughout your program to ensure that this invariant is upheld, so mutable data is not shared, and shared data is not mutated. The downside of this is that you have to internalize these rules and program to them. They can be tough to learn and tough to program with even after you have learned them, though it does get much easier with experience, I will say. The upside of Rust's model is that you can have your cake and eat it too: you can keep the high performance ceiling of a true mutable data model while maintaining memory and resource safety. In short, you can think of Clojure/Elixir as sidestepping the shared mutability problem at the cost of some runtime performance (though again in practice it is smaller than you would think), and Rust as tackling the shared mutability problem head on by transferring the cost of solving the problem to a more complicated compiler and a harder-to-learn programming model. These are just my opinions having used both Rust and the immutable data functional programming stuff in anger. I'm not trying to present one as being better than the other, the key point is that they're both better than what came before.