Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Elixir is one of those languages that changes you. I realize its a ruby flavored wrapper on top of erlang but I don't care. Coming from an OOP/C based language background, it took me a while to get it. Implicit returns? Immutable data? Pipes?? No inheritance??? No for loops????? And all thats just if you use the phoenix framework which maps pretty analogously back to a standard web server flow. Once you start digging into Supervisors and umbrella projects, the top of your head will get blown clean off. It's a hell of a drug.

I am glad to hear there are more companies out there giving it a try. Any time I see a job posting for a company that uses it, I give them a hard look. It tells me that they are a) hiring people who are of a certain mindset (see the python paradox[0]) and b) they understand the competitive advantage that using a language like Elixir can bring to the table.

[0] http://paulgraham.com/pypar.html



I'm a Ruby guy and I'd love to feel what you're feeling. Where should I start / what should I check out? Bonus points for concept walkthroughs and materials designed to bring Ruby folks up to speed, specifically concepts that need to be temporarily forgotten or unlearned in order not to get sad.

I like being a polyglot, but my schedule is tight enough that I need to hit the ground running or else I get pulled back to reality pretty quickly. There's a lot of posts and videos out there on Elixir, so curators are incredibly awesome in my world.


Start here --> https://elixir-lang.org/getting-started/introduction.html

You will start feeling the magic around chapter 4 with pattern matching and the rest gets just better :)

Try not to migrate your "how to .." thoughts from other languages into Elixir. It has some uniqe ways to solve everyday problems.

Have your interactive elixir console ready to play with as well, good luck!


Pattern matching will break you.

I get frustrated at least once a week trying to use it in a language that doesn't have it. My brain just thinks in pattern matching!


It's unfortunate when I encounter a language that has a crippled implementation of pattern matching (looking at you, Scala). After using Erlang, it's hard to accept anything less.


How are F#'s and OCaml's implementation of it, in your opinion?


I’ve not tried either, although in my limited exposure to SML it seemed fine.

The other related feature whose lack I regularly lament in most languages is multiple function heads, which apparently is rarely used in the ML family tree, bafflingly.


I haven't heard the term "multiple function heads" - is it similar to Haskell's way of defining functions? e.g.

    fib 0 = 0
    fib 1 = 1
    fib n = fib (n-1) + fib (n-2)


Yeah, this is Erlang:

    fib(0) -> 0;
    fib(1) -> 1;
    fib(N) -> fib(N-1) + fib(N-2).


But these are all compiled into, essentially, a giant case statement. It’s a syntactic sugar. Your last line is missing a dot at the end.


Concise code is its own reward. Yes, it's syntactic sugar, but there's a reason syntactic sugar is valuable.

Even if performance is the same, you wouldn't prefer this Javaesque code:

    Int.from(8).multiply(5)
You'd use `8 x 5` were it available.

Several discrete function heads are easier to mentally parse than a long case statement because you know without a shadow of a doubt that there's no code in the function above or below the case statement, and you always have all relevant bindings directly adjacent to their usage.

Consider this Erlang code:

    f(X, Y) ->
       case X of
          {1, 2} ->
              low;
          {2, 4} ->
              high;
          {3, 6} ->
              Y
       end
    end.
When you get to the 3rd case statement and `Y` appears, it's jarring because it was declared several lines removed.

Instead, this code makes it explicit for each function clause that we don't care about the 2nd argument, and when we do care, it's immediately obvious where it came from.

    f({1, 2}, _) ->
       low;
    f({2, 4}, _) ->
       high;
    f({3, 6}, Y) ->
       Y.


Yes, I agree with your point, I've written plenty of Erlang.


Exactly. I don’t know what the typical industry term for it might be.


Multiple Dispatch / Multimethods (I think?)


Interesting, it appears that multiple dispatch is accurate. Thanks.


Pattern matching!


No, it relies on that, but the creation of multiple function clauses via different matched heads itself isn't simply pattern matching.


What's wrong with Scala's pattern matching?


I shouldn't have said "crippled." It's just much more limited than when used in Erlang.

