hst337

hst337

How to get an AST and Macro.Env of a function by name and arity?

Summary

Is there any way to write a function which can be invoked in compile time and which can return an AST and Macro.Env of given function.

Example

We have a module

defmodule MMM do
  def fff(x), do: x + 1
end

And we can execute some function in compile time which will work like

iex> Macro.get_ast(MMM, :fff, 1)
{
 {:def, [context: Elixir, import: Kernel],
  [
    {:f, [context: Elixir], [{:x, [], Elixir}]},
    [do: {:+, [context: Elixir, import: Kernel], [{:x, [], Elixir}, 1]}]
  ]},
  %Macro.Env{}
}

PS

I know there is no such function, but how can something like this be implemented? What problems should I expect while implementing this function?

Most Liked

ityonemo

ityonemo

this is possible using Elixir compiler tracer hooks. I am pretty sure it broadcasts the AST and __ENV__ of a function being compiled.

Worst case scenario, collect em’ all, serialize them using :erlang.term_to_binary, and then stash everything into some file in /priv

OvermindDL1

OvermindDL1

In the erlang side things like -compile({inline,24}). are specified to inline module-local functions with a given weight or less, 24 is the default weight, so most ‘shortish’ functions will get inlined directly and always. It can be overridden though with a different weight, like 1000 if you want to inline almost everything, or you can force inline specific functions by giving it a list.

Do note though, inlining larger can help with some optimizations, but overall it usually doesn’t and it’s best to leave it at default as the size overhead doesn’t help the speed at that point, and calling module-local functions require no indirected call so their only cost is a stack frame at that point (if that’s even needed).

OvermindDL1

OvermindDL1

Such a function like that doesn’t exist because the AST is long long gone at that point. You could always make your own macro, say defmodulex or so and just use it instead of defmodule and have it build a new hidden function called __ASTS__/1 where you pass it an option of what to return and it can return the AST for whatever you asked for. Basically compile the compile and add in that function that just returns the AST of the module that was passed in?

Better question though, ‘why’ do you want it?

Where Next?

Popular in Questions Top

vertexbuffer
Hello, can anybody help here..? I have a list of players and I what to delete an element, but every for loop the list is reverting to ori...
New
vonH
In asking this question I am more interested about the expressiveness of the language itself and less concerned about the availability of...
New
stefanchrobot
What’s the safe way to decode a JSON string into a struct? I want to avoid calling String.to_atom. Jason.decode can give me a map with st...
New
komlanvi
Hi everyone, I was playing with phoenix liveView but I run into an issue. I have a form and want to validate each input text when the te...
New
bsollish-terakeet
Credo is smart enough to check for (something like) this: assert length(the_list) == 0 with this response: Checking if an enum is empt...
New
jerry
Good day to you all. I have been struggling to get a query involving like and ilike to work. Can anyone assist me on this, please? pro...
New
aalberti333
As the title describes, I’m trying to run Enum.map() over a list of key/value pairs, where the value is a map. My data looks like this: ...
New

Other popular topics Top

nobody
Hi! In PHP: $_SERVER[‘SERVER_ADDR’] - in Elixir? Searched the docs for ip address and the web, no good results. Thanks!
New
hariharasudhan94
Lets say I have map like this fetching from my database %{"_id" => #BSON.ObjectId<58eb1a7a9ad169198c3dXXXX>, "email" => ...
New
ashish173
I am using Ecto timestamps with postgres, I can see the timestamps() use the :naive_dateime but for my use case I wanted to store the ti...
New
sen
Hi All, I set a environment variables in dev.exs , like below code. when i start server, how can i set the ${enable} value? thanks. d...
New
sergio_101
I am VERY much an elixir newbie. I have taken one elixir course and one phoenix course on Udemy. During that course, I saw the instructor...
New
AngeloChecked
What learn first? Rust or Elixir Hi Elixir community! I’m here because i want learn a new language. I’m a junior developer and mainly i ...
New

We're in Beta

About us Mission Statement