<div>From <a href="http://zwrob.com/posts/erlang-01/">http://zwrob.com/posts/erlang-01/</a><br></div><div><br></div><div>I'm slowly learning [Erlang][0]. It's taken me more than 10 years to get to<br></div><div>where I am now...which, frankly, isn't very far. I thought I'd share some newbie<br></div><div>thoughts from a veteran software developer with over 25 years of experience in<br></div><div>the industry.<br></div><div><br></div><div># History<br></div><div><br></div><div>From 2009 to 2019...<br></div><div><br></div><div>* read books [(Joe, Fred, etc.)][4]<br></div><div>* write little code snippets<br></div><div>* post little [how-to-tutorials][3] showing how little I understand about Erlang<br></div><div>* wander away as I lose focus and time<br></div><div>* repeat.<br></div><div><br></div><div><br></div><div>This year, after Joe died, I thought...I'm not getting any younger either. I<br></div><div>decided to take the summer off and really study Erlang.  So far the process<br></div><div>has been:<br></div><div><br></div><div>* read the [same books][4], but only as references<br></div><div>* have a real problem to solve (I'm basing a business on it)<br></div><div>* write little code snippets (escripts) to POC business components<br></div><div>* document what I am learning on my [personal website][5]<br></div><div>* design the full scale app<br></div><div>* implement ... oops hitting the road blocks...<br></div><div><br></div><div><br></div><div>## Road blocks<br></div><div><br></div><div>### Erlang installation and tools<br></div><div><br></div><div>I wish I'd known about [asdf][6] much earlier. That's really simplified my dev box<br></div><div>configuration.  I wish that [rebar3][7] and [kerl][8] and other docs just pointed this<br></div><div>out.  In fact, I wish there was a `golden` path published that just says, look,<br></div><div>here's the common accepted tool chain you are going to want to use. Stay on<br></div><div>this path, and life will be easy. [rebar3][7] is a big part of this story, but<br></div><div>not the whole thing.<br></div><div><br></div><div><br></div><div>### Migrating from escripts to `real` apps<br></div><div><br></div><div>    $ rebar3 new escript myfooscript<br></div><div><br></div><div>I started with escripts because I didn't want the hassle of understanding OTP<br></div><div>or anything else as I was writing POC snippets to understand the basic Erlang<br></div><div>libraries. So I'd write an escript to shell out and curl some resource and<br></div><div>gradually build up an application that ingests data and writes into a database,<br></div><div>blah blah. But along the way I could learn about `xmerl` and other useful<br></div><div>libraries. Oh, and I could run the app and see STDOUT. Cool! Just like any<br></div><div>other language I'm familiar with.<br></div><div><br></div><div>So I roll up my sleeves and decide to create an app...<br></div><div><br></div><div>### Naming things is hard<br></div><div><br></div><div>    $ rebar3 new release|umbrella myfooapp<br></div><div><br></div><div>Um, why does 'umbrella' exist as an option here? Is it the same thing as a<br></div><div>'release'? Is it necessary? Why is 'release' called 'release'? This is an<br></div><div>overloaded term, as there are 'releases' which is a thing, and there's a<br></div><div>'release' command, and there's a 'release' target in the rebar3 command. And<br></div><div>there's an 'umbrella' in there, too. OK, release == umbrella, so I pick one.<br></div><div><br></div><div>    $ rebar3 new release myfooapp<br></div><div><br></div><div>### Where is STDOUT?<br></div><div><br></div><div>So, let me say, `rebar3` is great. I barely remember what it was like to use<br></div><div>`sinan` or `faxien`. (And while Loic's Makefiles look amazing, I'm nowhere near<br></div><div>smart enough to use them.) But here's the thing, I had to watch a number of videos<br></div><div>before I found out what the `shell` command was. This is important to me because<br></div><div>the next block I had was... how do I start my application _and_ see the output<br></div><div>from it? I want to watch STDOUT, right? I was watching some conference video<br></div><div>when someone mentioned that 'shell' was the coolest part of rebar3 and I'm<br></div><div>like, 'what is that'? And voila! It's what I needed.<br></div><div><br></div><div>This should be on the golden path.<br></div><div><br></div><div>    $ cd myfooapp<br></div><div>    $ rebar3 shell myfooapp<br></div><div><br></div><div><br></div><div>### Where is the golden path?<br></div><div><br></div><div>It's weird that there is no golden path. [In this talk][2], at 14:50, Fred talks<br></div><div>about how it's only far into various Erlang books that authors start talking<br></div><div>about running code outside the shell, in contrast to K&R C where it's discussed<br></div><div>on page 6. In fact, the entire (excellent) presentation is on the terrible state<br></div><div>of tooling in the Erlang ecosystem.<br></div><div><br></div><div>*begin rant*<br></div><div><br></div><div>#### Here's what's weird about Erlang : Books are out of date<br></div><div><br></div><div>* The books are already out of date. Even [LYSEFGG][9] still talks about<br></div><div>  [systools][11] and [reltool][12] even though [rebar3][7] and [relx][10] have<br></div><div>  supplanted them?  What's weird about this is to be reading the rebar3<br></div><div>  documentation, then cross-referencing with relx, and reading the various books<br></div><div>  that describe the old ways of building releases and relups, etc.<br></div><div><br></div><div>#### Docs are hard to follow<br></div><div><br></div><div>* [relx][10] documentation is pretty hard to follow<br></div><div>* Community support seems fragmented<br></div><div>  * [Github shows relx][14] has 41 open issues and 6 open pull requests, with<br></div><div>    89 contributors<br></div><div>  * [Github shows rebar3][13] has 107 open issues and 11 open pull requests,<br></div><div>    with 239 contributors<br></div><div><br></div><div>#### Who's maintaining these tools?<br></div><div><br></div><div>If I were Tristan or Fred, boy I'd be tired of supporting this stuff.<br></div><div><br></div><div>#### Where are the videos?<br></div><div><br></div><div>Here's another thing that's weird...<br></div><div><br></div><div>I cannot find videos on how to use the Erlang shell. So on top of that weird<br></div><div>fact, I'm finding out about erlang by watching Elixir videos. I was watching an<br></div><div>Elixir video on 'wobserver' and realized, 'Hey! I bet that's just a web<br></div><div>interface on some Erlang thingy called "observer"'.  So then I find out about<br></div><div>'observer' and how useful that is. Great!  But things like, how to I do basic<br></div><div>stuff like navigate from one process to another, what do I do when everything<br></div><div>seems hung and broken, what do real live seasoned Erlang devs do when '_stuff_<br></div><div>hit's the fan'? How do they go about examining a running system? The web seems<br></div><div>to have nothing on this. But that's just weird, b/c Erlang has been around for<br></div><div>over 25 years, and any other language / framework/ runtime whatever has zillions<br></div><div>of youtube videos.<br></div><div><br></div><div>*end rant*<br></div><div><br></div><div>## Culture of Quick Fixes<br></div><div><br></div><div>OK, so enough ranting. Let me get into [Fred's mention of the 'Culture of Quick<br></div><div>Fixes'][2] (at about 21:00) by introducing my own steaming pile of a quick fix.<br></div><div><br></div><div>So here's the deal. I'm trying to build a [company][15]. I have limited $$$, I<br></div><div>can't screw around learning stuff forever. At some point I have to build a real<br></div><div>live app and try to generate some buzz. I'll roughly describe my first<br></div><div>app/service and run through my decision points...<br></div><div><br></div><div>### App<br></div><div><br></div><div>The app basically pulls data from publicly available but disparate data sets,<br></div><div>ingests them, normalizes them into a common data store, and then surfaces the<br></div><div>data store for analysis, reporting, AI/ML, etc, etc. In a nutshell, take data,<br></div><div>add magic, produce pretty pictures.<br></div><div><br></div><div>### Process<br></div><div><br></div><div>* prototype in bash (or python, or whatever...)<br></div><div><br></div><div>Seriously, with just `bash` and I can query for my data, extract in, play<br></div><div>around with it, etc. If I wanted I could hook it up to `cron` and probably move on<br></div><div>to actually using the data rather than learning Erlang and how to build 'proper'<br></div><div>infrastructure.<br></div><div><br></div><div>### Prototype in escript<br></div><div><br></div><div>Here's where I take small tasks and learn the Erlang libraries to accomplish<br></div><div>what I'm trying to do. It takes about as much time to do this as the previous<br></div><div>prototyping step. I find this to be a great way to both decompose a problem and<br></div><div>learn a new language.<br></div><div><br></div><div>### Start building industrial grade services<br></div><div><br></div><div>So now, rather than focusing on my business, finding customers, analyzing the<br></div><div>data I've collected, or in any other way providing value that could bring in<br></div><div>revenue and allow me to purchase more Erlang books... I'm veering off into the<br></div><div>weeds and learning how to:<br></div><div><br></div><div>  * build erlang apps for real<br></div><div>  * build erlang releases<br></div><div>  * wire all this into docker containers<br></div><div>  * wire in monitoring and all the 'industrial grade goodies'<br></div><div><br></div><div>Along the way I tend to post about what I learn [here][5].<br></div><div><br></div><div>* Is any of this worthwhile?<br></div><div>* Am I just engaged in endless pencil sharpening?<br></div><div>* I dunno. I'm too close to the fire.<br></div><div><br></div><div>I'm having fun though. And it's incredibly useful to my brain in some way I cannot describe.<br></div><div><br></div><div>### The Problem<br></div><div><br></div><div>So back to "The Culture of Quick Fixes". As I'm building my first set of<br></div><div>components and learning about rebar.config and config/sys.config and more groovy<br></div><div>stuff, I run into the issue of how to deploy Erlang to docker containers. The<br></div><div>answer is, run the release with the `foreground` command. But this wasn't<br></div><div>obvious to me at first and took a lot of digging around the 'net, [posting a<br></div><div>question on the rebar3 discussion list][16], and just general noodling around.<br></div><div><br></div><div>But, if I'm building industrial grade applications, then I need to solve for<br></div><div>issues such as:<br></div><div><br></div><div>* How do I emit metrics from my app?<br></div><div>* How do I monitor my metrics (e.g. Prometheus)?<br></div><div>* How do I hook up a visualization tool (e.g. Grafana)? Alarms?<br></div><div>* And how do I wire all this up into a containerized solution so that it's<br></div><div>  re-usable and shareable?<br></div><div>* Don't forget my "awesome" Makefiles! I like to have a common control plane for<br></div><div>  all my services, and common Makefiles are great for this.<br></div><div><br></div><div>Now, if you watched the end of Fred's video, he was talking about many of these<br></div><div>same things.<br></div><div><br></div><div>*And I'll suggest that what I've built is an example of exactly what<br></div><div>shouldn't be done:*<br></div><div><br></div><div>* I ignored everything on hex. Why? Um, I don't really understand hex that well<br></div><div>  yet, I'd have to go read a bunch of code to understand what folks have done,<br></div><div>  and I'm still learning Erlang by building things myself. None of these is a<br></div><div>  good reason, BTW.<br></div><div>* I only published my stuff to github, and not to hex. This may be a good thing<br></div><div>  as I'd just be duplicating other, probably better, efforts.<br></div><div>* What I built should probably be a rebar3 plugin, and not a Makefile with<br></div><div>  dependencies on rebar3 etc.<br></div><div><br></div><div>However, I'll show you what this is because I think it satisfies a need and<br></div><div>perhaps we can all come up with a better implementation strategy. Or learn<br></div><div>something.<br></div><div><br></div><div>## Erlang-Seed<br></div><div><br></div><div>So, here we have 'yet-another-quick-fix' called [erlang-seed][17]. Let me be<br></div><div>honest, this is a 'quick-fix' to satisfy my own personal needs...<br></div><div><br></div><div>### The Good<br></div><div><br></div><div>What this does is create an erlang application, inject it into a Docker<br></div><div>container, and then spin up a local Docker cluster that monitors the Erlang app<br></div><div>and surfaces the metrics via Prometheus and Grafana. So with one command I can<br></div><div>generate an OTP application, all the infrastructure necessary to monitor it with<br></div><div>common tooling, _and_ spin it up and run it on my dev box. I find this to be<br></div><div>really useful. YMMV.<br></div><div><br></div><div>### The Bad<br></div><div><br></div><div>This is really crufty. It calls into rebar3 to generate the app. It should<br></div><div>probably be a rebar3 plugin so that it can better evolve with the tooling. It<br></div><div>could then more intelligently inject the necessary dependencies, instrument the<br></div><div>code with metrics, etc. Right now it's gross, as it just overwrites files as<br></div><div>necessary using mustache templates.<br></div><div><br></div><div>### The Ugly<br></div><div><br></div><div>* Do I have time to maintain this? No.<br></div><div>* Do I have time to make this a rebar3 plugin? Not right now.<br></div><div>* Will this probably break over time due to either rebar3, docker, or some other dependency changing? Certainly, eventually, yes.<br></div><div><br></div><div><br></div><div>## Summary<br></div><div><br></div><div>The reason I'm sharing this is to just widen the discussion on what the Erlang<br></div><div>education and tooling could look like. I think that generating full stacks that<br></div><div>allow developers to focus more on solving business domain issues rather than<br></div><div>forcing them to understand all the arcane details of whatever is under the<br></div><div>covers is the 'way to go (TM)'. There's got to be a way to allow developers to<br></div><div>maintain velocity while increasing their depth and scope of knowledge as<br></div><div>necessary. I've been studying Erlang intensely for at least a month now, read<br></div><div>the books _countless_ times, and read the online docs and I still don't quite<br></div><div>understand how this all fits together. I mean I get the big picture. But there's<br></div><div>a _lot_ of details.<br></div><div><br></div><div>Contrast this with Go. I was writing production code in 2 days. The quality was<br></div><div>production quality after about a week. Back in the day it took me about a month<br></div><div>to become proficient in Java, though it required reading Bloch's book "Java<br></div><div>Concurrency In Practice" to be 'good'. Python was similar, it took about a week<br></div><div>to ramp up, about a month to become comfortable. In all of these languages it<br></div><div>was a relatively short and easy ramp up and then smooth sailing for years and<br></div><div>years.<br></div><div><br></div><div>With Erlang it's an incredibly steep ramp that goes on and on. I guess if I<br></div><div>remember that I'm learning the equivalent of a language, an orchestration<br></div><div>framework (like kubernetes), a database system, etc., then it starts to make<br></div><div>sense.<br></div><div><br></div><div>Anyway, for my part, I'll keep posting things as I figure them out.<br></div><div><br></div><div>-Todd<br></div><div><br></div><div>[0]:<a href="https://www.erlang.org/">https://www.erlang.org/</a><br></div><div>[1]:<a href="https://ferd.ca/ten-years-of-erlang.html">https://ferd.ca/ten-years-of-erlang.html</a><br></div><div>[2]:<a href="https://youtu.be/Z28SDd9bXcE?t=1260">https://youtu.be/Z28SDd9bXcE?t=1260</a><br></div><div>[3]:<a href="https://github.com/ToddG/experimental/tree/master/erlang/wilderness">https://github.com/ToddG/experimental/tree/master/erlang/wilderness</a><br></div><div>[4]:<a href="https://github.com/ToddG/experimental/blob/master/erlang/resources/books.md">https://github.com/ToddG/experimental/blob/master/erlang/resources/books.md</a><br></div><div>[5]:<a href="http://zwrob.com/posts">http://zwrob.com/posts</a><br></div><div>[6]:<a href="https://github.com/asdf-vm/asdf">https://github.com/asdf-vm/asdf</a><br></div><div>[7]:<a href="https://www.rebar3.org">https://www.rebar3.org</a><br></div><div>[8]:<a href="https://github.com/kerl/kerl">https://github.com/kerl/kerl</a><br></div><div>[9]:<a href="https://learnyousomeerlang.com/">https://learnyousomeerlang.com/</a><br></div><div>[10]:<a href="https://github.com/erlware/relx">https://github.com/erlware/relx</a><br></div><div>[11]:<a href="http://erlang.org/doc/man/systools.html">http://erlang.org/doc/man/systools.html</a><br></div><div>[12]:<a href="http://erlang.org/doc/man/reltool.html">http://erlang.org/doc/man/reltool.html</a><br></div><div>[13]:<a href="https://github.com/erlang/rebar3">https://github.com/erlang/rebar3</a><br></div><div>[14]:<a href="https://github.com/erlware/relx">https://github.com/erlware/relx</a><br></div><div>[15]:<a href="http://envirosoftwaresolutions.com">http://envirosoftwaresolutions.com</a><br></div><div>[16]:<a href="https://www.rebar3.org/discuss/5d29172873e1ed00447cb362">https://www.rebar3.org/discuss/5d29172873e1ed00447cb362</a><br></div><div>[17]:<a href="https://github.com/ToddG/erlang-seed">https://github.com/ToddG/erlang-seed</a><br></div><div>[18]:<a href="http://zwrob.com/posts/developer-automation/">http://zwrob.com/posts/developer-automation/</a><br></div><div><br></div><div>-Todd<br></div>