Should I learn Rails or Phoenix?

everything in flow

The road to becoming an alchemist rookie is long and rocky. But like all such paths, it is worthwhile. And if not, you only show true consistent action when you have also gone down the wrong track.

Part 1: Why?

I didn't learn Elixir because it's functional, or new, or cool, or funky. I am a web developer. I build websites. Solving great math problems elegantly with functional language may be great for learning. It's just of no use to me with my everyday problems. These problems want to be solved quickly and sustainably. But there is the Phoenix Framework.

Elixir is to PHP like Phoenix is ​​to Laravel or Symfony. And Erlang to Elixir like the C ++ core from PHP to PHP itself.

(With the difference that you can easily access Erlang functionality in Elixir and that you have to write an externally linked module with PHP.)

First contact

There was one day in May when my colleague Max fell from his chair. The Phoenix Framework trended on hacker news. A web framework that was essentially based on the functional language Erlang was something absolutely revolutionary. And it endured a load. A lot of burden.

Phoenix is ​​based on Elixir and is an essay on Erlang. Both came from the pen of Josê Valim, who was also responsible for the Ruby on Rails Framework.

Elixir, on the other hand, is practically an attachment to the Erlang VM and is only around 3 years old. Erlang offers real multithreating, sorry for parallel processes - it was invented for distributed systems. In practice there is no OOP in the form of classes, interfaces and such things, but creating a process is just as easy as creating an object in other languages. Whereby, as I was allowed to learn, OOP in the true sense means: “I have isolated entities that can send messages to each other”. Elixir as a functional language with the ingenious process abstraction implements OOP more cleanly than commercially available OO languages, in which one can make far too much imperative nonsense, which bypasses the object encapsulation. “Classes” and “inheritance” are also not included in the original definition of OOP, which is a common misconception.

10 years of PHP, then came Javascript / Coffee / Typescript

My first contact with PHP was around 2000. After a trip to Perl, I stayed with PHP for a long time - to this day. For the daily work as WebDev it is absolutely great. Lots of people bashing around on PHP. "The syntax is not consistent," - "Procedural programming is something of yesterday." - "OOP is just tinkered with it." Well, it just starts running with the last cheap hoster. And bad code is not primarily due to the language - most of the time, however, people have perpetrated it - I have not yet seen any machines program. I've been working with PHP every day for around 10 years. However, Javascript has been increasingly added in recent years - mainly due to the increasing automation of build processes (Hello Grunt!) And the ongoing trend towards single-page apps. The common PHP programmer realizes over time: Javascript is cool too. After I actually understood the prototypical basic concepts of the language, Javascript was really fun. And a new language expands the mind. Already in “The Pragmatic Programmer” (also by Dave Thomas) it says: “Learn a new language every year”.

Motivation for new things about Code for Chemnitz

However, everyday professional life does not always offer a sufficiently large stage to try out revolutionary new things. Just try out Python in a company that mainly works with PHP and Java? Rather difficult. Then came the OK Lab Chemnitz or Code for Chemnitz. So every two weeks we sit together in a small circle of like-minded people and think about which great web projects we could start to advance our own city or to build tools for its residents. The nice thing about it: free choice of technology and a specific goal. The best conditions for dev-nerds! CVAG bus stop app with Angular and Node.JS? Clear! Shelter Page Parser in Javascript with a Publisher in Ruby? Why not. A sensor management card app with Meteor.JS? Yo! A simple sensor configuration program with Electron? Yep. A sensor data receiver REST web service in Python. Why not? We wanted to implement exactly the latter in Elixir / Phoenix. But nobody has been able to do that - but it's currently a clear goal for me.

In summary: PHP is still cool for me - with frameworks like Laravel and appserver.io as well as PHP7 it still has a long future ahead of it. Node.JS is cool elsewhere and complements the build stack around PHP very well - or is also a great thing as a standalone app server (e.g. with Express framework). But it's like in the GDR or in socialism. As long as you don't know the western products, everything is cool. But as soon as you have a look at western television or over the wall, everything pulls you in exactly that direction. This is how I feel the urge towards Elixir / Phoenix at the moment.

