Oliver

Oliver

As far as I can see, there are the following options for extending elixir with extensions or change the meaning of syntax:

The regular macros and the optional rules

So I can have my own macros with do-end blocks and rewrite any elixir code that is supplied within, like:

defmodule A do
  defmacro foo(do: block) do IO.inspect(block) end
end

defmodule B do
  import A
  foo do
     [1, 2, 3]
     x + y -> z
  end
end

So I’m allowed all elixir syntax in there and a few constructs like the -> but only within the typical limits how they are are used in elixir syntax itself. I could use the + and -> however to describe for example who syncs to whom or to describe a tree, do my own fancy flow control, etc.

It seems I cannot do:

defmodule B do
  import A
  foo do
    x -> y -> z
    1, 2, 3
    silly: :nilly
  end
end

So I cannot omit list brackets or use the -> more than once without line break or ; or have a keyword list while omitting brackets. (Please correct me if I’m missing something.)

So I could redefine to my heart’s content what elixir’s allowed constructs mean (or replace them arbitrarily) but not use its low-level primitives (comma lists without brackets, keyword lists without brackets, chaining the ->, etc). Do I understand it correctly?

[EDIT: I can see from examples I found since posting that I can get around some of these limitations by using the optional rules and faking a function call, so I could do this at least:

defmodule B do
  import A
  foo do
    something 1, 2, 3
    other silly: :nilly
  end
end

Because then the optional rules at least apply.]

Sigils

Anything in a sigil can pretty much be anything. I get a string and also what follows after the ending delimiter, and I can parse it in any way I see fit and if I do so inside a macro, I can even write code to replace the sigil.

So I could do this:

defmodule A do
  defmacro sigil_p(_, _) do
     quote do
       def silly, do: IO.puts("silly")
     end
  end
end

defmodule B do
   import A
   ~p"doesn't matter"
end

B.silly

So any of the allowed sigils could be used to inject a DSL anywhere in elixir, and since it allows a variety of delimiters, the sigils could emulate elixir constructs like lists in syntax and yet have additional or different semantics.

So I see these two mechanisms - which are undoubtedly powerful and very useful - and wonder if there are other ways to do this without writing such DSLs into separate files and let elixir be simply the compiler that transforms them into usable code.

I mean, I have no problem packing my custom syntax into sigils, but if the same could be done within a do-end block that would even be nicer.

To make it clear, I’m not complaining. I’m looking for all options to allow me to have more of my own syntax for my own DSLs, and this is what I found. If you know more, please share. :slight_smile:

Thank you for any feedback!

Showing Posts 1 to 2

zachallaun

zachallaun

I think you have the gist of it! The issues you’re running up against with the do/end block is a limitation of the parser, which has to use its knowledge of Elixir syntax to construct an abstract syntax tree that obeys syntax precedence, associativity, etc.

vfsoraki

vfsoraki

You’re totally right.

Macro is for when you can use Elixir’s syntax, but you want to (re-)define what’s the meaning of some (or all!) of operators/functions/arguments/…. . For example, ExUnit is a kind of DSL.

Sigils are bare strings, you parse it as you will. The most obvious example for me is Heex to embed HTML in Elixir files.

Maybe look at both of them to see how they work.

— All posts loaded —

Where Next? Top

Trending in Questions Top

katta
I having some trouble figuring out if I have set myself too strict of standards for my production server. Currently I can handle 75% of r...
New
brecabral
Documentation While reading the Scoped Routes section, I noticed that the documentation currently refers to a problem without explainin...
New
achenet
Hello, I’m trying to build a basic Phoenix web-app, and I’d like to use Tailwind. However, when I launch mix phx.server, I get an error...
New
kpanic
Hi everyone, I am toying with the idea of building a “match maker” for giving personal help to people that wants to start coding. I sta...
New
asweet-confluent
I recently noticed that Elixir’s Logger defaults its primary log level to :debug when no :logger, :level application configuration is pre...
New
Cxx-mlr
I’m working on a small exercise involving update_in/3, and I came up with this solution: data = %{ name: "Periodic Table", category:...
New
ChrisAmelia
I’ve got trouble wrapping my head around the order in which functions are called in this snippet (from Phoenix’s authentication): toke...
New

Other Trending Topics Top

GenericJam
Edit: 2026 May 15 - This post is archived. Mob is alive!! Main docs: mob v0.7.11 — Documentation A bit of explanation for the slightly c...
New
JesseHerrick
Hey, I’m Jesse and I’m the main contributor behind Dexter, a full-featured, lightning-fast Elixir LSP optimized for large codebases. It s...
New
mudasobwa
I am happy to introduce the very α version of the new programming language compiled to BEAM. Welcome Cure. It has literally three kille...
New
garrison
Hobbes is a low-level distributed database for the Elixir programming language. Hobbes provides a simple, safe, and scalable storage lay...
New
mhanberg
Hi everyone! The first release candidate for the Expert language server project is now available! We’ve published a press release detai...
New
budgie
A little off-topic, but I feel like people here have a good head on their shoulders. I used to be quite good at making software. Was luc...
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews