Lua 5.3: functional version of // operator?

classic Classic list List threaded Threaded
24 messages Options
12
Reply | Threaded
Open this post in threaded view
|

Lua 5.3: functional version of // operator?

Miles Bader-2
One thing I've run into with Lua 5.3-work1 is that I want to make code
which is portable between different versions of Lua, and while this is
usually pretty easy by simply using runtime tests, one can't use
anything which is invalid syntax in earlier Lua versions, like the
"//" operator.

For instance, I can use the following style of "adaptable" code:

   -- A version of floor that returns a true integer value in Lua 5.3.
   --
   local ifloor = math.ifloor or math.floor

To define an "idiv" function, which is basically math.floor(a/b), I'd
like to use the "//" operator in Lua 5.3, as it may be more efficient.
But I'm not sure how to write this, because 5.2 won't accept the "//"
syntax, even if the code is never executed.

For that reason, it would be nice if Lua 5.3 came with a standard
"math.idiv" function, which basically just returns a//b...

Then I could just write my own version adaptable local function like:

   -- Returns math.floor (a / b)
   --
   local function idiv (a, b)
      if math.idiv then
         return math.idiv (a, b)
      else
         return ifloor (a / b)          -- ifloor from above
      end
   end

Thanks,

-miles

--
Bacchus, n. A convenient deity invented by the ancients as an excuse for
getting drunk.

Reply | Threaded
Open this post in threaded view
|

Re: Lua 5.3: functional version of // operator?

steve donovan
On Mon, Jul 8, 2013 at 8:35 AM, Miles Bader <[hidden email]> wrote:
One thing I've run into with Lua 5.3-work1 is that I want to make code
which is portable between different versions of Lua, and while this is
usually pretty easy by simply using runtime tests, one can't use
anything which is invalid syntax in earlier Lua versions, like the
"//" operator.

I share Miles' concern here. This is the first serious break with Lua 5.1 after more than eight years - like a Python 3 moment. I understand that people sometimes need 64-bit integer arithmetic (which is why his proposed idiv won't in general work) but it's a very specific point to choose to break with the past.

steve d.

Reply | Threaded
Open this post in threaded view
|

Re: Lua 5.3: functional version of // operator?

Rena
In reply to this post by Miles Bader-2

On Jul 8, 2013 2:35 AM, "Miles Bader" <[hidden email]> wrote:
>
> One thing I've run into with Lua 5.3-work1 is that I want to make code
> which is portable between different versions of Lua, and while this is
> usually pretty easy by simply using runtime tests, one can't use
> anything which is invalid syntax in earlier Lua versions, like the
> "//" operator.
>
> For instance, I can use the following style of "adaptable" code:
>
>    -- A version of floor that returns a true integer value in Lua 5.3.
>    --
>    local ifloor = math.ifloor or math.floor
>
> To define an "idiv" function, which is basically math.floor(a/b), I'd
> like to use the "//" operator in Lua 5.3, as it may be more efficient.
> But I'm not sure how to write this, because 5.2 won't accept the "//"
> syntax, even if the code is never executed.
>
> For that reason, it would be nice if Lua 5.3 came with a standard
> "math.idiv" function, which basically just returns a//b...
>
> Then I could just write my own version adaptable local function like:
>
>    -- Returns math.floor (a / b)
>    --
>    local function idiv (a, b)
>       if math.idiv then
>          return math.idiv (a, b)
>       else
>          return ifloor (a / b)          -- ifloor from above
>       end
>    end
>
> Thanks,
>
> -miles
>
> --
> Bacchus, n. A convenient deity invented by the ancients as an excuse for
> getting drunk.
>

do
  local f = loadstring("return function(a, b) return a // b end")
  if f then idiv = f()
  else idiv = function(a,b) return ifloor(a / b) end
  end
end

Reply | Threaded
Open this post in threaded view
|

Re: Lua 5.3: functional version of // operator?

