in the same way you define a lambda function when you do not need a named one

The difference being that you cannot inspect a lambda. You never pull data out of a lambda, only run it. Since tuples are something you have to read back out again, being nudged to name those things makes sense.

Removing the ability to have more than 3 parameters in a value constructor of a custom type seems completely arbitrary.

It isn’t though. It’s a common theme in books and best practice tips to get the number of function arguments down to three, preferably one or two, because after that it becomes very difficult to remember what order the argument goes in, especially if they’re all the same type. Both Uncle Bob’s Clean Code and Effective C# comes to mind, though I’m sure there are others. The same argument applies to tuples and custom types.

Why not also prohibit function names that are less than 5 characters long?

Functions are, amongst other things, often used as getters and setters. x is a perfectly valid name in a record to represent the x coordinate, so x would also be a perfectly fine function name for a getter function.

Or 4-level nested records? Surely you should use a flat data model.

This would actually limit what you could do with the language, my proposal (with the exception of pattern matching in records, which I did say I forgot to account for) would only make it harder to let code grow without thought.

While a flat data model does make the code easier in general, it can be easier to reason about a nested structure.

There are also performance reasons to nest instead of keeping things flat.

Is it really the job of the compiler to try to eliminate what you might consider “code smells”?

On this point I’m sure we are both thinking yes. Elm is staticly typed and enforces pure functions because the compiler also serves as a strict linter.

Or would you say that when all functions in your program can accept any type isn’t a code smell? Or that it isn’t a code smell that every function in your program can perform side effects?

I’m sure that we both are using Elm because it eliminates a bunch of code smells enabled in other languages. What we’re discussing now is if a custom type which contains 4 or more parameters should be named or not.

would be tenable if records actually supported pattern matching in things like case statements. Unfortunately they do not, so this is really a non-starter.

What if records had better pattern matching support?

Finally I would like to add that there are languages where custom types supports at most one parameter, and if you wanted to store more in it you would have to use tuples or records. It could very well be that three is too big a number and that it should be two or even just one.

I do agree that pattern matching on records would have to be better for my suggestion to be feasible, which is something I’ve admitted to overlook.