SW engineering, engineering management and the business of software

subscribe for more
stuff like this:

Learning Elixir, Phoenix and LiveView: A Primer for Experienced Programmers

In order to make web apps with Elixir, here’s a short primer on learning the language and major frameworks:

First, don’t just learn Elixir. You can and should learn Elixir and Phoenix at the same time. After getting a hang of Phoenix, jump into LiveView.

There is a learning curve to the ecosytem. It’s not particularly steep, but it is longer than a language like go but not as long as required by the Haskell or OCaml ecosystems.

Learning Elixir

Start with the official guide: https://elixir-lang.org/getting-started/introduction.html

For experience programmers, the syntax is heavily Ruby inspired. If you are familiar, it’s not a big leap.

If you aren’t familiar with Ruby

Things to learn:

  • atoms:
  • linked lists:
    • use comma separated square brackets: ["thing", "thing2", "kalamazoo"]
    • classic CS linked lists. If you are used to arrays, some operations are O(n) such as length or append.
  • maps:
    • percent-curly braces and arrow notation: %{"abc" => 123, "xyz" => ""}
  • tuples:
    • just use curly braces: {1,2,3} or {"key", value}
    • you’ll often see function return tagged tuples like this:
      • {:ok, success_value}
      • {:error, error_message}
  • keyword lists:
    • These are lists of kv tuples, where the key is an atom.
    • Why not use a map? There are a bunch of syntactic niceties around keyword lists. you should read about them here: https://elixir-lang.org/getting-started/keywords-and-maps.html
    • examples:
      • [{:atom, "value"}, {:atom, "dup keys ok"}, {:ordered, "they remain orderd"}]
      • [shorthand: "notation", for: "keyword lists"]
    • if a function arg is a keyword list like so; def do_something(options) all the following are equivalent:
      • do_something({:verbose, true}, {:debug, false})
      • do_something([verbose: true, debug: false])
      • do_something(verbose: true, debug: false)
      • do_something verbose: true, debug: false
  • sigils:
    • These are syntactic sugar for some common types. They start with a tilde, then a letter then some stuff depending on which letter.
    • date sigil: ~D[2021-02-03]
    • regex sigil: ~r/foo|bar/
    • time sigil: ~T[23:00:07.0]
    • more: https://elixir-lang.org/getting-started/sigils.html
  • anonymous functions (closures):
  • You can skip parentheses
    • Calling a function can be done normally like so: function(arg1, arg2) or sometimes you can omit the parentheses like so function arg1, arg2.
    • The compiler will tell you if parentheses are required due to some ambiguity.

Some of the quirkier (and cooler) parts of Elixir

Immutable Everything

From erlang, you can’t change a data. You can bind (assign) a variable, and rebind it but you are binding a new thing. You never really change existing data.

The pipe operator |>

Pattern matching and guard clauses:

There is no return statement

The last expression is automatically returned. You can’t return early. This one will trip you up occasionally as you have to think about breaking up functions or using pattern matching, guard clauses, case statements or if statements instead of early return.

The Enum module

This one goes with the pipe operator as something you have to learn. It’s everywhere and it’s very “Elixiry” to have long chains of data transformation with Enums and pipes. In addition to the functional stalwarts of map, filter, reduce, there’s a ton of useful collection processing utilities in there. Eventually, you start thinking about transforming data instead of assigning and mutating variables.

https://hexdocs.pm/elixir/Enum.html https://elixir-lang.org/getting-started/enumerables-and-streams.html

Named Structs

They are kind of like objects if you squint hard enough. Really, they are maps with some type metadata baked in. You can pattern match against them and do other things with them. they look like this:

user = %User{name: "amattn", bday: ~D[2021-02-02]}

Erlang

You can call any erlang module.

https://elixir-lang.org/getting-started/erlang-libraries.html

Tooling

The rest

There’s still a lot to learn. I do recommend skimming thru every page of the getting started guide just to get a sense of what you don’t know yet:

In particular: - Module system, aliad, require, import - @attributes - OTP, processes, supervisors - GenServer - streams - [try catch, throw, after, rescue]: https://elixir-lang.org/getting-started/try-catch-and-rescue.html - meta-programming (macros)

Learning Phoenix

Phoenix is an opinionated framework with quite a bit of magic to it. You can strongly feel the Rails influence. Paying attention to directory structure and naming conventions is much more important than in other web app frameworks. Like the entire Elixir ecosystem, this means there is a learning curve, but great velocity gains to be had once you get used to it.

The official guide is quite well written.

You should read the whole thing but start with the request life-cycle guide and then go back and read all the others.

Learning Ecto

Ecto is the Phoenix ORM (Technically it’s not an ORM, but it certainly covers much of the featureset of an ORM. Read more here). It works best with Postgres but the major databases vendors are all supported.

The official docs are well written: https://hexdocs.pm/ecto/Ecto.html

A good way to play around with Ecto is to try out the mix phx.gen scaffold generators:

mix phx.gen.html
mix phx.gen.json
mix phx.gen.context
mix phx.gen.schema

phx.gen.html|json create the context, schema as well as the controllers, view, templates, etc. the html variant in particular is a great example of seeing how ecto ties into phoenix and how changesets work at the data layer as well as in the UI.

phx.gen.context will simply create the context and schema while phx.gen.schema will only create the schema.

Also the phx.gen.auth project is an excellent example of of a vanilla but production ready auth setup with canonical Ecto usage.

mix mix phx.gen.auth Accounts User users

Some concepts:

  • Changesets: These are like mutations in GraphQL. You will want to learn them, because they are a key part of interactivity in Phoenix.
  • Ecto.Multi: transactions

Learning LiveView

Again, some of the best example code is the scaffolding:

mix phx.gen.live Blog Posts post title:string content:string publish:utc_datetime

And I can’t recommend enough Pragmatic Studio’s LiveView Starter and Pro Courses. In particular, From the free starter course: lessons 3 and 4 are the best intro to what LiveView is and lessons 18 and 19 on the two tupes of LiveComponents (stateful and stateless).

Once you get the basics down, There are two great non-trivial projects you can look at for advanced usage:

Deployment

I wrote an overview about deploying to a cloud instance here:

https://amattn.com/p/deploying_elixir_phoenix_webapps_to_the_cloud_with_releases.html

Also checkout the #deployment channel in the Elixir slack community.

Other Resources

Docs:

Communities:

Newsletter:

Free stuff:

Stuff you have to pay for but is worth it:



in lieu of comments, you should follow me on bluesky at @amattn.com and on twitch.tv at twitch.tv/amattn. I'm happy to chat about content here anytime.


the fine print:
aboutarchivemastodonblueskytwitchconsulting or speaking inquiries
© matt nunogawa 2010 - 2023 / all rights reserved