With the book “Programming Elixir” I am just through Part 1 “Conventional Programming” by teaching the basics of the language. I have just started the 2nd part “Concurrent Programming” and am really starting to understand what amazing possibilities it offers.

Part 2: PHP vs. Javascript vs. Elixir

As already described above, I am mainly familiar with PHP and Javascript. I used to program Java for a few years. But that was a long time ago, so my assessments are rather not state-of-the-art. So I can't make comparisons to Python or Ruby. Here are a few assessments.

Hard limits

PHP can only be single-threaded by default and strictly follows the share-nothing principle. Modern web applications are increasingly reaching hard limits. Bootstrapping must be carried out for each request. Caching such as APC relieves the pain, but the pain remains. Projects like appserver.io use the pthreads extension, which enables multithreading in PHP.

Node.JS was preparing to expand the programming options with its callbacks and asynchronous calls - yes, it even feels a little functional. However, it is based on the Chromium and thus on a single thread. Real multithreading or processes are therefore not possible in Node.JS either. The limits are foreseeable. Just don't let yourself do the math. Then it's alright.

With Java you can also build webapps - so-called servlets. They run on application servers that bring a lot of great things. DB connection pooling, load balancing etc. Java is still the method of choice for serious, real large (web) applications for many companies. However, you buy the convenience of Java's garbage collection and the OOP forest through massive RAM use. As far as I know, such an app will not start below 1 GB. Whereby RAM is no longer an issue today. But Java can do real threading - with the usual pain like synchronization problems and race conditions. You can only really get a grip on this if the threads are all running in sync. Well, then you can actually leave it. The average productivity using Java is rather difficult by today's standards. Tons of boilerplate code, rapidly sprawling class forests that need to be navigated, endless controls in XML (even the build tools). Not to forget: working in the TDD cycles within seconds is not so nice due to the JVM's warm-up time.

The limits of Elixir or the Erlang VM? No idea. There is an example in the book in which a chain of processes is formed that adds up a number by one. This started with 1,000,000 process instances takes just over 7 seconds on a MacBookPro Mid 2014. Processes can therefore be used like objects. And you can do calculations - with any precision. If necessary, the VM adjusts the data type itself. The 1000th Fibonacci number? Any number with about 100 digits. Oh yes, and then there is the supervisor who simply starts the failed processes again. Goodbye failure. Performance and resilience: Node, Java and Go already go to their knees on a single sheet: Comparative Benchmark Numbers @ Rackspace. Side note: in the linked example, the ~ CPU was at just 70% at Plug / Phoenix - the connection to the server could not carry out more requests to use it to capacity.

Syntactic sugar

In PHP new language features are gradually being introduced. But in order to be able to use this in existing legacy applications, you have to migrate it to the newer PHP versions. And unfortunately companies shy away from the effort.

Javascript of today is mainly written according to the ES5 standard. Also in Node.JS. It can be programmed quite nicely with that. With ES6, sorry ES2015, many new language features are added.

Elixir itself is practically just a set of macros that is resolved into Erlang code. In principle, you could also use your own language in Erlang.

Why ; and further clutter is unnecessary

I found the commands to be terminated with semicolons great from the beginning (around 2000). Before PHP and Java I just did Visual Basic and Turbo Pascal. As an autodidact, C and C ++ were too spacey for me. But PHP looked a bit like C - so it was cool per se.

Javascript also uses ";" as a command separator. Cool too. And then came Code for Chemnitz and Python and Meteor, JS and Coffeescript. One evening in a cozy group I wrote a little Python script under guidance that parsed an HTML page. Then the ice was broken for me and my love for the semicolon was extinguished. I tweeted a little later, "No brackets are hipster stuff."

