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
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.
- Always Use String-Keyed Maps for External Data.
- Convert External Data to Structs ASAP.
- Use Structs in All Other Code.
- Use Structs for Output Data.
- Avoid Using Atom-keyed Maps That Aren’t Structs.
- Use Keyword Lists Only for Function Arguments
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
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.