Miles Bader-2
Rena <[hidden email]> writes:
> do
>   local f = loadstring("return function(a, b) return a // b end")
>   if f then idiv = f()
>   else idiv = function(a,b) return ifloor(a / b) end
>   end
> end

Hmm, I think I'd prefer math.idiv...  oO;

-miles

--
The trouble with most people is that they think with their hopes or
fears or wishes rather than with their minds.  -- Will Durant

Reply | Threaded
Open this post in threaded view
|

Re: Lua 5.3: functional version of // operator?

steve donovan
On Mon, Jul 8, 2013 at 9:31 AM, Miles Bader <[hidden email]> wrote:
Hmm, I think I'd prefer math.idiv...  oO;


Why not just check _VERSION, unless I'm missing a subtlety?

Reply | Threaded
Open this post in threaded view
|

Re: Lua 5.3: functional version of // operator?

Vadi
I think using // would throw a syntax error when the code is loaded under Lua <5.3, so Miles would like to use a function instead that would allow him to avoid that issue.
Reply | Threaded
Open this post in threaded view
|

Re: Lua 5.3: functional version of // operator?

steve donovan
In reply to this post by steve donovan
On Mon, Jul 8, 2013 at 9:40 AM, steve donovan <[hidden email]> wrote:
Why not just check _VERSION, unless I'm missing a subtlety?

Which I just did, sorry. Rena's idiv will do the job, not sure about the compatibility version...
 

Reply | Threaded
Open this post in threaded view
|

Re: Lua 5.3: functional version of // operator?

Miles Bader-2
In reply to this post by steve donovan
steve donovan <[hidden email]> writes:
> On Mon, Jul 8, 2013 at 9:31 AM, Miles Bader <[hidden email]> wrote:
>
>> Hmm, I think I'd prefer math.idiv...  oO;
>>
> Why not just check _VERSION, unless I'm missing a subtlety?

(1) doesn't work

(2) _VERSION checks are ugly/flaky anyway, I'd prefer feature checks
    where possible (e.g. the way it checks whether math.ifloor is nil
    or not)

Rena's version will "work" but it's gross...

-miles

--
Conservative, n. A statesman enamored of existing evils, as opposed to a
Liberal, who wants to replace them with new ones.

Reply | Threaded
Open this post in threaded view
|

Re: Lua 5.3: functional version of // operator?

Miles Bader-2
In reply to this post by Miles Bader-2
I wrote in a previous message:

> Then I could just write my own version adaptable local function like:
>
>    -- Returns math.floor (a / b)
>    --
>    local function idiv (a, b)
>       if math.idiv then
>          return math.idiv (a, b)
>       else
>          return ifloor (a / b)          -- ifloor from above
>       end
>    end


Of course this is better written as:

  local idiv = math.idiv or function(a,b) return ifloor (a / b) end

[In general that's a pattern I tend to like to follow when writing
version-adaptable code using some new function NEW_FUN: define a local
version of NEW_FUN whose value is "NEW_FUN or function (...) ... end".]

-miles

--
Barometer, n. An ingenious instrument which indicates what kind of weather we
are having.

Reply | Threaded
Open this post in threaded view
|

Re: Lua 5.3: functional version of // operator?

Rena
In reply to this post by Miles Bader-2

On 2013-07-08 4:12 AM, "Miles Bader" <[hidden email]> wrote:
>
> steve donovan <[hidden email]> writes:
> > On Mon, Jul 8, 2013 at 9:31 AM, Miles Bader <[hidden email]> wrote:
> >
> >> Hmm, I think I'd prefer math.idiv...  oO;
> >>
> > Why not just check _VERSION, unless I'm missing a subtlety?
>
> (1) doesn't work
>
> (2) _VERSION checks are ugly/flaky anyway, I'd prefer feature checks
>     where possible (e.g. the way it checks whether math.ifloor is nil
>     or not)
>
> Rena's version will "work" but it's gross...
>
> -miles
>
> --
> Conservative, n. A statesman enamored of existing evils, as opposed to a
> Liberal, who wants to replace them with new ones.
>

