Search⌘ K
AI Features

Getting Domain Specific

Explore how to create an HTML domain-specific language using Elixir macros. Understand the benefits of DSLs in making code clearer and closer to your problem domain. This lesson guides you through building an HTML DSL and when it is appropriate to use this approach.

Why use domain-specific language?

One of the most powerful ways to use macros is to build domain-specific languages (DSLs). DSLs can create a custom layer in the language to attack problems closer to our application domain. This can make our code easier to write and make it more clearly represent the problem being solved. With DSLs, we can codify our business requirements and operate at a shared level of abstraction with the callers of your library.

Creating an HTML DSL

Let’s extend the tools we’ve learned so far to create an HTML DSL by completing the following steps:

  • First, we’ll introduce domain-specific languages.
  • Second, we’ll build a complete HTML DSL that generates templates from pure Elixir code. During this process, we’ll uncover a few advanced macro features and learn how to apply them.
  • Finally, we’ll review when and when not to use DSLs and ways to decide if they are a good fit for our library.

How DSL works in Elixir

Before we start coding, let’s look at what DSLs are all about and how metaprogramming makes them so easy. In Elixir, DSLs are languages defined by custom macros. They are a way to build a language within a language for solving a specific domain problem. In our case, our domain is HTML generation.

You may have experience with HTML generation in other languages where the string of HTML is produced by mixing source code within markup, parsing the file, and evaluating the result. These solutions work, but we often have to leave pure source code behind for a different template syntax.

This requires yet another syntax to learn and context-switching between languages as we write our program.

Creating an HTML DSL in Elixir

Let’s suppose if instead of parsing an external file, we could write regular Elixir code that expresses the HTML specification. The result of running the code would produce a complete HTML string.

Let’s see what such an HTML DSL might look like with macros:

Elixir
# Defining a markup macro that has a div component with h1
markup do
div class: "row" do
h1 do
text title
end
article do
p do:
text "Welcome!"
end
end
# If the page is accessed with a logged in user, show an "Edit" tag.
if logged_in? do
a href: "edit.html" do
text "Edit"
end
end
end
# Output:
# "<div class\"row\"><h1>Domain Specific Languages</h1><article><p>Welcome!</p>
# </article><a href=\"edit.html\">Edit</a></div>"

Since macros are first-class features, we can imagine a macro per HTML tag that generates the necessary HTML string for a tree of tags. This example program is a complete domain-specific language.

Any user who glances at the code would immediately understand the HTML specification expressed by the source. Such a library would allow writing HTML and Elixir in the same context, leading to interesting solutions. We’ll build such a library in the next lesson.