Oliver

Oliver

DSL options within elixir modules?

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!

Most Liked

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.

Where Next?

Popular in Questions Top

shahryarjb
Hello, I get Persian date from my client and convert it to normal calendar like this: def jalali_string_to_miladi_english_number(persi...
New
senggen
Erlang/OTP 25 [erts-13.2.2] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] 15:22:35.803 [error] gen_event {lager_file_backend...
New
pmjoe
I have a relationship of love and hate with Elixir. Lots of things are just absolutely right, but there are some things that are kind of ...
New
gshaw
What is the idiomatic way of matching for not nil in Elixir? E.g., First way: defp halt_if_not_signed_in(conn, signed_in_account) when...
New
itssasanka
Hi all, Trying to get some more clarity over utc_datetime and naive_datetime for Ecto: https://hexdocs.pm/ecto/Ecto.Schema.html#module-...
New
Jim
As a follow up to my earlier question: I have the code compiling and running but not getting a successful login from the rest server. ...
New
qwerescape
Is there a way to get the call stack or stack trace at any point in the code? Not from exceptions, but an expression that returns how the...
New
kostonstyle
Hi all I want to have a unix time, from the current time plus 1 hour. DateTime.now + 1 hour How to get it in elixir? Thanks
New
chrisalley
ExUnit now has describe blocks which is a welcome addition coming from RSpec. In the docs, it states that nested hierarchies of describe ...
New
sabri
Can someone explain the settings of pool_size of Ecto in config file? and what is the recommend size? Thanks
New

Other popular topics Top

pmjoe
I have a relationship of love and hate with Elixir. Lots of things are just absolutely right, but there are some things that are kind of ...
New
axelson
This post is a wiki (feel free to hit the edit button near the bottom right of this post to add your own changes!) This post collects co...
239 45766 226
New
ycv005
I have followed this StackOverflow post to install the specific version of Erlang. And When I am running mix ecto.setup then getting fol...
New
SoCreat
i’m a new one to elixir which editor can i use vs code? or atom? Thanks! :smiley:
New
lastday4you
I wanted to check elixir version in phoenix because i found that my elixir is 1.5 but when i use Enum.chunk_by it said the function is un...
New
alice
Hey, Just curious what are the main benefits of Elixir compared to Clojure? When is Elixir more useful than Clojure and vice versa? Th...
New
baxterw3b
Hi guys, i’m new in the Elixir world, and i have to say, that i love it! i’m having some problem to understand anonymous functions with ...
New
chrisalley
ExUnit now has describe blocks which is a welcome addition coming from RSpec. In the docs, it states that nested hierarchies of describe ...
New
TunkShif
This post is an instruction guide to help you setup your Neovim for Elixir development from scratch. It includes general information on h...
273 38985 115
New
siddhant3030
Hi, I have to write a raw query for one of my project. But till now I have used ecto queries and don’t have much experience writing raw ...
New

We're in Beta

About us Mission Statement