From digging a bit it appears to be somewhat the JVM's fault[0] and quite a lot of it is simply that it's a different type of language from Erlang.

In Erlang, nearly every line of code involves pattern matching, regardless of whether the developer takes advantage of it or not. Every assignment statement, every function return, every function parameter, is an exercise in pattern matching. It's at the core of the language, not an add-on.

As I mentioned in another comment, a closely-related feature that really shows it to its full advantage is multiple function heads/clauses.

[0]: https://www.scala-lang.org/old/node/11982


OK, I also don't like Scala's inability to deconstruct in the parameter list. I come from an ML background where that is possible. But I found it less bothersome in practise than I had originally anticipated.

Erlang has pattern matching on bits [1] which is convenient, that would be nice to have, especially when writing networking software.

[1] P. Gustafsson, K. Sagonas, Efficient manipulation of binary data using pattern matching.


Good point on the binary pattern matching. I’ve rarely used it, but it is quite powerful.

I was pleased to discover Python’s tuple pattern matching in function heads, only to be disappointed that it was removed in Python 3.


You are completely right. I work mostly in TypeScript and JavaScript for day to day and I miss pattern matching so much. Object de-structuring is nice and all but once you've seen the possibilities in a language where its a first class citizen... everything else just seems inadequate.


It's getting there for us in JS land, slowly but surely! There's still a lot of discussions that need to happen (read as "mostly bikeshedding" IMO), but once they settle on the actual syntax, i'd feel comfortable to start using it with compilers.

https://github.com/tc39/proposal-pattern-matching


Awesome! Thanks so much.


No problem at all! I am also a ruby guy, so i can easily say that Elixir will not disappoint you.


I'm kind of a ruby guy, and I started with the elixir intro from their website. Very clear and well documented. Then I built a website using Phoenix and learnt through that.

Docs in elixir are first class citizen, so everything is very well documented. And just like in ruby/rails land, any question you may google will return a lot of high quality posts with answers!


Highly recommend this: https://codestool.coding-gnome.com/courses/elixir-for-progra...

I think it's probably the best way for an experienced programmer to get up to speed on idiomatic Elixir, why you do certain things, etc...


+1 on this.

The coding-gnome is the first tutorial that explained OTP, Supervisors and GenServers at a level that helped me understand how to actually use them.

Afterwards, official Elixir Documentation also became much more readable and understandable to me. Before that point, some things just seemed to arcane because my understanding of OTP was wrong.


The official docs for Elixir or Phoenix framework go a long way. One thing that sticks out above the rest for me is Elixir koans[0]. They’re extremely rudimentary but I think the project showcases Elixir’s hot reloading if I’m not mistaken and it’s very fluid. Other follow along courses may have taken this approach but I was extremely impressed by how everything fits together.

[0] https://github.com/elixirkoans/elixir-koans


"The gateway drug" IMO is the Phoenix framework. It models cleanly to much of what you already know as a Ruby dev. The creator, Chris McCord wrote a book [0] for it that is one of the most well written programming books that I've come across. Chris does a fantastic job of making the information accessible and understandable. You learn by building an app of substance and apply all the concepts that make phoenix a wonderful web framework to use. Towards the end, Chris starts easing you into some of the more "hardcore" concepts and gives you the opportunity to use them on the project you are building throughout the book. That level of quality just seems to permeate the ecosystem as a whole. Others on here have made the point that the waters might start getting muddied as it gets more popular but I've had nothing but great experiences so far and would love to see it really take off.

[0] https://www.amazon.com/Programming-Phoenix-1-4-Productive-Re...


I found the Programming Phoenix book to be quite nice because it similar to Hartl's Rails tutorial. Seeing where and how the two differed was very useful.


Elixir in Action from Manning, and all of the PragProg books are great


Funny how that pg post has aged. Now python is the language you learn if you want to get a job.

What’s the new python?


Rust, ClojureScript, Clojure, Racket, Elixir, Elm, Reason, OCaml, Haskell


I would add Nim to this list, just after Rust


Also, Java and C++, even if they are "only" used at a "few" companies that happen to have the hiring power of 1000 startups each.


