Oliver
I’m generating a module from a macro, like this:
defmodule WhereTheMacroIs do
defstruct [:same_for_all]
defmacro generate(name) do
quote do
defmodule unquote(name) do
def simplified_example(%WhereTheMacroIs{} = msg), do: msg.same_for_all
end
end
end
end
defmodule WhereIUseIt do
require WhereTheMacroIs
WhereTheMacroIs.generate(SomeOtherName)
def test, do: SomeOtherName.simplified_example(%WhereTheMacroIs{same_for_all: 42})
end
The problem I get is that the struct %WhereTheMacroIs{} will be name-expanded to %WhereIUseIt.WhereTheMacroIs{} when expanding macro WhereTheMacroIs.generate/1 - which is not what I want. I want all generated modules to use the same struct internally.
I googled for a while but I was unable to find a way to suppress this extension of the struct name.
This seems to happen even if an alias is used or not.
I’m using elixir 1.6.
Trending in Questions
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
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
Hi everyone.
My team and I have been working on a fairly modest app based around video streaming and chat, but we’ve landed a customer t...
New
I really like the adapter patterns that ecto, nebulex, waffle, etc. use and would love find something similar for a key management servic...
New
Hello folks!
So at work, we are seeing some situations where we have to define some “fixed” strings that are used across the codebase in...
New
I’m working on a small exercise involving update_in/3, and I came up with this solution:
data = %{
name: "Periodic Table",
category:...
New
How Can I Optimise Compile Time Dependencies
I have been building an elixir application for about 2 years now. Many modules and files ha...
New
Other Trending Topics
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
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
Hey. Is there anyone here who creates agents in their apps? Not talking about using agents, but creating them. I’m finding it pretty diff...
New
I fully migrated to my own harness from Anthropic/Gemini and I think it’s time to share it. Welcome DSH, the DeepSeek Harness, fully writ...
New
Beam Bots (or just BB for short) is a framework for building fault-tolerant robotics applications in Elixir using familiar OTP patterns. ...
New
There has been a thread to discuss the Stack Overflow Developer Survey on this forum every year since 2018, so here’s yet another one for...
New
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #library
- #deployment
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #elixirconf
- #channels
- #exunit
- #discussion
- #code-sync
- #podcasts
- #javascript
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #ai
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #blog-post
- #elixirconf-us
- #elixir-ls
- #phoenix_html
- #iex
- #graphql
- #genstage
- #websockets
- #supervisor
- #advent-of-code
- #distillery
- #processes
- #elixirconf-eu
- #api
- #forms
- #security
- #metaprogramming











Showing Posts 6 to 1- Show Best Posts
- Show All (oldest first)
- Show All (newest first)
Oliver
Hi, dimitarvp.
I actually wanted to re-use the same struct definition in each module - not the
defstructstatement but simply the struct itself.I ended up doing something like below to achieve my goals. This is not what I was working on but follows the same principles:
The data structure itself (SimpleTree) is given, but operations on the actual values can still be generic and overridden. One can define only the parts that change in another module - here the order of elements. How the tree is built doesn’t change, but what kinds of values are in it and how they are ordered can be defined by the user.
In my own project I aimed to re-use the equivalent of
%SimpleTree{}because the complex data structure will remain the same while the types and operations on the leaves needed to be flexible. The problem I encountered was that when puttingdefmodulein aquoteblock that the struct names expanded to include the names of the enveloping module. (NobbZ’ advice about prefixingElixir.solves that particular issue.) But in the end what I wanted to achieve was easier done by a construct like I shared above - it just took some re-thinking my approach.For the sake of example I implemented two different kinds of operation:
add/2: Needs a functionorder/2defined in the module whereuse SimpleTreeis done. It must be defined inside the__using__/1macro.to_list/1: Depends solely on the structure of the data itself. It can be effectively defined outside the__using__/1macro. (So I actually pull it in withdefdelegateinstead of defining it inside the macro.)Both re-use the
%SimpleTree{}struct - it is only defined once. No multiple definitions of the same struct even if used in different modules. ModuleSimpleTreeknows nothing much about the data inside the value field - except that it is not another%SimpleTree{}struct (because that would break the algorithms). All the specifics regarding the actual values inside the tree are externalized to the one invokinguse SimpleTree. This makes it a similar pattern to C++ generic programming.(I didn’t compile my example, it was just the best I could think of when trying to show what I was trying to actually do.)
dimitarvp
Okay, but why would you want to duplicate the same
structdefinition in every module? Shouldn’t it stay defined only once and just be used by the generated modules?Maybe I misunderstand but it does look like you are trying to copy the same struct definition for each module.
Oliver
Thank you.
I also figured it might be less problematic to only define function defs in the
quoteblock instead of adding thedefmodule- I’ll probably refactor to something more like the__using__/1macro in GenServer.Thanks for the tip with the
Elixir.! I saw this somewhere but it didn’t click in my brain…As for the bureaucracy… To unroll a new elixir version to our central infrastructure I would have to go through hoops involving one or two months time of waiting, and so far 1.6 has proven to be a quite blessed version.
NobbZ
Oh, I do only realize now that you use the
defstructoutside of the module.So you can either use
unquote(__MODULE__)(if I remember expansion rules correctly) or useElixir.WhereTheMacroIsto specify fully qualified module name.It wouldn’t solve your problem, yes. But I never understood the bureaucracy behind the staying outdated philosophy… Though I have to deal with it quite often due to my day work… One of our customers is still using Java5…
Oliver
I can’t update easily. Bureaucracy reasons, unfortunately. (Also, would that solve my problem…?)
This was a simplified example. In the concrete example I have a central data structure - the data type does not change. So I want to re-use the struct for it. I still can combine the same structure with different callbacks (given as macro params) and define this under a new name.
The example already allows injecting a name to each expansion of generate/2 anyway, so name collisions are excluded. But my real problem is the struct.
NobbZ
You should update.
I do not understand. So you want to call
generatetwice and it shall generate the same module twice as well? This will cause warnings during compilation and also can cause weird races when the modules happen to have the same name, but different Implementation.