One attrs param vs multiple named params?

Hello folks,

I often see attrs being used as parameters throughout Elixir code examples. Is there any rhyme or reason as to when it is more idiomatic to pass everything in as attrs vs breaking it into multiple named parameters? Should I be trying to pass only one large attrs map into my functions, or having multiple attrs for each struct type, such as def add_book_to_user_library(user_attrs, book_attrs, author_attrs)?

Thanks in advance.

2 Likes

The approach in my team is to use at max 3 parameters for a function.

My personal reasiong is that I like to use pipelines and a single parameter object makes this easier, as I can put the logic what parameters to use in its own clause andmake the business logic easier to read (for others and future me)

Usually attrs is only used in phoenix controllers or when it is considered an opaque value that you pass down in the call pipeline, eg to a callback.

In rubyland I have seen similar rules which then have been followed religiously, which lead to the last argument beeing a map and bad error messages when a key in the map was missing.

In Elixir we would even get a proper error message by the compiler if we forgot an argument in a 7 arity function.

If course, one should avoid having functions with high arity in the public API, as they make it hard to grasp the API, still, if it makes sense to have a function with 5 arguments, make it 5 arguments rather than 2 of which one is a map that wraps 4 of the arguments!

5 Likes

I think this is a generally good rule of thumb. I am more strict about this with public functions vs private functions though. Private functions, particularly if you need to manage optimized manual recursion, can end up with a higher arity.

5 Likes