Coming from the Clojure world, every time I read about about Elixir, the similarity of the two langauges' values always surprise me: immutability, macros, dynamic and gradual typing, concurrency, and on.
I've yet to touch Elixir (or Erlang, for that matter). Does anyone have experience using both? Thoughts? Has anyone crossed from one language to the other over any strong preference?
I have used both (though Clojure less). I have not built distributed applications in Elixir yet, so I do not focus on those features in this comment. I prefer Elixir because:
1. My brain thinks in terms of editing lines, not s-expressions; I didn't get the hang of paredit, and editing without paredit required really tedious edit operations.
2. Elixir's understanding of types matches Erlang's and the host VM, while Clojure invents its own uni-typed IObj but runs on a typed VM. Interop with Java required adding type annotations. Elixir/Erlang interop seems to be almost entirely pain-free.
3. Elixir has a lot of syntax niceties like triple-quoted strings that automatically remove indents. And pattern matching everywhere.
4. I can feasibly (and in fact, have) audited and built all of my Elixir and Erlang dependencies from git repositories, while doing the same with the Maven dependencies needed for a typical Java project would be almost impossible. I wouldn't even know where to begin with bootstrapping all the necessary Maven plugins.
5. Elixir/Erlang has per-process garbage collection and memory limits, though I haven't taken advantage of these yet.
> My brain thinks in terms of editing lines, not s-expressions; I didn't get the hang of paredit, and editing without paredit required really tedious edit operations.
In my experience, learning and then working in Common Lisp, starting with paredit is tough. I disabled paredit for a while until I got the hang of thinking in s-expressions as you say. After a while when I tried paredit again, it was glorious.
Early on I did set up % as a global key that goes to the matching parenthesis if on parenthesis, and otherwise inserts the character typed.
I use Vim for editing Lisp. Basic :set lisp mode that dates back to ancient Unix implementations of vi and the % command for jumping between matching parentheses. In Vim, selecting a range and typing = re-indents it, and == indents the current line. I set shiftwidth to 2. When I need to move the indentation of a whole block I use select and < or >. Or << and >> for the current line. With those basics, I comfortably do 95% of all Lisp editing.
For instance to move an expression: put cursor on one parenthesis, type v for visual select, type % to jump to the other paren, then x to delete. Move somewhere, p to paste. Adjust formatting here and there, done.
I edit C and other languages in pretty much exactly the same way.
> Has anyone crossed from one language to the other...?
Yes, I've been doing Clojure for maybe four years, and picked up Elixir over the course of 2016. Frankly, I think I'll be preferring Elixir over Clojure for most tasks from now on.
The concurrency/parallelism story in Elixir/Erlang is just so much better than Clojure, or honestly anything else. (I'm talking about OTP and Supervisors here, but even the bare Process system is nicer than working with Clojure's CSP implementation)
Plus, because Erlang is also a functional language there isn't any Functional/OOP friction when interfacing with the native VM or with Erlang libraries. It's turtles all the way down, which I really appreciate after many times getting stuck in the mire of Java/OOP that lurks beneath the surface of Clojure.
Oh, and Phoenix blows any of the Clojure web systems out of water. It's awesome.
> Oh, and Phoenix blows any of the Clojure web systems out of water. It's awesome.
Are you referring to performance, or api design? In clojure there is almost no http apis by design, you're supposed to hook a library that follows the ring spec so it's not a nice comparison imho.
Right, and that's the bit I'm not keen on. You either end up with a totally bespoke stack of libraries for each project, importing the same boilerplate for basic things like csrf-protection, or you have Luminus vomit a bunch of code on disk and then you have to pick through the project and get rid of the stuff you don't want.
Then you realize that much of the code in the Luminus scaffold is managing state with mount (used to be with Component), and that's just a poor imitation of OTP from the Erlang world.
I dunno, I've been there, done that, and wasn't so fond of it. Phoenix, by contrast, strikes me as the right balance of lightness and pragmatism, with first-class support for managing stateful resources in a sane way (OTP mofos), and all the right defaults so I can be productive from day-zero on a new project.
[EDIT: to clarify, the Clojure way isn't _wrong_, and I do see the merit, but in my experience I prefer how things work out with Elixir and Erlang]
I was very interested in Clojure and studied it for awhile. I liked it a lot, but had a difficult time becoming proficient with it. Part of it was the tooling (I tried learning Emacs and Clojure simultaneously when I should've only focused on Clojure), but my biggest hurdles were the syntax and understanding the error stack traces. They just seemed way too opaque. This really slowed down my progress. On the flip side, when I picked up Elixir, I became productive very quickly. Studying Clojure actually helped a lot here because I was familiar with functional programming and immutable data, but Elixir's familiar syntax and easier to understand error messages made it much easier for me to grok. I've since built a few things in Elixir and have been very happy with it.
It's not a coincidence, Clojure was a big influence on Elixir... I think actually it's a bit of a funny parallel with Ruby, I know Matz has said the biggest influences on Ruby were Smalltalk, Lisp (or eLisp via Emacs) and Perl, and Elixir has a similar relation to Ruby, Clojure and Erlang (I think Jose has talked about this somewhere also).
I spent a few weeks with Closure about a year ago. To be honest, Elixir is much more pleasant to work with. However, I might be biased as my main lang is Ruby...
You still have to bend your thinking, yet, you feel that you become productive much faster.
I've yet to touch Elixir (or Erlang, for that matter). Does anyone have experience using both? Thoughts? Has anyone crossed from one language to the other over any strong preference?