4 ms·
In short: - being on JVM means Jepsen can use JDBC drivers to interact with databases - Clojure was designed to facilitate concurrent programming (via softwar
by koito17 3y ago
In short:
- being on JVM means Jepsen can use JDBC drivers to interact with databases
- Clojure was designed to facilitate concurrent programming (via software transactional memory and persistent data structures)
- Clojure's interactivity allows quick prototyping
- Clojure's community has a strong emphasis on backwards compatibility
- macros allow a great deal of code reuse
- while there are some big drawbacks (niche language, no strong static typing, ...), it isnt an issue in practice since Jepsen is only worked on by 1-3 people at a time
I agree with most of these points, but it seems overly simplistic of an explanation. I really wanted to see what other languages were used for prototyping and why they were deemed insufficient. For instance, Haskell is mentioned but the most treatment it gets is that it was too "dogmatic" for writing Jepsen. There was no comparison on how easy it is to interact with databases from Haskell as opposed to Clojure. Moreover, Jepsen was prototyped "in a few different languages", but they are not compared to Clojure, let alone mentioned.
- travisjungroth 3y agoBased on the title and intro, I think part of the point of this post was to have something to link to for a “good enough” answer to this common question. I’m guessing he wrote this relatively quickly. It was a choice made over ten years ago. Trying to recreate the decision would likely be rather time consuming, prone to mistakes, and really only invite more discussion.
- deleted 3y ago[deleted]
- fulafel 3y agoIndeed the protoyping takeaways would be interesting. It's quite rare in real world apps to prototype a system in several languages to pick one. From the text, to me it seems more likely to me that there were several prototypes for other reasons, and they might not be functionally or architecturally equivalent enough for direct language comparisons.
- aphyr 3y agoDB vendors generally don't write Haskell clients, which put a serious damper on my "test lots of databases for a living" project. Love Haskell as a language, but it's just not a popular target, and I wasn't brave enough to go for C interop. As I touched on in the post, Haskell is also rigorous about side effects--I've found it difficult to, say, inject side-effectual performance monitoring into an otherwise pure piece of code so I can profile it. Maybe Haskell experts are better at this, or the story is better now. There was a Ruby version of Jepsen too. That enjoyed better library support and language flexibility, but it suffered from terrible performance, a standard library built for mutability, and a janky thread model. There was, at the time, essentially no way to reliably time out a Ruby thread. That was a dealbreaker all in itself. I wrote some of Jepsen in Erlang too, but abandoned the project quickly. It's got a really good concurrency story. A VM designed for concurrency and failure with bounded reduction queues--honestly this is something I miss in the JVM. I love Erlang as a language (and I think some of my Erlang might still be in prod!) but it also suffered from a lack of client support, not being well-suited for high-speed mutable state, and generally terrible string manipulation. There's a lot of strings in Jepsen. ;-)
- travisgriggs 3y agoCame here to ask about Elixir, since the opener requirements of your post kind seem like a sales pitch for the things OTP people get excited about. This last bit answers that though I think. Thanks.
- koito17 3y agoSo you tried Haskell, Ruby, and Erlang, and each had their own deal breakers (database clients, threading, controlling side effects, etc). This is all worth mentioning in the article IMO. I love using Clojure, but I will admit that the article left me wanting an explanation just like the one you've provided here. Thanks for taking the time to respond!
- asa400 3y agoJust to add an additional anecdote/perspective for other folks curious about the Erlang mention: the lack of client support in Erlang/Elixir is real, unfortunately. Just an artifact of it being a smaller ecosystem, but it's improving all the time. You can do mutable state manipulation in Erlang/Elixir through a few mechanisms - ETS tables is the main one - but it's not "high-speed" in the sense you find in C/Java/Rust/etc., where you want to bash on a slice of mutable, contiguous memory containing primitive (word sized/aligned) values. It's also a bit awkward, as ETS tables are more like having Redis inside your application than they are an actual collection type. Regarding string manipulation, strings in Elixir are actually quite good. This is one of Erlang's sore spots that Elixir improved upon. I'd put Elixir's string manipulation facilities up against anything I've used, including Java and Clojure. And +1 to the point about Erlang's concurrency story. If you have a highly concurrent problem, Erlang/Elixir really is best in class. It isn't a perfect technology by any means but it really is as good as everyone says it is.