One of the best things in Elixir is it’s metaprogramming capabilities. You can write pretty performant DSLs (domain-specific languages). That means, you can naturally write on another simple language (HTML, SQL, XML, protobuf) inside of Elixir. Maybe, with a bit different syntax but the same semantics. There are some of my favorite DSLs:

  • Ecto is the best ORM I ever worked with. If you used to active record approach, you’ll might feel uncomfortable at first, then you’ll question why there is some repetition, but when you come through this, you’ll see how ingenious are some design ideas in Ecto. Inside, it has a separate module for migrations, for schemas, for queries, for data validation, for database connection. Each module is independent and can be used on its own, but it also plays together very well. And each module has a nice and very natural DSL. For example, if you know SQL, you already can read this query:

Ecto.Query.from(p in MyApp.User, where: p.last_name == "Smith") |> MyApp.Repo.all

  • In most of the languages, when you write tests, you write functions or calsses, inside all dome magic fundtions or methods to assert something… But not in Elixir. In Elixir, you have ExUnit which is so natural way to write tests. For example:
  test "the first user is always admin" do
    assert get_user_role(1) == :admin

+ The same for HTTP endpoints. Usually, you have functions which you register later (or decorate) for expected HTTP methods and paths. In [Plug](, you kinda just do what you need right away:

```get "/hello" do
  send_resp(conn, 200, "world")

forward "/users", to: UsersRouter```

+ [Temple]( is a DSL for HTML. Which is, again, very natural if you know HTML (but less repetitive):

```temple do
  h2 do: "todos"

  ul class: "list" do
    for item <- @items do
      li class: "item" do
        div do: item

The elephant in the room is that in Temple you still have all these soup of `end`'s at the end instead of closing tags. Python-style blocks are easier to read but in Elixir you have Ruby-style `do-end`. The motivation is that because of macros and all that stuff the parser needs to be able to recognize code block without knowing the context. For example, in Python, `if` is always a test expression and then a block to execute (which can be on the same line as any other block but it's still a block). In elixir, `if` is just a macro (a function) in which you pass `do-end` block as the second argument.

+ [Re]( is my first Elixir library, a DSL for regular expressions:

```Re.one_or_more(Re.Chars.any_digit) |> Re.compile```