José Valim: Beyond Functional Programming with Elixir and Erlang
functional programming is not a goal in the Erlang VM. It is a means to an end.
Erlang (and Elixir) are practical languages and there is nothing wrong with that. If you are interested in the History of Erlang - Joe Armstrong: 26 years with Erlang or How I got my grey hairs:
Here it becomes clear that some of Erlang’s roots actually come from Prolog (that is where all the emphasis on pattern-matching comes from), a declarative, logic programming language that doesn’t even support functions. But the issue of this topic is “Thinking Functional”.
It is often asserted that it is possible to apply “functional practices” in traditional imperative languages but in my personal experience that is not an efficient way towards adopting “functional thinking” because the imperative escape hatch is always so close by. Even in Haskell it is possible to write in an imperative style - the difference is that it typically sticks out like a sore thumb (so you better have a good excuse ready ) - Haskell is functional by default since it is based on lambda calculus. Learning Haskell is a bit like going to the (functional) language immersion school - everybody gives you dirty looks when you revert to your familiar imperative ways.
That being said Haskell is probably too much of a “full frontal assault” if one has had very little exposure to “thinking functionally”. In my personal case Clojure (a Lisp dialect) was the first successful wrecking ball to chip away at my imperative mindset - if one has no Java development background then it may make sense to look elsewhere (however I think it is important not to get too enchanted with Lisp just because on the surface “it does everything I need to do” but one should certainly learn to appreciate and wield it (certainly come in handy with emacs)).
Now I’m no static typing bigot - but in my personal assessment dynamically typed languages like Clojure, Erlang, and Elixir may not push the programmer/designer enough to actively “reason about types” (and their “compositionality”) in the same way strong static typing in Haskell tends to. Of course ultimately this leads down the path to Category Theory for Programmers.
At the very least there seems to be one repeating theme for “things I wish I was told before I started” - “Dialyzer”, e.g. Bernard Duggan: Erlang in production: “I wish I’d known that when I started”
For the time being I simply view concepts like semi-group, monoid, functor, applicative, monad, etc. as “design patterns on steroids”. Actually design patterns from the OO realm (as helpful as they can be) are more like “sloppy laundry lists” compared to these concepts. Basically design a type that strictly observes the identified “laws” (constraints) and enjoy all the other guarantees that go with it by default. Often people get too hung up on one particular instance (e.g. the IO monad) and a particular use case (e.g. dealing with side-effects) and never stick around long enough to understand the full scope of power that these abstractions can yield (on the flip-side dwelling too much on them probably will end in “type” analysis paralysis - but balance is key, as always).
When it comes to “thinking functionally” it may also make sense not get too fixated on one particular language (it’s always handy to have a secondary) but to also have a look at those languages that hang out in the same neighborhood - but are just a little bit different.
Garrett Smith: Why The Cool Kids Don’t Use Erlang
In the case of Elixir you could work with Phoenix on the back end but use something like Elm, PureScript or BuckleScript to further push the envelope of the “functional programming experience” on the front end.