How common is it that people pass in an empty list?
If it is common (and for instance the parameter is expected to often be based on dynamic user input, rather than programmer-written code), I’d use an error-tuple (or maybe a nil, see below), since it is a common error.
If it is very uncommon, (i.e. only occurs in ‘exceptional’ situations, for instance when a programmer mistypes input parameters), I would use an exception, which means that the average user is not burdened with having to handle it.
Using nil only makes sense if there is one and only one(!) way of your function to return a ‘useless value’ result, and if you do not consider passing inputs that produce this useless value an error. This might actually be true for passing in [] to your statistics function. As soon as there are multiple ways to get a ‘useless value’ (for instance if you have a container that might contain nils) then don’t use them, since their meaning becomes ambiguous.
So: Exceptions for programmer mistake, errors for user mistake or context problems that keep you from continuing, nil if there is exactly one, clear, way to get a ‘useless value’.
value | {:error, reason} is definitely a bad idea. Any of the three listed approaches (nil, ok/error, raising exceptions) is better, because they are consistent in what they return.


















