The key point is: you cannot use a value to represent the absence of
a value, at least not as a generic methodoly.
So, if you need to return any value + error, you need more than one
value (like 'pcall' does) or some other mechanism besides returns (like
'error'). That is a fact of life, and we are not going to solve it
by throwing more values/non-values/semi-values/error-values into the
language.
In one sense this is of course true by definition, but in another sense I think it’s just a case of moving the goal posts around. The fact is the concept of an “error” indication is an item of information. Whether this information is represented as an out-of-band data value (e.g. -1), the presence/absence of an additional return value, or the transfer of control to another location in the program (pcall) seems to me more a matter of style. In other words “i have an error because a value/type is xxx” and “i have an error because i reached this line of code” are really just different ways to express the same thing. From that standpoint I don’t see error() as any more (or less) logically fundamental that an explicit error type or value representation; they are both ultimately conventionalized ways to indicate the same thing.
It is of course true that one style might be perceived as more convenient or elegant than another, but that is a matter of taste and is probably why people get so passionate about error handing methodologies.
—Tim