9 ms·
Towards a better Erlang - The Excitement of Elixir
- saraid216 14y agoSo... what's the catch? Can someone provide a devil's advocate against picking up Elixir? I've been working at learning Erlang, but it's been a challenge and Ruby's syntax was a first love, so Elixir sounds ideal for me and I'm tempted to try it. It just... can't be as good as the hype. So I'd like some earnest objections to Elixir, especially if they're answered objections.
- devinus 14y agoAuthor here. If Erlang's community is small, Elixir has an even smaller community. Elixir did just recently rise to the #56 most popular language on Github[1] from #57 however, so it's on the rise. [1]: https://github.com/languages/Elixir https://github.com/languages/Elixir
- josh2600 14y agoDevin, Are there any negatives in Elixir that are not present in Erlang? Thanks for the awesome writeup. These pieces which take current writings and pair them with real-world answers are great.
- devinus 14y agoIn five months of working with Elixir, I can only think of one issue I've had that's related to importing Erlang records with functions as a default value. Even then, the issue is being thought about[1] and there's already several workarounds. Issues are resolved quickly and Elixir releases happen often. [1]: https://github.com/elixir-lang/elixir/issues/554 https://github.com/elixir-lang/elixir/issues/554
- josevalim 14y agoI am Elixir creator. There are a few downsides comparing Elixir today with Erlang. First, there are all trade-offs related to Elixir being a new language: we have fewer resources and a smaller community. Fortunately, Elixir community is growing very active (on IRC) and it is very likely you get some support on whatever you are tackling. Also, we haven't reached 1.0 yet, which means backwards incompatible changes may happen, but we do our best to properly deprecate them first. Regarding the language features, since Elixir provides a macro system, you can apply to Elixir some of the same complaints people would apply to Lisp and meta-programming in general: i.e. people can definitely go overboard and write code that is hard to read and maintain ("magic"). On the other hand, Erlang does not provide macros and has a set of restrictions on how your code looks like (only one module per file, module forms cannot have custom expression, etc). At the end of the day, it boils down about Elixir giving you more power, but also requiring more responsibility from you to use it wisely. Some people prefer to work with a given set of strict rules. Finally, we also do our best to have a regular and sane syntax (it is important after all to have sane macro behaviour). However, due to optional parenthesis, there is some space for ambiguity. Assuming you have a function named `abs`, `abs + 1` is treated as `abs() + 1` but `abs +1` as `abs(+1)`. Those cases are very few though and we also warn about them in the guide. It is one of the trade-offs you pay for having a more convenient syntax most of the times, so you can write: defmodule Foo do def bar do 1 end end Instead of: defmodule(Foo) do def(bar()) do 1 end end I believe this translates well some of the observations developers tell me when migrating from Erlang to Elixir.
- klibertp 14y ago"Erlang does not provide macros" I never wrote any myself, but what about parse transformations? Aren't they essentially non-hygienic macros?
- josevalim 14y agoSorry, I could have expressed myself better. Erlang does not provide lisp style macros. They provide macros, but they look more like templates and are limited. For example, a couple days ago I wanted to write this macro: -define(line(Opts), case lists:keyfind(line, 1, Opts) of { line, Value } -> Value; false -> 0 end). I can call this macro as: ?line(SomeOpts) Basically, the compiler will replace ?line by the template defined above. You cannot manipulate the AST via such macros and they contain severe limitations. In particular, the example above just works if you use it once per function. Since variables are not hygienic, after you use ?line once, the variable Value is going to be bound and it will be considered unsafe (because it is defined in just one of the branches) and your code will fail to compile if you use it again. In case you want to manipulate the AST, you can indeed use parse transforms. But it requires a considerable amount of work to get simple stuff done and iirc you can just use one per module.
- josh2600 14y agoDoes anyone have a counterpoint to this article about why not to use Elixir? We're pretty deep into using native erlang for our work so I don't know how much benefit we'd squeeze out of a switch to Elixir, but this is quite intriguing. BTW, thanks so much for the mention. The core of Kazoo is an all Erlang Stack and we're proud of it (before anyone jumps at me FreeSWITCH is not written in Erlang but it's also not something we at 2600hz wrote). Building the sorts of massively scalable infrastructures we want with the uptime requirements we need would be much harder without the awesome concurrency tools Erlang provides. Delighted that people care about these kinds of languages :D. Disclaimer: I am the Community manager for http://www.2600hz.com http://www.2600hz.com and the Kazoo Product.
- nirvana 14y agoYes, there's one reason not to use Elixir that I know of: [Edit: It appears I might be wrong on this.] It doesn't fully cover the erlang syntax. There are a few things you can do in erlang that you can't in elixir. As I understand it, this will be resolved relatively soon, in an upcoming release, possibly only in a matter of months. Elixir and erlang can be mixed pretty easily, so there's no harm in trying a module in elixir just to see how you like it. Underneath, it's "erlang all the way down", so you're unlikely to run into problems.
- yrashk 14y ago> "It doesn't fully cover the erlang syntax." Wondering what exactly are you referring to?
- nirvana 14y agoI don't know. I'm new to the language, and after doing the "crash course for erlang developers" and reading the release notes about a month ago, I believe I read that there wasn't full coverage, and that it was expected in 8.0 (or maybe 7.4?) You probably have forgotten more than I know about this language, so I'm just going to assume I'm mistaken (or was reading something out of date.)
- kriro 14y agoYeah I'm monitoring them. Seems like a good bet that Elixir will be my language of choice down the road. Some great people behind it, I have a feeling once Dynamo gets a bit more mature (2013 is their year) the language will take off. This video is a nice intro imo (~50 minutes): http://vimeo.com/53221562 http://vimeo.com/53221562
- devinus 14y agoDeveloping on Dynamo is already a blessing compared to other Erlang web frameworks[1]. My benchmarking has put simple Dynamo apps on par with barebones Cowboy which isn't surprising given that Dynamo uses Cowboy under the hood. [1]: http://i.imgur.com/YyAVw1D.png http://i.imgur.com/YyAVw1D.png
- imsofuture 14y agoI can't possibly be alone in liking the Erlang syntax...
- Scramblejams 14y agoSame here. When I learned it, I expected to have more trouble than I did, and the syntax just sits nicely with me. Despite all the complaints about when you use which punctuation, the wart factor seemed a lot lower than all the bleating complainers prepped me for. Some warts you can't get away from (e.g. records, though you might use the parse transform du jour), but others you can (e.g. if? Who uses if? Just use case!). Elixir looks nice, but for now I've got my eye on Joxa[1] instead. Anyway, lots of people worry about learning this syntax or that syntax. In this particular case, they should worry less about learning syntax and more about learning OTP, because once you get past lightweight message-passing concurrency and immutability, OTP's where most of the power lies for building a robust system. [1] http://joxa.org http://joxa.org
- Posibyte 14y agoI assure you that you are not. I find the Erlang syntax incredibly simple and elegant. Every solution seems to be just modifying some grand-unified pattern a bit to fit. But, I guess one mans Erlang is another mans APL.
- devinus 14y agoI can sympathize, I found it's simplicity nice at first. But it quickly wears on you as your codebase grows and you have to refactor. You can find seasoned Erlangers complaining about it's peculiarity often, whether they'll admit it's a problem or not.
- davidw 14y agoIt has two major flaws: * When you move code around, you have to pay a lot of attention to the "ant turd tokens": ; , and . or the lack of one in the right places. That is very annoying. * It's very repetitive at times. Redundancy is great for servers, not so much for code you have to modify. Take this as an example: https://github.com/erlang/otp/blob/master/lib/stdlib/src/filename.erl https://github.com/erlang/otp/blob/master/lib/stdlib/src/fil... It's got a lot of things repeated, and you have to play "spot the difference" to read the code and figure out what's going on. That's a fun game for my four year old, not so much when you're working. I like pattern matching, and it seems that with some tweaks, you could extract common bits of code and end up with something more succinct, so that you only write code that regards the actual differences between two code paths, rather than also having to write the same boilerplate over and over. I have been spoiled by Ruby's "don't repeat yourself" mentality.
- deleted 14y ago[deleted]
- ryeguy 14y agoI can't quite grasp how elixir works with immutability. I have used erlang and am familiar with how it works. In elixir, is it saying that if I create a record and store it in variable "a", I can later set "a=3", but I am unable to change the record once it's created?
- tikhonj 14y agoMy understanding is that you can't set the variable per se. Rather, you can only bind a new variable with the same name, shadowing the old binding. This is very similar to how let bindings work in other languages like OCaml and Scheme. So changing a is more akin to creating a new scope with a new value bound to a rather than mutating a. However, I should be clear that I'm just inferring this from how let statements work in other languages--I've never actually used Elixir.
- josevalim 14y agoThis is correct. That's how Elixir works.
- rdtsc 14y agoThis doesn't have to be an "either or" choice. The great thing is both of them live on the wonderful BEAM VM. They both can take advantage of a completely concurrent garbage collector and all the other goodies. Some modules can be written in Erlang some in Elixir. Elixir it seems very easily can call Erlang functions. I don't know about vice-versa though. A lot of things in the article are related to syntax. I agree that single assignment is not needed for concurrency and the if statement can just return a nil. This, I argue is a matter of preference. In a large system knowing that a variable you set could not have changed, makes state management more explicit, some might see that as a benefit. Also if statements are actually expressions, they should return a value. Choosing a default value of nil seems arbitrary. Just add another clause to if. Besides you'd probably want to use 'case ... of' anyway in most place. Just because 'if' in Erlang matches with the same keyword from C, doesn't mean that both work exactly the same way. Now with the records, yes, there has been talk about adding "frames" (the equivalent of dictionaries or hash tables in other languages). The developers are thinking about it and I believe in release after the next or the one after that we might see that. Now one thing I am really excited about in Elixir is macros. The ability to create a DSL. That is what probably will get to start playing with it.
- josevalim 14y ago> This doesn't have to be and "either one choice". The great think is both of them live on the wonderful BEAM VM. They both can take advantage of a completely concurrent garbage collector and all the other goodies. Some modules can be written in Erlang some in Elixir. Indeed! > Elixir it seems very easily can call Erlang functions. I don't know about vice-versa though. Vice-versa is also true. :) Given you have an Elixir module called String, you can it from Erlang as: 'Elixir-String':upcase(<<"fin">>) I agree 'Elixir-String' is not the prettiest sight but this is because Erlang had an experimental feature called packages that forbade us from using 'Elixir.String'. Luckily, this "feature" is being removed from R16 and in the future you should be able to simply call 'Elixir.String'. There is more information about integration with Erlang in the crash course: http://elixir-lang.org/crash-course.html http://elixir-lang.org/crash-course.html > Choosing a default value of nil seems arbitrary. nil would be an arbitrary choice if you look only at 'if'. But if the language constructs and the standard library consistently uses nil, it is coherent. In Erlang, not having a matching if raises an error, accessing an unknown key in process dictionary returns the atom 'undefined' and accessing an unknown key in a dict returns the atom 'error' or raises an error (depending on the function you call). In Elixir, they would all return nil. This is extremely important, because it allows you to create conveniences around nil, like the operators && and ||.
- jallmann 14y agoElixir looks interesting, but the issues it addresses in Erlang are mostly superficial and subject to taste; eg I like single-assignment, and consider 'nil' a deficiency that can usually be avoided with proper typing. But each to his own -- Erlang does have its quirks, but for me, that mostly fades once you're neck-deep in code. I'd like to see a BEAM-based language designed with an eye towards advancing the tenet of fault-tolerance in ways Erlang currently can't. Probably the most significant weakness right now is with the type system -- lacking exhaustive checks for pattern and function matching always makes me nervous, since that's probably the most common source of errors in my Erlang code. Rust looks promising in this regard. If a best-practices framework emerges a'la OTP, Rust is going to be the dream love-child of ML, C and Erlang.
- devinus 14y ago> Elixir looks interesting, but the issues it addresses in Erlang are mostly superficial. Perhaps if you also view the issues Clojure addresses in Java to be mostly superficial, but I have to politely disagree. > The language has its quirks, but that mostly fades once you're neck-deep in code. Respectfully, I would argue that the quirks aren't made apparent until you're neck-deep in code. That's when it really becomes painful.
- rlander 14y agoWhat? Yes, Elixir's syntax is different, but it retains most of Erlang's semantics. And it's not hard to see that Clojure and Java are very different beasts, both syntactically and semantically.
- devinus 14y agoI'm reminded of a talk by Rich Hickey in which he recounts his experiences trying to initially make Java more immutable. He concluded that while it was certainly possible, it was less than ideal and that a language such as Clojure facilitated expressing the semantics he wanted to convey. As a thought exercise, I would have you re-implement Spawngrid's mimetypes[1] library in Elixir to better understand what I mean. Email me at devin@devintorr.es and I can further elucidate. [1]: https://github.com/spawngrid/mimetypes https://github.com/spawngrid/mimetypes
- lucian1900 14y agoSmall nitpick: Clojure's macros are not hygienic. For better or for worse, this was a conscious decision. If anything, Elixir's macros look more like Scheme's syntax-case, Rust's macros or sweet.js.
- minikomi 14y agoIs elixir strong enough to learn on its own, or should it be thought of in a Coffeeacript frame of mind - where learning the underlying Erlang is pretty much required..
- klibertp 14y agoIt's an important question - I don't know myself, because I don't know Elixir and I'm not even sure if I want to learn it (I like Erlang syntax...) but I'd like to know this too. My quick guess is that no matter how much work goes into Elixir it is not going to replace all the libs written for Erlang, in Erlang - and so basic knowledge of Erlang is still needed to use Elixir to it's full capabilities, even if just for reading Erlang docs.
- josevalim 14y ago> My quick guess is that no matter how much work goes into Elixir it is not going to replace all the libs written for Erlang, in Erlang - and so basic knowledge of Erlang is still needed to use Elixir to it's full capabilities, even if just for reading Erlang docs. This is correct. Syntax wise, you can learn about Elixir and not worry about learning Erlang syntax at all. However Erlang ships with OTP which, as the blog post says, is a design methodology and a set of libraries for building robust systems. Elixir does not intend to replace OTP (at all). For example, the next Elixir version that will ship in a week contains docs and guides on how to write OTP applications. We explain most of the Erlang API required to do so, but eventually you will want to call OTP modules and read their docs, for example: http://www.erlang.org/doc/man/application.html http://www.erlang.org/doc/man/application.html Keep in mind that calling Erlang modules from Elixir is straight-forward and I believe you will find reading the docs too. You mostly need to know how the literals look like, for example: What | Elixir | Erlang atoms | :foo | foo modules | Foo | foo variables | foo | Foo tuples | { 1, 2 } | { 1, 2 } lists | [1, 2] | [1, 2] binaries | << 1, 2 >> | << 1, 2 >> You can find more information in the Elixir/Erlang crash course: http://elixir-lang.org/crash-course.html http://elixir-lang.org/crash-course.html