Coffeescript also comes without; off, offers unbelievable syntax sugar. You just have to try it. It feels great. All superfluous signs and dirt are gone. It remains the essence of meaningful source code.

In Javascript for example like this:

In Coffeescript then like this:

Everything you need is there, without all the paste around it.

Elixir also usually comes without ";" therefore. The example above looks like this there:

Close to Coffeescript, right?

A module with a function looks at least like this:

Keeping a long story short.

Phoenix Framework: a killer framework?

At the time, José Valim played a key role in developing Ruby on Rails. A framework with which complex applications can be implemented in the shortest possible time. This is probably made possible by the convention-before-configuration paradigm. There are routes, templates, controllers, models, ORM, etc. - but everything is expected in exactly one place. This saves you a lot of thought like “where do I put this or that?”. There is no such thing in Meteor.JS. This makes it easier to get started, but makes project growth more difficult if you have not seen a meaningful directory structure before. Phoenix follows the same approach as Ruby on Rails and specifies a lot - and expects a lot in exactly one place. But there is a wealth of tools that make generating new controllers, routes, models, etc. child's play. So far I haven't started a Phoenix project myself, but after reading the excellent documentation, I initially fully concentrated on Elixir. Without basics in the language it's just difficult. But what I've read about Phoenix so far has really blown my shoes.

I have to note that in my daily work I have always worked (= had to work) with company-specific frameworks. That's not bad, but Stackoverflow and Google simply fall away in the event of problems - you have to rely on the help of colleagues.

Phoenix is ​​preparing to be a full stack framework. Unfortunately the browser cannot (yet) support Erlang / Elixir, so by definition it cannot be as full stack as Meteor. But it covers all areas of a web application. And even more: "Channels" abstract connection protocols of all kinds, included Websockets. So you can connect your iPhone app to your toaster in real time via Phoenix - the future is the Internet of Things - and only Phoenix is ​​really optimized for it! In the beginning, Meteor is faster to develop for a pure browser server, but Phoenix is ​​far more powerful.

Response times

Danger! The following comparison lags a lot, but roughly shows the direction.

At PHP Bootstrapping always takes place first. A productive response time of 200ms is quite good for a large framework.

In Node.JS bootstrapping takes place at startup. The response times are therefore correspondingly shorter. (<100ms?)

In Java I once worked on a Websphere application. This application swallowed several GB of RAM and talked to an Oracle DB. Response times of 10ms on the test system were very good there.

When visiting websites in Phoenix response times are given in the log in µs. In µs!! 1elf! Of course this is the Helloworld example because there are no really big applications yet, but it shows the direction quite well.

Part 3: actually learning Elixir

So, now everyone is motivated to actually learn something new, yes? It's all terribly much better than anything that's been there. Yes, right, but as always there is a price to pay:

Functional programming: incredibly different

  1. Functional programming! = Imperative programming .. programming a bunch of small functions is very different from coding in PHP. Programming a Christmas tree-like code is practically impossible. Following the principles of clean code is therefore much more obvious.
  2. In Erlang and thus Elixir all variables are by definition immutable. Elixir at least allows things like x = x + 1 - Erlang himself doesn't. Even when adding new elements to huge lists, a new one is always created. However, in the form [itemtail] - i.e. the new variable has the new entry and a reference to the rest of the list.
  3. ”=” Does not assign values ​​but “equals”. That is a huge difference, keyword “pattern matching”. In the book, "I do not think it means what you think it means." It is unbelievable what kind of crazy constructs are possible with it.
  4. If a function has more than 10 lines and this is not via> being connected is definitely doing something wrong. See 1.

Laws of nature waver

