Sebb

Sebb

I just tried to create a struct without fields (because: why not?).
It’s not possible with defstruct, which insists on an argument.

Best it can do is

defstruct _: nil # nice

btw, this is not OK:

defstruct [_]

isn’t that inconsistent?

So I tried to figure out what defstruct does. From the docs:

To define a struct, a developer must define both __struct__/0 and __struct__/1 functions. defstruct/1 is a convenience macro which defines such functions with some conveniences.

Where are __struct__/x documented?

Structs are usually defined with the Kernel.defstruct/1 macro

What if I want to be unusual? How can I define a struct by hand, maybe even without fields?

Showing Posts 1 to 7

dimitarvp

dimitarvp

…but what’s your goal?

Sebb

Sebb OP

to create a struct without fields :upside_down_face:
Actually I really think I have a use case, but the main point is: just being curious.

NobbZ

NobbZ

Using an empty list as argument to defstruct/1works for me:

iex(1)> defmodule S do
...(1)>   defstruct []
...(1)> end
iex(2)> %S{}
%S{}
sheharyarn

sheharyarn

Like @Nobbz said, you can just do this:

defmodule X, do: defstruct []

The reason this doesn’t work is that you cannot assign _. The first example works because :_ is not _, so you can do defstruct [:_] which is equivalent to your first example.


This is the macro that’s called underneath when defining a new struct. Going over the definition should help you better understand manually defining a struct in a module.

daskycodes

daskycodes

One way to define a struct is to use a simple map with the __struct__ key

Let’s say we have a module StructWithoutFields

we could call

iex> %{__struct__: StructWithoutFields} |> is_struct()
true

This will be a struct but we won’t be able to call %StructWithoutFields{}

The next step I’d suggest is looking into the macro implementation like @sheharyarn suggested.

I left a lot of parts out in the following example but this might give you an idea

defmodule StructWithoutFields do
  @struct %{__struct__: __MODULE__}

  def __struct__(kv) do
    Enum.reduce(kv, @struct, fn {key, val}, map ->
      Map.replace!(map, key, val)
    end)
  end

  def __struct__() do
    @struct
  end
end

With that module you will already be able to call

iex> %StructWithoutFields{} |> is_struct()
true

If you haven’t read it yet I can really recommend reading Metaprogramming Elixir: Write Less Code, Get More Done (and Have Fun!) by Chris McCord
It goes into a lot of detail on how macros work and how basically a lot of elixir is build upon macros

Sebb

Sebb OP

thanks for the great advice, can’t fully understand the defstruct-macro yet, but I’ll take a look at the book. (feeling a little too stupid for that right now, not having thought about defstruct []).

aiwaiwa

aiwaiwa

One legitimate reason would be to implement a protocol without data.

Use case: postgrex/lib/postgrex/parameters.ex at v0.16.5 · elixir-ecto/postgrex · GitHub

— 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
peck
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
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
bradley
I really like the adapter patterns that ecto, nebulex, waffle, etc. use and would love find something similar for a key management servic...
New
unaware8150
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
Alvinkariuki
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 Top

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
KristerV
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
mudasobwa
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
jimsynz
Beam Bots (or just BB for short) is a framework for building fault-tolerant robotics applications in Elixir using familiar OTP patterns. ...
New
juhalehtonen
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
budgie
I love Elixir. It’s one of 2 programming languages I’ve ever fallen in love with. But I don’t use it anymore. Serverless was the promis...
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews