lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


Dirk Laurie <dirk.laurie@gmail.com> wrote:
> 1. If the argument list always has a first element, there is no reason to
> stay with numbers. Anything for which less-than is defined can work.

This could be useful! Actually, if you asked me if this was already
the behavior, I wouldn't know it for sure.

Dirk Laurie <dirk.laurie@gmail.com> wrote:
> Oliver Kroth <oliver.kroth@nec-i.de>:
>> Is this so?
>>
>> I would expect the minimum or maximum element of the argument list to be
>> returned as result.
>> With an empty list, I would not be confused to get nil.
>
> It's the same principle by which when n<1,
>
>    1 + 2 + 3 + ... + n
>
> evaluates to 0  and
>
>    1 * 2 * 3 * ... * n
>
> evaluates to 1.
>
> max satisfies relationships like: max(a,b,c,d) = max(max(a,b),max(c,d)),
> no matter how you split up the arguments. For a consistent definition
> of max(), you need max(a,b,c,d) = max(max(),max(a,b,c,d)). But the
> only value of x for which always y = max(x,y) is x=-math.huge.

This is cute, but I think in practical situations math.huge and
-math.huge would end up most often be used as special values to signal
"there were no arguments", and then you wouldn't be able to tell apart
if math.huge was actually passed as an argument. To me, the least
surprise would be to either return an error, as it is now, or to
return nil.

Tried to think of a somewhat realistic example with a variable number
of arguments.

1) min on an empty arglist returns nil

-- groups is an array of arrays.
function get_minimums(groups)
   local minimums = {}
   for _, group in ipairs(groups) do
      table.insert(minimums, math.min(unpack(group)))
   end
   return minimums
end

2) min on an empty arglist returns error

-- groups is an array of arrays.
function get_minimums(groups)
   local minimums = {}
   for _, group in ipairs(groups) do
      if group[1] then
         table.insert(minimums, math.min(unpack(group)))
      end
   end
   return minimums
end

3) min on an empty arglist returns math.huge

-- groups is an array of arrays.
function get_minimums(groups)
   local minimums = {}
   for _, group in ipairs(groups) do
      local min = math.min(unpack(group))
      if min ~= math.huge then
         table.insert(minimums, min)
      end
   end
   return minimums
end

Even in behavior 3, I'd never write it like that, I'd write the code
like that from behavior 2 instead. Except that if I forgot to test for
the empty table, I'd silently end up with math.huge's in my result,
whereas in case 2 I'd get an error.

All code snippets above have of course the caveat that each group is
small enough so it can be unpacked and given as an argument list.
Having math.max(t) and math.min(t) to get the least or greater element
of a sequence when given a single table as an argument would be nice,
if a bit overengineered[*] (but then that would be incompatible with
your proposal #1, which I think is more useful/consistent).

[*] not to mention people would expect the same behavior from
string.char and all other variadic functions in the standard library.

-- Hisham