Why the Elixir language has great potential
adrian-philipp.com
adrian-philipp.com
The ease of navigating an Elixir project is a huge benefit. If I want to know where a function is defined, it's very easy to find it. There's none of this class-reopening or meta programming malarkey that you get in Ruby (where is a Rails controller's render method defined exactly?)... it's all right there in the module.
Another thing that I love is that it's trivial to separate processing of several pieces of data into separate Elixir processes. To do something similar in Ruby, I would probably need to either use concurrent-ruby or spin them off into a background job with Sidekiq. In Elixir, it's baked right in.
Elixir is well-designed, the community is very friendly and it's just a pleasure to develop in.
I would view Elixir as an improvement (iteration?) of Ruby built on Erlang. The article points out it was written by Jose Valim . It derives its structure from the documented shortcomings of both parent languages.
http://elixir-lang.org/getting-started/meta/macros.html
Check out the Foreword section.
Regarding learning Elixir, I thought LearnElixir.tv was great, but wasn't nearly as impressed by LearnPhoenix.tv. The latter is good, and definitely worth the money, but it didn't feel like it went into nearly the depth and breadth that LearnElixir.tv did. I also recommend the books "The Little Elixir & OTP Guidebook," by Benjamin Tan Wei Han, and "Programming Elixir," by Dave Thomas. Elixir School (http://elixirschool.com) is great online resource, and the Hex docs (https://hexdocs.pm) are clear and well organized. Finally, "Take Off with Elixir" (https://bigmachine.io/products/take-off-with-elixir/) is a great video/book offering.
Is the app public? (If you don't want to mention its homepage, I'll understand since it's your employer.)
Here's the website for more information: http://goskip.com.
We just released our software into two markets on the 1st of this month, and plan to release into markets nationwide beginning early 2017. I'm compelled to secrecy until then, but yes, I do plan on doing a thorough write-up of our product and our experiences with Elixir.
There's a lot of niceties you get out of the box (mix is pretty nice and the testing framework is included, the REPL is good, love that they improve the error messages and consider an unclear error message a bug). I'm already used to pattern matching from Prolog so that's a great plus (I wanted to use Erlang initially but Elixir has won me over). I also feel like I'm thinking in a functional way much clearer (I'm using the PragProg book and this video tutorial https://bigmachine.io/products/take-off-with-elixir/ which both stress it, both resources highly recommended).
Once I start dipping into OTP I'm sure I won't be looking back anytime soon. It's been a while since I was this excited about a language.
Phoenix (web framework) is also pretty awesome. The abstraction of chaining a request through a bunch of functions to generate a response is very fitting. Plugs make sense.
tl;dr: Try it!
Aside from that... Elixir feels really fun. Maybe it's a silly metric, but that's just my biased opinion.
The last feature that caught my attention was their deployment tools. I haven't used em yet, but based on a conference video I watched, it looks like they have pretty sweet setup. They claim to have very easy zero downtime upgrades / downgrades. And I think preparing a release automatically bundles dependencies, so everything is contained in a single compressed file.
I'd argue that from a hacker's perspective, this is the most important metric. It's what keep you returning to the language, and what gives it vi(r|t)ality. Don't underestimate fun!
When I started learning I didn't understand why I had to use a different operator for string concat vs numerical addition and the Dialyzer talk from ElixirConf explained it very well.
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?
Still you need to understand the whole process and OTP deal.
You still have to bend your thinking, yet, you feel that you become productive much faster.
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.
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.
Also, I hope you were setting https://www.emacswiki.org/emacs/ShowParenMode
Just my 2¢.
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.
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.
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.
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]
1. Security. Small non-obvious mistakes are easy to make and very important.
2. High visibility. Risky, and if it goes wrong it's a major thing your customers notice.
3. Dry. It's just not particularly interesting for me, it's certainly solved in other frameworks (e.g. devise). I'm aware this last point is extremely selfish of me, however.
There's a deprecated `conn/0` function that you'll accidentally call instead if you forget to do this.
I've come across some paid services (e.g., stormpath, auth0) that seem to do what I'm talking about. It would be really nice if there were a free project along those lines though.
1. http://microservices.io/patterns/apigateway.html 2. https://getkong.org/ (a few auth plugins) 3. https://github.com/auth0/nginx-jwt / https://www.stavros.io/posts/writing-an-nginx-authentication...
Website blurb:
Add authentication to applications and secure services with minimum fuss. No need to deal with storing users or authenticating users. It's all available out of the box.
You'll even get advanced features such as User Federation, Identity Brokering and Social Login.
Subjectively speaking, I really like the terse yet expressive syntax. It's also nice to have a smaller codebase.
There's an awesome package that creates HTML docs out of your comments. It's really useful for creating documentation on the fly. Elixir's official docs are made this way.
I'm about halfway through a course I think is very good for beginner-level programmers (https://www.udemy.com/the-complete-elixir-and-phoenix-bootca...).
Elixir School is also a good resource.
Phoenix shows a lot of promise too, I haven't taken to JS so it would be good not to have to use it as much as possible.
I signed up for the digest there and it's one of the few "bulk" emails I get that I actually read.
The thing that constantly gets me about Elixir and Phoenix is the default tends to be the correct way of doing it. Let me explain.
For example, the other day, I was looking at filtering a next parameter to remove the domain (for security- you could redirect someone to fake login box on your host after they log in)... however it's unnecessary as redirect/2 in phoenix if passed a URL rather than a path will throw an error by default. As an aside different exceptions will return different HTTP error codes - for example a database not found exception from Ecto will cause a 404. There are hundreds or thousands of these little decisions that are the correct/simpler decision.
Elixir and Phoenix, for want of a better way of saying it, show great programming taste. So to say it's a coat of paint is a bit harsh; it's the right coat of paint, in my opinion.
I am having a lot of fun as I find it to be a refreshing approach to web development.
Elixir's guide is quite exhaustive. You can easily start building a toy app over a weekend.
I have open sourced the source code for my blog/web-shop that I built using Elixir/Phoenix. I am not an Elixir expert and this is not the best written Elixir app, but if anyone wants to look at the code for a simple CMS and shop built with Elixir and Phoenix, here is the link - https://github.com/authentic-pixels/ex-shop.
Here is a link to the live website - https://www.authenticpixels.com/
https://github.com/elixir-lang/plug/issues/258
So, for a language that's primarely based around webserver, i find it really woorying that http2 support wasn't a primary concern, and depends on donation to a third party developper...
I guess it means the language is still young and so is the ecosystem.
Elixir leverages Cowboy quite a bit and HTTP2 requires substantial rewrite of Cowboy.
This will be completed in the release of Cowboy 2.0
If you want to read why Cowboy needs to be majorly refactored, read the link below
Our websocket endpoints, our app servers, and other services all run on Elixir, and pretty much without any incidents.
Erlang/OTP is battle-tested and it's really the first time I could comfortably sleep at night without worrying about stuff going down. Personally I think Elixir past the point of just having "potential" and is my default go-to language to solve any problem as long as it makes sense to solve it with Elixir.
Just curious, what other languages/frameworks have you tried in backend? Are you running Phoenix?
(I know it's apples to oranges... but for some tasks, like backend / high concurency microservices etc., both an apple and an orange are perfect fit, so it's worth comparing. I've heard of Ruby or Python people jumping to Go or Elixir, but not of any comparison.)
Both are very similar in their underlying approaches. The biggest difference is that you have to write a lot more error handling code for Go.
The other thing is interfaces. With Go if you want to be able to pass multiple different types of structs to a function you have to define an interface that fits with both by showing each have a field named X of type Y. Because of that you end up needing to define a lot of interfaces.
Elixir accomplishes the same thing with pattern matching. You can define a function that shows parts of a nested hash in the argument and in order to call that function the hash you pass has to have those keys. It's much more flexible and less clunky IMO.
The other thing is Go's compiler strictness about making you remove any library from the import that not in use. When doing development or experimenting with a new library it gets really old having compiler yell at you about this because you commented something out. With Elixir, the compiler WARNS you about it. You still get a great big "get rid of all this stuff that isn't used" on compile, but it doesn't interrupt your development workflow.
Details like that, better package management, etc make me significantly more productive with Elixir. Phoenix is excellent and it's view layer is extremely fast and flexible - probably my favorite view layer that I've ever dealt with across many languages. Contrast that with Go templates, which to me felt a lot more like JSP.
I got productive quickly with Go and loved the simplicity and ease of development. The speed of compilation is amazing, and the programs run at a blazing speed. Then hit the wall and found myself repeating myself again and again. The lack of generics, pattern matching was really a deal breaker for me.
I chose Elixir for another API backend, and I really loved it. Hex, the package manager, Phoenix framework, the rock solid Erlang/BEAM and the Elixir language itself was a breeze from Go. Even though it compiles slower, and sometimes Hex package would fk up package hierarchy, the whole experience was great. The IDE support is bit flaky, and I used ST3.
I would highly recommend Elixir over Golang.
For example you could use JRuby and Akka and probably have something comparable to Elixir (I haven't tried it as I prefer Java and Scala). And you could then use any Scala or Java library.
The only big issue I have with the JVM is that it is a memory hog and thus expensive. Consequently the most compelling thing about Elixir is that is on the erlang vm but I still prefer static typed languages. If Elixir were typed I might be more excited about it.
Don't get me wrong I love more options and we even use Erlang in my company but the JVM just has more flexibility.
Regarding the types on BEAM, there are types: maps, records, binaries, atoms, numbers, booleans... there's no classes but one does not need classes. Actors replace objects perfectly fine.
I only mention JRuby as many folks switching from Elixir are Ruby shops.
Personally I find the actor model too heavy (programming wise) for local concurrency and rather use some other message passing for distributed programming (zeromq, rabbitmq, kafka, etc). I know people hate damn queues and reactive programming but that is what I know (and I admit it is less efficient and more error prone than builtin green threads (go) or actors).
I realize now Elixir makes it damn easy because it is all in one package it is just a shame that there isn't some ML like language that compiles to Erlang bytecode.
There is! https://github.com/alpaca-lang/alpaca
It's very new, though. I wouldn't write production stuff in it just yet.
Probably the biggest issue we have with Elixir right now is libraries, but it's a more subtle problem than "there isn't a library that for this thing I want to do". To the contrary, I've been pleasantly surprised at how many libraries are available and how good they are.
The issue with libraries that I see is that because the language is so young and the core libraries are changing so rapidly (for the better!) a lot of useful third-party libraries have trouble keeping up. So we frequently find that a new feature has been rolled out to a core library that we really want to use, but upgrading it breaks a dependency in a third-party library.
It's sort of to be expected, right? The language has captured enough mindshare that people are building useful libraries left and right, but it hasn't gained quite enough adoption that there are armies of developers who can devote time to keeping those libraries updated to the minute - you don't have 100 developers behind a given library, you have 10 or 2 or 1.
Elixir was just released 5 years ago, and despite some success, has not taken off as much as the absolute top programming languages released around that time. For example, Go, released just 2 years earlier, is by far the most successful of new languages from the last 10 years.
Given my skeptical mindset towards neomania, it might surprise you to hear that I'm a huge proponent of Elixir! Here are my reasons for studying Elixir and using it exclusively for my non-work projects, despite there being countless other recent, appealing languages:
- Although the language is young, it's built on Erlang, which is 30 years old. Even if Elixir fails, there is a lot of knowledge transfer between the two languages (probably 90% of what I learn from using Elixir transfers directly over even if I switch to exclusively Erlang).
- Web applications are a fantastic use case for the Erlang VM (BEAM). Take a look at this article (https://joearms.github.io/2016/03/13/Managing-two-million-we...) by Joe Armstrong, one of the creators of Erlang, written earlier this year.
- Elixir is quite a bit different from other languages I'm familiar with. It's compiled and functional, has powerful pattern matching, uses lightweight processes and the actor model, and comes with OTP, a complete set of tools that I can use for free. This means even if/when the language dies, I've added a lot of new skills to my programming toolbelt.
To anyone that has decided, like I have, that Elixir is worth putting some time into learning, I'd like to recommend the book Elixir in Action (https://www.manning.com/books/elixir-in-action) and the blog of the author of that book, which has infrequent but outstanding posts (http://theerlangelist.com/).
This is a really valuable point. My personal rule of thumb has been that every hardware or software technology takes 5 years to mature: it will useful long before then, but it take years for all the issues to be found and fixed and the ecosystem to fill out, so if you invest before the 5 years, expect less than perfection. Equally, if a technology does not seem to be maturing after 5 years in the field, it's probably not going to happen.
My personal long-term bet is Rust. It is an incredibly well-run project with a superb community, it has use cases that few other languages can fill, and I think that it has potential beyond it's currently defined position as a "systems language" (if you can write business applications in Swift, why not Rust?). Even if I'm wrong, it fills the criteria of being a programming language that is changing how I think about programming, so it will be a valuable experience.
Actually the adoption is quite good considering there is no industry giant backing it. There are plenty of companies using it in production and there is a job market for it.
Comparing the adoption with Go/Swift is a bit unfair.
What I'm finding is that every justifiable reason for using go outside of portable binaries...is that Elixir is the option I would have preferred or is simply a better fit. So much Go adoption came from concurrency needs of Ruby, Python and PHP Devs at a time when Elixir just wasn't ready yet.
The staying power of Elixir despite not being backed by Google or first to market here gives me great confidence. If nothing else, Elixir is educating a lot of people about what makes Erlang so good...and once you understand Erlang/BEAM you see everything that's missing everywhere else. Without learning it, you've got an ignorance is bliss situation.
Especially around using macros, but also other lexing errors like missing closing delimiters, ...
Line numbers are often non-existant or wrong, and the terminal output is hard to read.
Devs should take some inspiration from Rust. Wonderful error messages, and mostly accurate line numbers even in expanded macros.
Otherwise, Elixir is definitely interesting though.
I'm interested to hear though, can anyone care to comment on their experiences with Elixir's package ecosystem? How much developed is it and/or how much more to go to be suitable for most major projects?
We are using Elixir for more than a year now at work and in almost all cases where we couldn't find a Elixir lib we found an Erlang one.
If you can't find a package then you could try looking it up at https://github.com/h4cc/awesome-elixir or asking on the elixir slack (https://elixir-slackin.herokuapp.com/) or on the #elixir-lang channel on Freenode.
After all that if you can't find a package that suits your needs then it's very easy to create one. "mix new (your project)" and away you go.
That's what I did with my elastic package (https://github.com/radar/elastic) when I couldn't quite find something that suited my exact needs. There's Elastix and Tirexs out there (those are the ones I know of) but neither really suited what I needed, so I just built my own.
I don't know how it could be a deal breaker if a package didn't exist already. I'd encourage you to build whatever you don't find already existing and contribute back to the community.
As an example, I hit the issue recently where a changeset wouldn't accept nil for a relation via put_assoc. That seemed like an very trivial problem to be hitting for a project that's been around so long. And I hit a number of issues that had that sort of feeling.
Another thing was that, if you update a thing with new relation data, you have to force-reload the relationships from the database again. That was pretty surprising and seemed like it should be unnecessary.
I think there's room for an Ecto alternative that tries to be a bit less fancy and gains a lot because of it.
The Ruby-inspired syntax have helped the language to gain traction amongst Rails developers but for somebody like me who only exposure to Ruby is Capistrano it doesn't do much.
Read more here https://www.bignerdranch.com/blog/elixir-and-io-lists-part-1... and in part 2.
The trade off there is prescheduling, where the VM caps execution time of processes in the scheduler guaranteeing that a heavy process isn't allowed to take over the machine VS cooperative scheduling where the code has to periodically check in with the scheduler to relinquish control.
Prescheduling won't be faster in a benchmark, but if you have millions of small requests their response time will remain consistent in the face of bad actors or infinite loops trying to takeover the machine.
For this web framework test Phoenix (Elixir) does almost as well as Play (Java) https://github.com/mroth/phoenix-showdown
The benchmarksgame's site quotes "Most (all?) large systems developed using Erlang make heavy use of C for low-level code, leaving Erlang to manage the parts which tend to be complex in other languages, like controlling systems spread across several machines and implementing complex protocol logic."
So it depends I guess.