top | item 22165277

(no title)

cutety | 6 years ago

Definitely agree, though I respect the effort/desire to learn Erlang first given the fact the first time I saw Erlang code I was so confused/put off by it, the syntax was so foreign (not c-like, not lispy), variable names up capitalized, atoms are bare words, source files are just tons of functions, the tooling isn’t anything like modern languages (though since Elixir and hex/mix, that situation has gotten way better), then you’ve got all the OTP behaviors which are entirely unique to Erlang/BEAM, Erlang’s documentation though excellent and extensive isn’t by any means beginner friendly (IMO), and to top it all off, unless you’re coming from another pure functional language you have to deal with working in a new paradigm. Basically, Erlang is intimidating, which is unfortunate because how powerful BEAM and the OTP behaviors are.

However, Elixir wraps up the power of the BEAM and OTP in a much more approachable package. The syntax is much more familiar (thanks Ruby), provides tooling on par with (and better than some) popular modern languages, the language itself also provides more modern user friendly features (macros, pipe operator, protocols, etc). All with a community that is very beginner friendly and willing to help.

If you want to make use of OTP/BEAM, Elixir is by far the best way to enter. When you learn Elixir, you will also learn the major OTP behaviors and concepts (Supervisors, GenServers, Applications, Registry). Eventually you’ll find that there are even more goodies in the beam not directly exposed by Elixir (genstatem, ets/dts/menisia,timer,digraph — are a few of my favorites). Fortunately though, you can call Erlang modules/code directly from Elixir (and vice-versa), so you’ll then eventually dip your way into playing with Erlang modules as needed and when you approach the docs after having experience with OTP with Elixir, you’ll notice a lot of things are familiar and the Erlang docs become much less intimidating.

Basically Elixir is a much easier entry point to Erlang. Erlang is a great language, but very different with a lot of new concepts and which can kill your motivation to learn how awesome the BEAM is, so if you want to learn Erlang, by all means give it ago, but if you find yourself frustrated/confused with it, try Elixir for a while, then come back to Erlang and I bet it will be a lot easier.

When I initially saw Erlang, I was put off, the docs were confusing and I would avoid them at all costs, always try to look for an Elixir wrapper. Now after having worked with Elixir a lot? I frequently find myself going to the Erlang docs first to find a solution instead rather than hex or whatever. I can easily grok my way through an Erlang projects source, which previously was completely foreign to me. Will I ever likely write anything serious in pure Erlang? Probably not. Am I saying if you learn Elixir you will also just pick up Erlang? Absolutely not. What it will do though is make the process of learning Erlang (if that’s the goal), and it’s absolutely massive built in library of tools/abstractions/patterns that no language I’ve seen comes close to replicating an order of magnitude easier.

discuss

order

dnautics|6 years ago

You may like this: the very odd gen_statem callback pattern exists to group different callbacks by state (which you can't do because you need to group like headers together). But in Elixir, we use modules and macros to organize our code more sanely and less ad-hoc-ey:

https://hexdocs.pm/state_server/StateServer.html

cutety|6 years ago

I've only had 2 complaints with gen_statem, the docs were initially some of the most confusing/unclear and the state_functions callback mode (which I think partially is to blame for my first complaint as I was expecting a more gen_server like api with handle_* functions -- which exists but the docs use the state_functions for most of the examples and the handle_event just kinda getting some "oh by the way this exists" examples). I actually initially decided to just keep using gen_server's with a "status" or whatever value in their state as I figured it was good enough. At some point over the next few weeks I actually ended up having this talk[1] pop up in the recommend videos, and I figured I give it a watch to see if it would help make sense of gen_statem or at least just confirm that I don't need it. And while watching it, once he started explaining actions (timeouts, state_timeouts, postponing, etc) I realized that gen_statem literally solves so many problems that I've had in the back of my mind on the project I was working on like "I should figure out a way to change the state of A and do something when it doesn't receive any messages from X,Y,Z processes" (gen_statem's timeouts!) or "how should I handle messages received while attempting to recover, I guess I could put them in a queue or something..." (oh, gen_statem will let me postpone them until it's healthy!). It took a couple more re-readthroughs of the docs to fully grasp, but now it gets included in almost everything I work on, it's so useful (though I guess I should've assumed those were already solved problems by the BEAM/OTP as usual).

However, now my biggest complaint about Elixir is that gen_statem didn't get any official wrapper. StateServer looks like almost exactly what I would want out of an official Elixir wrapper. I also like to see the addition of `handle_continue` as well, because the first thing I did before migrating any of the gen_server's to gen_statem's was create a small wrapper module to a) make the handle_* return values more in like with GenServer's (basically just making it {:(no)reply, (transition|keep), data, [actions]}) and b) add a quick and dirty handle_continue callback because I use it all the time with GenServer. And this literally just looks like a more polished version of that, so thanks!

[1] https://www.youtube.com/watch?v=_4MTIffWhYI