OCaml? Someone other than Jane Street is using OCaml?


I think the Reason syntax is picking up a lot of steam these days, especially in areas where React is used (web frontends and ReactNative apps). You can see some of the companies using it here https://reasonml.github.io



Rust, maybe. I'm not particularly leading edge myself, so I've heard of it but never actually tried it.


Yep. The last time I picked up a language it was python. It lived up to much of what I had read. I've ignored most languages and watched them come and go with the exception of web dev which is not my thing. I wanted a better more pythonic C++ and have started dabbling in Rust. It appears to be everything people say. Would recommend.


golang


JavaScript.


No loops? That can be life changing.


If you’re wondering: Erlang (and so Elixir) has a very “pragmatic” design behind its abstract machine/runtime; it’s not like the lack of loops is to be functionally pure or anything.

They remove loops in the Erlang abstract machine so that there are only ever O(1) instructions executed between each function call (where a tail-recursion is considered a function call.) With this constraint in place, the runtime can get away with a hybrid of cooperative and preemptive scheduling called “reduction scheduling”, where functions only ever yield when they make a function call (or return from one.)

By ensuring every function body has O(1) “reductions” before it hits a CALL or RET op, the runtime guarantees (unlike cooperative scheduling) that execution will always yield from a task in a bounded amount of time; and by ensuring yields only happen at call-sites, the runtime ensures that (unlike preemptive scheduling) there is no register state to preserve at time of yield—all the scheduler has to record when it pauses a task is the thunk (function pointer + parameter list) for the call it was about to make.

Together, these guarantees allow for extremely low-overhead context switching between tasks in a soft-realtime context.

Other systems (e.g. .NET’s Orleans) simulate this hybrid approach by splitting code into state machines with explicit yield points being the state transitions. But AFAIK, only ERTS takes the approach of making function calls into the state transitions. (Because, without the no-native-loops constraint, such an approach doesn’t work at all.)


Recursion is the way to go in Erlang / Elixir: https://learnyousomeerlang.com/recursion When one writes a bit if Erlang for a while, one gets a completely different view on any software to be written in the future. Erlang is life changing. But there are things where other technologies are better fit.


> Recursion is the way to go in Erlang / Elixir

I think it's important to realise that they're different ways of writing the same thing. For example, in Lisp, the 'do' operator is basically a C-style for loop: in Scheme, it's a macro over tail recursion, and in Common Lisp, it's a macro over gotos, but it provides an almost identical interface to programmers. Using recursion over loops is just a stylistic/syntactic choice, the really important part is understanding how recursive functions are equivalent to loops, and vice versa, so that you can apply your experience in one situation to the other.


Hence I said “in Erlang / Elixir”. Because, really, in those two, recursion IS the only way to go.


I don't know Elixir, but I do know Erlang (one of Elixir's inspirations). The lack of loops is replaced by recursion or higher level functions. Tail calls (all, not just recursive) are optimized so that you don't blow the stack. Since the two (iteration and recursion) are easily transformed into the other, it's a pretty clean mode of coding.


You can sort of loop in Elixir eg.

Enum.map(1..100, &IO.puts/1)

prints the numbers 1 to 100


Well, there is also a `for` construct:

for i <- 1..100, do: IO.puts(i)

I guess what people mean is that that’s an abstraction over function calls?


> No loops? That can be life changing.

I doubt it would be for someone from a Ruby background, where higher order functions already generally replace built-in loops.


As someone who's done a bit of Rust, I'm starting to see its influences just reading that list of features.


It looks to me like Elixir is just doing the same things most other functional languages are doing.


The language itself is a fairly typical FP, but only if you disregard the VM it runs on and the OTP framework.

As I've frequently said about Erlang, the language is much more powerful than the sum of its parts. There are a great deal of complementary features in the stack.


It is really the BEAM that is most compelling, Elixir is a great language on top of it, but the VM provides tools that simply don't exist in most other languages, if any. Specifically things like runtime tracing with pattern matching, the ability to connect an interactive remote shell to a running system and poke at it using code, ETS/Mnesia, hot upgrades/downgrades, etc.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: