error type((tab[index])), 'unsupported type'
end
function fun3(tab, index)
return nil, FIXME(type((tab[index], 'bad type of element in table')))
end
The extra parentheses around the parameter(s) given to type() look very tricky! A programmer (or an IDE) may think that these parentheses are superfluous and would discard them.
I don't see ANY benefit or any use for the error generated by "type()" when it's called without any parameter, it should just simply return nil. Using type() in Lua is very common for functions already making complex conditional execution based on the types of objects it accepts and inspects (these may be complex analysis using recursion inside tables, inspection of metatables, inspection of function environments, and so on).
These "dummy" parentheses are quirky. Some programmers use extra parentheses everywhere which do not clarify the code, when there are deeply nested in expressions and are not even needed such as:
if (((a == 1) and (b == 2)) or ((c == 3) and (d == 4)) then ... end
which is simply:
if a == 1 and b == 2 or c == 3 and d == 4 then ... end
[note]
Programmers should know or learn the priority of operators used in expressions...
Add function calls like type() and you have too many parentheses and it actually gets harder to guess visually how they are paired to create subexpressions.
We see lot of those dummy parentheses also in other languages. Including in C/C++ with the false assumption that these parentheses for subexpressions would force their order of evaluation, and we have IDE's using refactoring tools that will help to automatically remove all those unneeded and indesirable parentheses
[/note]
I just hope that IDE's or program editors (if they are used for Lua and know its syntax) will know that parentheses around Lua function calls are important: these "dummy"-like parentheses must be preserved when the closing parenthesis is not immediately followed by a comma, or by another operator, or by another closing parenthesis ")" or bracket "]".
This exclusion of the comma is also not effective when a function call between these "dummy" parentheses is followed by a trailing comma inside a table constructor. So the following does not work:
table1 = { 1, type(_expression_) } -- may generate a runtime error
We must use:
table1 = { 1, type((_expression_)) } -- or equivalently
The last two statements do not
always
add any extra value at index [2] in the table (which may then contain one or two items), but the _expression_ given to type() must still be evaluated. Can you guess a simple and reliable rule to know which dummy parentheses can be safely removed???
Instead of using extra "quirky" parentheses around the last parameter of type() to avoid the error, I think it's better to follow it by ",nil":
table1 = { 1, type(_expression_, nil) } -- or or equivalently
table1 = { 1, type(_expression_, nil), }
But some programmer communities may have different rules about their preferred style, and will think that appending trailing ",nil" to parameters of function calls is also quirky (or bad style) and can be safely removed (this is not the case), or that it will optimize the generated code (avoiding the extra push of a nil value on the stack) by assuming that the function never needs to explicitly have final nil arguments, except possibly in the 1st argument.
But all these are equivalent, including those with trailing ",nil":
table2 = { 2, _expression_ }
table2 = { 2, _expression_, } -- the trailing comma has no effect
table2 = { 2, (_expression_) } -- parentheses have no effect
table2 = { 2, (_expression_), } -- idem
table2 = { 2, _expression_, nil } -- idem
You cannot guess here how many items are in table2 (it could be 1, 2, or more). But here you you that there will not be more than 2 items:
table3 = { 3, (_expression_), nil }
The item in table3 at [1]=3, the item at [2] is the 1st result of the _expression_ or nil, all items at [3] or higher are nil