lua-users home
lua-l archive

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

On Tue, Mar 4, 2014 at 11:17 AM, Roberto Ierusalimschy
<> wrote:
> For of all, many thanks for sharing your thoughts. Really useful.
>> The switch of tostring returning "2.0" instead of "2" is somewhat significant:
> We really thought that change would be small. The manual always has
> recomended programmers not to use 'tostring' for "serious" output:
>   * tostring (v)
>     Receives a value of any type and converts it to a string in a
>     reasonable format. (For complete control of how numbers are
>     converted, use string.format.)

I tried to draw a distinction between "programmer" and "casual Lua
user".  The definition and significance of those groups is a matter of
opinion. Loosely: A "casual user" knows how to program a little and
reads enough of the documentation to get going.

This kind of user may not be important in this use case, but it seems
like formatting numbers is a common occurrence.

>> There are a few other cases where you need just the integer of a
>> result and you want to append it to some other text, like when you're
>> formatting a number with commas, a social security number or a phone
>> number. There is a decent amount of implemented Lua that will return
>> "1.0,234.0,567.0" (1,234,567), "+1.0 (612.0) 555.0-5555.0" (+1 (612)
>> 555-5555), etc.
> Are you sure this is so frequent? Wouldn't these numbers be usually
> represented as integers (and therefore printed as such)?

No. I'm not sure of the significance. I can only write anecdotally.

I've had to patch 3 libraries. My total library usage is rather small,
so I was extrapolating. The fix was exactly the one that you suggest
in this email and it worked perfectly.

>> The fix for this feels different than even the one for _ENV/setfenv.
>> You can overload or replace tostring to check for an integer and
>> return the integer portion but this is a "patch" that brings back old
>> behavior.
> What is the problem here? If you explicitly want the old behavior,
> put it back:
>   local oldtostring = tostring
>   tostring = function (x)
>     if math.type(x) == "float" then return string.format("%.14g", x)
>     else return oldtostring(x)
>     end
>   end
> (That is why 'print' uses 'totring' after all.)

I want to emphasize that I was writing about my experience and
potential areas of confusion for a new user, and also areas that will
need to be addressed by someone patching a library.

So, there is no "problem". What I meant to convey is a contrast
between _ENV and setfenv. In that case, the patch provided a common
way to make 5.2 and 5.1 work in the same way. In this case, it's a
reversion to the old way. It's just different. Not a problem.

>> If you want to use "//" but also need to support users of
>> older Lua, then you have to have access to "load", or require and
>> pall, or  a macro processor...
> You can also use math.ifloor:
>> = math.ifloor(3.0)
> 3
> (I am not sure 'ifloor' was already present in work 1...) For older
> versions, you simply define it to be floor:
>   math.ifloor = math.ifloor or math.floor
>> Also, code that uses "//" consistently will be different than code
>> that uses "math.floor", every now and again. Let's say that you want
>> an integer value to appear, without a ".0":
>> --5.2 behavior
>> > = string.format("%s", n)
>> 1001
>> --5.3 behavior
>> > = string.format("%s", n)
>> 1001.0
> Again, if you are printing numbers, shouldn't you be using a proper
> number format here, instead of "%s"? Or, again, you can use ifloor.
> And, yet again, wouln't 'n' be a proper integer, more often than not?

This is the part that I really wanted to articulate. If I am writing a
cross-version library, I can't easily use `x // 1` or otherwise know
if it is an int (or even should be one). So, I take a "function" based
approach that will vary, depending on my environment (can I use load
to see if `//` compiles?). In 5.3, // means that I have an integer and
it's very simple and straight forward. 5.2's approach will be somewhat
different and some care needs to be taken.

That said, I'm sure that the solution to cross-version issues is
simple in *someone's* mind and a nice compat53 library will make
things easier.

> The main idea of printing 2.0 instead of 2 (for people) is to make
> them aware that a number that probably should be an integer is not.
> (When the number should really be a float, it could print 2.1 or 2.2,
> so 2.0 should not cause any harm.) More often than not that could be
> (and should be) fixed in the code.
> Maybe a new function to "normalize" a number (make it an integer if
> it has an integer value) would be a useful adddition...
> -- Roberto

If I'm working in 5.3 only, this is not at all required. I know if
it's an int and if I want one, I can make one. [I will note that `x //
1` is a very common idiom in my code.]

In Lua, there is no "integer" type. Depending on the origin of the
number, I may have two identical values, one displayed as "1" and the
other as "1.0". This is great and maybe even helpful, if I'm debugging
something where "1.0" will hint at a bug in my code. It's why I
assumed that the change was made.

If I'm just *using* Lua, it seems odd that this detail would result in
a number showing up one way if, for example, I type it into a terminal
and another way if I set it with `x = 1`. It seems odd *because*
`type(x)` returns "number" and not "float" or "integer". [I don't
think it should, I'm just stating that "number" makes them appear

In the mind of someone debugging the inconsistency, their first
reaction might be, "Everything *seems* the same... why is it

So what is the fix?? There is nothing to fix! It's a design choice and
you decide! :) I agree that the old behavior is easily attained and
that the new behavior was picked for good reason.

My motivation was to convey an experience. I was surprised to spend a
couple of hours combing through source code that relied (wrongly) on
`tostring` and thought that this feedback would be helpful.