Language Idea: Limit custom types to three arguments

robinheghan profile image Robin Heggelund Hansen ・2 min read

Language Idea is a new series where I note down some ideas I have on how Elm could improve as a language. Each post isn't necessarily a fully thought out idea, as part of my thinking process is writing stuff down. This is more a discussion starter than anything else.

In Elm 0.19 you can no longer create tuples which contains more than three elements. The reasoning behind this is that it's easy to lose track of what the elements represents after that. As an example:

(0, 64, 32, 32)

Is a bit more cryptic than:

{ xPosition = 0
, yPosition = 64
, width = 32
, height = 32

The rule here is quite simple, if you feel yourself in need of a tuple containing more than three elements you're better of using a record with named fields.

There is, however, another way in which you can work around this restriction in Elm 0.19.

Custom Types

Yes. Custom types can still contain more than three parameters. Which is strange, as there is little to separate tuples from custom types with the exception of syntax and comparability.

Let me be clear though, you should prefer records with named fields. Names provide basic documentation, and records let you forget about what order parameters are in. I'd say that even when you're using custom types, you should always limit them to three (maybe even two) parameters and use records if you need more than that.

As to why Elm allows more than three parameters in custom types; I don't know. It might just be an oversight.

So here is a question: should Elm limit the number of parameters in custom types to three, as it does with tuples?

I think it should.

Edit: The idea here is that one can do type Person = Person { name : String, age : Int } instead of type Person = Person String Int as it would make it more obious what each parameter is. It should then be encouraged to use records within custom types if there are many fields to store within the custom type.

Posted on by:


Editor guide

There is a very good rule of thumb, the zero, one, infinity rule. The main point is, that if you put random limitations (ie not forbidding or allowing just one, but more than one but not more than x) this limitation will always feel abitrary.
This is one of the many reasons why I would never consider elm for production use, the language is working against you and your domain.


This idea is only there to make it more explicit what your code does. There's nothing here that limits what one can do with Elm, so I don't understand what about this make you uneasy to use it in production?


Because this looks like a linter's job.
It's absolutely unacceptable that you can't just jam in one more parameter but must refactor all existing sites first.


more than one but not more than x) this limitation will always feel abitrary.

The is a limit to how many things can a person keep in working memory at the same time. This limit is around 4 for most people. So, 3 is a good number as it still leaves some space. It is not arbitrary. Joining things into a record would "chunk" them and turn them into one thing.


I think this is the kind of rule that should be a convention, not a hard limit enforced by the language.


Life will already penalize us for using too many parameters, because they become hard to manage. It seems like further limitations are unnecessary. If the dev does not learn from life's natural feedback loop, they probably won't learn from this limitation either. (1, 2, 3, 4, 5) will just become (1, 2, (3, 4, 5)) in 0.19. Case first second third forth fifth -> becomes Case first second (CaseInner third forth fifth)) ->. This (and the tuple) restriction seems pretty arbitrary. And arbitrary restrictions tend to be the least-loved kind.


As far as I know, custom types with more than 3 parameters is the way to pattern match against more than 3 conditions. I don't have a readily available example BUT I remember Evan suggesting this as a workaround. Removing this facility would force people with that need to use cascading case statements.

Business logic can sometimes be crazy complex.

A change like this might be beneficial even in those complex cases as it might force a redesign that might improve the comprehension of complex code BUT still, it needs to be well thought out.


I agree. I have several examples of that, just check out the Dict implementation in elm/core.

So my suggestion isn't really feasible unless records get better pattern matching. But I guess that has it's own downsides? :/


You can still have an arbitrary number of arguments by using tuples of tuples of tuples though. But it's a good principle, I use it when I have more than one parameter actually.