4 ms·
> Clojure solves the same problems Rust solves in a much simpler way I'm curious about that, can you elaborate? I'm a beginner in Clojure and I only know a fe
by lucasoshiro 1y ago
> Clojure solves the same problems Rust solves in a much simpler way
I'm curious about that, can you elaborate? I'm a beginner in Clojure and I only know a few concepts about Rust, but it seems to me that they solve (at least, currently) very different problems...
I only saw Rust being used in places where C or C++ would be used in the past (Linux kernel, CLI apps, desktop apps), while I only saw Clojure being used as a modern and functional Java and JS replacement.
Not to mention how different they are as languages (static vs dynamic typing, native vs jvm, borrow checker vs garbage collection)
- labrador 1y agoOne 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 1y ago[deleted]
- bmitc 1y 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 1y 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 1y 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 1y 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 1y 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 1y 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.
- 1y ago
- asa400 1y 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.
- Zambyte 1y agoThe main problem that Rust tries to solve, and that functional programming (which Clojure heavily leans into) solves, is avoiding shared mutable state, which leads to data races and (potentially subtly) wrong concurrent programs. Functional programming avoids shared mutable state by avoiding mutable state. Operations are only represented as transformations instead of mutations. Other languages like Erlang / Elixir use message passing techniques like the Actor Model to avoid shared mutability. Instead of avoiding mutability, like in functional programming, in the Actor Model you avoid sharing, by instead sending messages around. Rust is interesting because it solves the problem of shared mutable state, while allowing sharing, and allowing mutability, just not at the same time. State can be mutated until it is shared. While it is shared, it cannot be mutated. This is the goal of the ownership system in Rust.
- SkiFire13 1y ago> The main problem that Rust tries to solve, and that functional programming (which Clojure heavily leans into) solves, is avoiding shared mutable state I would argue that avoiding _unrestricted_ shared mutable state is a mean for Rust, not a goal. The main goal would be to provide a way to make safe, fast and non garbage collected programs, which doesn't seem at all what clojure is aiming for.
- pjmlp 1y agoAs proven by ongoing research in things like Linear Haskell, one doesn't need to throw GC productiviy away, to get deterministic resource management. Best part of Rust is catering to a crowd that not even at point gun will consider touching anything that might resemble having any kind of automatic resource management. Hence why I consider articles like "How We Saved 70% of CPU and 60% of Memory in Refinery’s Go Code, No Rust Required" [0] interesting to read and make awareness, even if Go isn't one of the languages I happen to be entusiastic about. [0] - https://www.honeycomb.io/blog/how-we-saved-70-cpu-60-memory-refinery https://www.honeycomb.io/blog/how-we-saved-70-cpu-60-memory-...
- codesnik 1y agoWell, erlang and elixir operate on almost exclusively immutable data, in addition to message passing between "processes". They are more strict than most other languages in that regard.
- jimbokun 1y agoThis the “non-low level” code qualification.