lua-users home
lua-l archive

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


On 4 June 2014 18:27, Andrew Starks <andrew.starks@trms.com> wrote:
>
>
>
> On Wed, Jun 4, 2014 at 3:52 PM, Dirk Laurie <dirk.laurie@gmail.com> wrote:
>>
>> 2014-06-04 18:48 GMT+02:00 Andrew Starks <andrew.starks@trms.com>:
>> > print(math.min(1,2), math.max(1,2))
>> > --1.0, 2.0
>> > I would have expected integers.
>>
>> RTFM.
>>
>> "Unless stated otherwise, all functions in this library operate with
>> and return floats."
>>
>
> If "should" == "The Fine Manual says so" then I guess it's a dumb question.

That's of course not the case. Dirk's bluntness was uncalled for, and
as far as I know 5.3work2 is not the final release version so treating
the work manual as dogma is a bit premature.

In an informal quiz here at the lab, everyone expected math.max() to
return an integer when given all integers. When I told them it returns
a float, everyone went "oh..." and when I asked them how should it
behave when given an integer and a float, opinions were mixed.

Given that the operation is closed in integers, it was reasonable to
assume that math.max is overloaded, like for instance `+` (hence
expecting an integer when passing two integers). And like `+`, it's
fair to assume that in the comparison `i < f` the integer value is
promoted to float. On the other hand, given a sequence of numbers s,
it can be a bit surprising that math.max(table.unpack(s)) may not
return an element of s. However, in light of other behaviors such as
table keys, relying on subtype preservation when dealing with a mixed
bag of ints and floats is probably not a very good idea already, and I
assume that if one is mixing ints and floats they are already thinking
of them as floats in general.

Lua 5.3 already makes some effort to preserve integers as integers
when working exclusively with them in its operators. And let's recap
that little "ranking" of math functions by use I posted recently [1]:

[1] http://lua-users.org/lists/lua-l/2014-04/msg00354.html

Here's the Top 7. (I chose 7 because math.sin is the first fully
float-to-float function there)

1) math.floor 44679
2) math.random 27874
3) math.min 16661
4) math.abs 16297
5) math.max 14023
6) math.ceil 12714
7) math.sin 11376

The landslide victory goes to math.floor, which was our main "cast to
int" operator until now; with integers in the language it's safe to
assume this number will go down in the future.

Second place goes to math.random, which does have an integer mode of
operation already.

Positions 3, 4 and 5 go to functions that are often used to operate on
ints, and that are quite useful for "non-mathematical" code (one can
think of a gazillion uses: comparing network packet identifiers,
character codepoints, etc.)

Entry #6 is the leader's poor cousin.

And only then the "fully float" functions start in the list.

math.abs has the least compelling argument for having an integer mode
since one can do ~x+1 but I know that I'd be using math.abs in my code
instead of that (or code my own abs if math.abs remains
float-only...).

But the argument of having math.max and math.min preserve integers
(and their precision) has, in my opinion, a very strong case.
(Especially since math.max and math.min _are_ convenience functions
after all, so the "roll your own" answer does not apply.)

-- Hisham