But Elixir also proves the following: (quoted from “Programming Elixir” p.9) 1. OOP is not the only way to design code 2. Functional programming does not have to be complex or mathematical 3. The basics of programming are not assignments and loops 4. Parallelism does not need locks, semaphores, monitors and the like 5. Processes are not necessarily expensive resources 6. Even if it is work, programming should be fun 7. Hardly learned OOP “patterns” in the enterprise area are almost all complete obsolete by working on a higher level of abstraction. In general: whenever you think remotely of “pattern” during daily coding for what you are doing, that is a sure sign of a weak point in my programming language. Only languages ​​with “hygienix / homoiconic macros” are immune to this weakness, that would be Lisp (-> Clojure, Scheme) and Elixir as known representatives.

Elixir is not the Holy Grail, but there is also no one true way to program - just as there is no one God. But it's different enough from the mainstream to give you a different perspective - open your mind and explore new ways of thinking about programming.

Functional programming breaks up encrusted thought structures.

Book “Programming Elixir” by Dave Thomas

There is currently no German book on the subject of Elixir. But there are some very good English books on the subject. The best entry for advanced beginners is probably “Programming Elixir” by Dave Thomas.

There is a beginner's article on Elixir on heise developer, which is a bit inaccurate (to put it politely).

As described above, I have now worked through the first part (important! Reading is faster than understanding and doing it yourself!) And am scratching the second part. But that is optional today if you want to start with Phoenix.

With the help of this book, I developed a structured language for myself for the first time. The “You turn” exercises are mostly known mathematical / programming problems such as prime numbers, Fibonacci numbers, map & reduce, copy string operations, etc. Not very, very difficult but demanding.

My effort for learning

I am writing this blog article at the end of my two-week vacation in the Austrian Alps - more precisely in the Asten Valley at 2050m. In my opinion, a vacation is the perfect basis to deal with fundamentally new things. Not that you should spend your entire vacation in front of the laptop, definitely not. But after a long hike you can a) sink into the evening with fruit schnapps and wine in front of the television or b) use the refreshed and liberated mind and read things that interest you. On a winter vacation about 5 years ago I read “The Pragmatic Programmer”. A book that I would have needed months to write in everyday life. But as it was, it was read through within a week, including the return trip.The following maxim applies on vacation: no fancy = chilling, much fancy = reading & trying. So have

I read and / or tried it for 1-2 hours in the evening. Once the whole evening (5h). Read the week before your vacation 2-3 evenings. Overall, it is difficult to estimate the effort. Maybe 40h so far? Maybe 50h?

No matter, in the end one thing counts above all: the fun and the kick of the “Aha” experience - and the “energy of understanding” (quote: Stefan Münz, SelfHTML)

Examples of motivation

The following examples should make you want to try.

Calculate prime numbers

My first variant with a good example of pattern matching:

My final and what feels like the best solution in the 4th iteration with a double-filtered list comprehension:

Call in each case with:

Calculate Fibonacci numbers

As a simple module:

The 37 Fibonacci numbers are then calculated as follows (after approx. 5 seconds):

Result:

In the absence of caching, the calculation of larger numbers takes forever. Max has accelerated the example a bit by using lists, including Doc and Spec: elixirplayground.com/?gist=1dfd7f1d8dbc6afb1f3d

And now as a process agent who also caches individual results.

In then like this:

The output then after about 3 seconds as follows:

Elixir can calculate really well.

Conclusion

The learning curve of Functional Programming and Elixir felt to me at first flat, then increasingly steep. I learned most about the “Your turn” while trying it out. Until such a prime number algorithm runs, it can be implemented in around 4 ways and flavors.

Elixir programmers call themselves alchemists. I currently call myself Alchemist Rookie, as I am still at the beginning of the possibilities of Elixir, Erlang OTP and Phoenix. But consistent learning paves the way to becoming an alchemist. Elixir may soon replace PHP and Javascript (in the backend) in day-to-day business.

So, let's go! Make Elixir and Phoenix mainstream!

Thanks also to @ Hisako1337 for food for thought, the review and some technical corrections and comments!