Llixer - lispy syntax of the Elixir ast

ExSpirit started like that, and IMO is the best elixir parse I’ve seen (It’s actually the best parser I’ve seen anywhere lol). And now literally all my published packages use it :stuck_out_tongue: (and the next one to come out will use it too).

Lol, ExSpirit I made for an actual use actually, I need to parse this weird-as-frick custom proprietary format of something at work (that needs special cases piled on special cases), and I know the C++ Spirit library very well (I used to work ‘on’ it) and none of the Elixir libraries did what I needed, so… I remade it.

Now I did not really intend to publish it as it was primarily just for my use, but it became useful for other things and putting in on Hex.pm was the easiest way to store it. ^.^;

1 Like

@OvermindDL1

Asking here to avoid derailing the comma thread even more:

I’ve actually been played with an idea to do a Staged compilation pipeline of LISP, this is how macro systems work in most languages (not lisp’s) and although it is ‘slightly’ more limiting, it allows me to output (even typed) ‘final generated code’ much more easily.

1 What is a Staged Compilation Pipeline? Is it something in which you have lots of intermediate representations with different type between the source and the generated bytecode? From what I understand this is different from Lisp because lisp simply expands the AST recursively, right?

  1. How does that help in producing typed code?
1 Like

In the context of, say, Elixir Macro’s it is where the source is parsed first, then macro’s are expanded recursively, then final code is generated.

What Lisp traditionally does is parse, then for every ast branched fully parsed it executes the function within it, which might be a macro that outputs a new AST to then run (and keep running until no macro is returned but rather a normal function call). It basically ‘runs as it reads’. In my simple one I broke it up into 2 stages, a parse + macro expansion, then an execution (and that is mostly just because I wanted to introspect the output to see how it looked. ^.^;

However, having the multiple stages is easier for typing as it allows you to look both up and down the callstack to be able to reify types that way instead of only being able to do the immediate level (which is why Typed Lisps’s traditionally use C-style typing instead of ML-style).

1 Like

Is this visible to the end user? I’d like o be able to pretend that this is “normal lisp” xD even though it’s actually super advanced ML disguised as Lisp disguised as Erlang.

And why do several stages help? Couldn’t you go up and down the callstack in the fully expanded AST? Or do you want the macros themselves to be typed?

1 Like

Same way it is visible in Elixir, there are distinct pipelines and they ‘appear’ in certain areas in how macro’s and normal functions can or cannot be called in certain contexts. ^.^

Nah, no point in typing the macro’s, however it would be useful to pass in the macro’s typed code so they could do different things depending on what types things will end up being, which is a huge capability boost right there. :slight_smile:

1 Like

Could you please give a practical example?

That’d be pretty cool for optimization (C++ style), bit because of late module binding and because it’s impossible to inline calls accross modules it’s probably not that useful…

1 Like

Well say you want to re-implement protocols, so you build up a protocol set of implementations at compile-time, then you call whatever function in it (let’s say compare/2), it can use the static types to purposefully inline things, say it can check the calls passed in and see if they are trivial (a single expression or two) then can inline it straight since it knows the types there at compile-time, thus having not even a single function call of overhead. ^.^

1 Like