arashm

arashm

When to use Struct?

I read the “Programming Elixir” book, here is quote from the book:

At some point, the old object-orientation neurons still active in the nether regions of your brain might burst into life and you might think, “Hey, this is a bit like a class definition.” And you’d be right. You can write something akin to object-oriented code using structs (or maps) and modules.
This is a bad idea. Not because objects are intrinsically bad, but because you’ll be mixing paradigms and diluting the benefits a functional approach gives you.

Having this in the back of my mind, today I’m making a simple app which relies on data comes from a JSON API. The data structure is deeply nested and the API on different end-points uses different keys for same objects (imagine in one it returns name in another it returns title). So I thought I’d convert those JSON data to different structs and define a to_normalized_struct function in those to convert them to a struct that provides a same interface to be used through out the app.

But then… I thought maybe I’m coding OO here and may face wrath of functional programming gods later. So when is right to use structs? How would you implement the code for above problem?

Most Liked

slashdotdash

slashdotdash

A useful comparison of structs and maps is made in When to Use Structs, String-keyed Maps, and Atom-keyed Maps.

It lists six rules governing the best practice usage of these data structures.

  1. Always Use String-Keyed Maps for External Data.
  2. Convert External Data to Structs ASAP.
  3. Use Structs in All Other Code.
  4. Use Structs for Output Data.
  5. Avoid Using Atom-keyed Maps That Aren’t Structs.
  6. Use Keyword Lists Only for Function Arguments
bbense

bbense

My 2 cents. The way out of the OO trap is to think data and transformations.

I can’t answer your specific question w/o knowing the larger context, it might make sense to simply create a transform function for each JSON type to a standardized data form. Or it might make sense
to avoid the central form and just make transforms that extract the data you need.

The way to answer that question is to think about any transforms you need for the resulting data. What data structure makes the most “sense” in your problem? Rather than modeling “things”[1], start thinking about transforms and the inputs and outputs they need.

The Struct construct handy in that it provides both an easy to read access syntax and it constrains your transforms to a specific set of keys in a Map. However, the problem with Struct is the dual of it strengths, you lose the ability to dynamically change the structure of the data as the problem evolves. Struct requires that you “model” the problem in advance. This is not a terrible thing; in fact the strong type people would claim this is a very good thing. It does take away some of the flexibility and power of a dynamic language.

So as a practical guide, I’d suggest that if you are either constantly adding fields to your Struct or creating many slightly different, but almost the same structs, then you probably don’t understand the problem well enough yet to use a struct. The other thing to be aware of is that Struct only constrains the keys, not the values. If you find yourself putting wildly different values under the same struct key, then you’re probably in the weeds.

[1]- Experience suggests this is also the source of most problems with OO design as well.

AstonJ

AstonJ

I am just going through the Elixir and Phoenix Bootcamp course and in my notes I have written:

Structs

Just like Maps but with 2 advantages:

  • Can be assigned default values
  • Additional compile-time checking of properties

If we know the properties we are going to be working with we will use a Struct instead of a Map.

Where Next?

Popular in Questions Top

tduccuong
Hi, is there any work on GUI with Elixir, that is similar to Electron/Javascript? My idea is to bundle Phoenix and BEAM into a single se...
New
9mm
I am constructing a JSON object (map) and I need to conditionally set a field. I’m trying to write proper elixir-way code… and I’m at a l...
New
aadeshere1
I have a another noob question about loop. Since elixir is immutable, while loop is not directly possible. total = 10 while total != 0 ...
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
hariharasudhan94
lets say i have a sample like a = 20; b = 10; if (a > b) do {:ok, "a"} end if (a < b) do {:ok, b} end if (a == b) do {:ok, "eq...
New
nobody
Hi! In PHP: $SERVER['SERVERADDR'] - in Elixir? Searched the docs for ip address and the web, no good results. Thanks!
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
Brian
What is the proper way to load a module from a file in to IEX? In the python world, doing something like this pretty standard: from ....
New
WestKeys
Currently suffering from paralysis by [HTTP client] analysis. This is rather unusual in Elixirland as there tends to be consensus on the ...
New
marick
I had some trouble figuring out how to make many-to-many associations work. Once I got it working, I wrote a blog post. Because I'm a nov...
New

Other popular topics Top

sorentwo
Hello! tl;dr Announcing Oban, an Ecto based job processing library with a focus on reliability and historical observability. After spen...
985 42842 311
New
AstonJ
Posting this to see if we can make things easier for people to get into Neovim. If you use Neovim and have a favourite distro please let ...
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
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
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
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
boundedvariable
I am going through the kafka architecture. All the features what the kafka is providing are already in Erlang. I would like hear your opi...
New
joaquinalcerro
Hi there, I am working with Ecto-Postgresql and I need to call all of the records from a specific table but the table has 40,000 record...
New
PeterCarter
There are pre-rolled solutions for other frameworks that do work. However, Phoenix does not seem to have these. Have people had good expe...
New
lanycrost
Hi everyone! I need implement if…else if…else condition from my elixir code, and anymore of this control flow structures not work proper...
New

We're in Beta

About us Mission Statement