You could certainly check for the existence of 5.3 functions instead, and that might be cleaner... (and I feel it'd be faster, but you only need to check once either way.) Nothing prevents you from assigning to math.idiv either.

Reply | Threaded
Open this post in threaded view
|

Re: Lua 5.3: functional version of // operator?

Dirk Laurie-2
In reply to this post by Miles Bader-2
2013/7/8 Miles Bader <[hidden email]>:

> steve donovan <[hidden email]> writes:
>> On Mon, Jul 8, 2013 at 9:31 AM, Miles Bader <[hidden email]> wrote:
>>
>>> Hmm, I think I'd prefer math.idiv...  oO;
>>>
>> Why not just check _VERSION, unless I'm missing a subtlety?
>
> (1) doesn't work
>
> (2) _VERSION checks are ugly/flaky anyway, I'd prefer feature checks
>     where possible (e.g. the way it checks whether math.ifloor is nil
>     or not)
>
> Rena's version will "work" but it's gross...

<sigh> here we go again ... </sigh>

If compatibility with 5.2 is that crucial, why insist on writing code
that in Lua 5.3 will return true integers? Why not just write in Lua
5.2 and trust the developers to provide a compatibility option?

Reply | Threaded
Open this post in threaded view
|

Re: Lua 5.3: functional version of // operator?

Sean Conner
In reply to this post by Miles Bader-2
It was thus said that the Great Miles Bader once stated:
>
> For that reason, it would be nice if Lua 5.3 came with a standard
> "math.idiv" function, which basically just returns a//b...

  Hmm ... in C, the div() function returns both the quotient and the
remainder.  If one is provided, you might as well return both results [1].

  -spc

[1] Wrote my own idiv() function that does just that:
        https://github.com/spc476/lua-conmanorg/blob/master/src/math.c


Reply | Threaded
Open this post in threaded view
|

Re: Lua 5.3: functional version of // operator?

Miles Bader-2
In reply to this post by Dirk Laurie-2
Dirk Laurie <[hidden email]> writes:
> <sigh> here we go again ... </sigh>

Huh?

> If compatibility with 5.2 is that crucial, why insist on writing code
> that in Lua 5.3 will return true integers? Why not just write in Lua
> 5.2 and trust the developers to provide a compatibility option?

The thing that prompted the exploration of this was that "tostring" in
Lua 5.3 returns something different for floats than it does for
integers, even for floats with integer values, and I had some code
that got confused by that.  This code uses floor(a/b) to get that
value, and I changed it to use ifloor but along the way, realized that
for some uses it might be nice to directly use "//" for efficiency
reasons (e.g. Roberto's earlier post about changing some code to use
"//").

-miles

--
Inhumanity, n. One of the signal and characteristic qualities of humanity.

Reply | Threaded
Open this post in threaded view
|

Re: Lua 5.3: functional version of // operator?

Dirk Laurie-2
In reply to this post by Rena
2013/7/8 Rena <[hidden email]>:

> Nothing prevents you from assigning to math.idiv either.

I like semi-global variables, i.e. local variables whose scope is
the entire file, visible as upvalues everywhere.

   local idiv = require"idiv"

I'll go with Sean's modification: an idiv module for Lua 5.2 providing
a function that returns quotient and remainder. A math.idiv in Lua 5.3
is not really necessary: the 5.2/5.3 compatibility code can go into the
module source. But since work1 is the one time when the developers are
asking us, put the request on the wishlist by all means.

Reply | Threaded
Open this post in threaded view
|

Re: Lua 5.3: functional version of // operator?

D Burgess-4
How about require "intop" (like bitop).

There must be something other than idiv that would be handy. (Can't
think of it though.)


On Mon, Jul 8, 2013 at 7:21 PM, Dirk Laurie <[hidden email]> wrote:

> 2013/7/8 Rena <[hidden email]>:
>
>> Nothing prevents you from assigning to math.idiv either.
>
> I like semi-global variables, i.e. local variables whose scope is
> the entire file, visible as upvalues everywhere.
>
>    local idiv = require"idiv"
>
> I'll go with Sean's modification: an idiv module for Lua 5.2 providing
> a function that returns quotient and remainder. A math.idiv in Lua 5.3
> is not really necessary: the 5.2/5.3 compatibility code can go into the
> module source. But since work1 is the one time when the developers are
> asking us, put the request on the wishlist by all means.
>



--
David Burgess

Reply | Threaded
Open this post in threaded view
|

Re: Lua 5.3: functional version of // operator?

D Burgess-4
I have previously implemented Lua 5.1 on processors/compilers with no
floating point. That is LUA_NUMBER is int and no mathlib. I recall
that it was not too difficult.

Is an integer only Lua possible with Lua 5.3?

Reply | Threaded
Open this post in threaded view
|

Re: Lua 5.3: functional version of // operator?

Luiz Henrique de Figueiredo
> I have previously implemented Lua 5.1 on processors/compilers with no
> floating point. That is LUA_NUMBER is int and no mathlib. I recall
> that it was not too difficult.
>
> Is an integer only Lua possible with Lua 5.3?

If you never use real numbers in Lua, you won't pay any price for
processing floating point. If your C compiler does not understand float
or double, not even if they are implemented in software and are slow, it
is not a ANSI C compiler.

But you can try defining LUA_NUMBER to be say long and see what happens.
I'd like to hear your experience with that.

Reply | Threaded
Open this post in threaded view
|

Re: Lua 5.3: functional version of // operator?

Roberto Ierusalimschy
In reply to this post by Miles Bader-2
> > If compatibility with 5.2 is that crucial, why insist on writing code
> > that in Lua 5.3 will return true integers? Why not just write in Lua
> > 5.2 and trust the developers to provide a compatibility option?
>
> The thing that prompted the exploration of this was that "tostring" in
> Lua 5.3 returns something different for floats than it does for
> integers, even for floats with integer values, and I had some code
> that got confused by that.  This code uses floor(a/b) to get that
> value, and I changed it to use ifloor but along the way, realized that
> for some uses it might be nice to directly use "//" for efficiency
> reasons (e.g. Roberto's earlier post about changing some code to use
> "//").

Probably 'a//b' should be faster than ifloor(a/b), but my specific
point was something else. In my case (and I supect this can be a common
pattern), the problem was not the performance of floor(a/b) per se, but
how its float result "contaminated" the rest of the algorithm. (The
algorithm became a mix of floats and integers, doing conversions all
the time to compare them, to index tables with floats, etc.)  In my
particular case, using ifloor(a/b) solved the problem all the same.

-- Roberto

Reply | Threaded
Open this post in threaded view
|

Re: Lua 5.3: functional version of // operator?

Javier Guerra Giraldez
In reply to this post by Luiz Henrique de Figueiredo
On Mon, Jul 8, 2013 at 8:03 AM, Luiz Henrique de Figueiredo
<[hidden email]> wrote:
> If you never use real numbers in Lua, you won't pay any price for
> processing floating point.


i think some non-FPU architectures have to link with a float library
if your code has any float operation.  there might be a space
advantage by not having the code, no matter if it's executed or not.

--
Javier

Reply | Threaded
Open this post in threaded view
|

Re: Lua 5.3: functional version of // operator?

Luiz Henrique de Figueiredo
> i think some non-FPU architectures have to link with a float library
> if your code has any float operation.  there might be a space
> advantage by not having the code, no matter if it's executed or not.

Right. I meant time penalty, not space, which is also important in small
platforms.

12