[ANN] Ravi-Distro 0.5 alpha release

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

Re: [ANN] Ravi-Distro 0.5 alpha release

Philippe Verdy
OK, but basic search on the Internet still refer to the old specification which is on the Lua.org site itself. What was unspecified is now specified since Lua 5.3 only (and I know various sites that still use Lua 5.1, and several JIT compilers that did not use these clear statements for Lua 5.3, which may now cause incompatible behavior with valid interpretations of the former less precise specification).

Yes the new spec specifies that a zero step is now a *forward* iterator only (this is an arbitrary choice of Lua 5.3, in both cases it will cause either an infinite loop or no loop executed at all, and in both cases the start value, which will be constant if loops are executed will only be compared to the limit value: if start >= limit you have an infinite loop).

What is missing (but is implied) in the 5.3 manual is the case of a missing step value; the sample code says
   local ..., step = ..., tonumber(e3)
so it can return nil, then
   if not (var and limit and step) then error() end
so a "nil" (unspecified) step would cause an error. The first statement of the pseudo-code should be:
   local ..., step = ..., (e3 == nil and 1 or tonumber(e3))

There's still nothing that indicates clearly that the default value of the missing third expression in parameter of the numeric for loop is 1 (this could still be a problem if an implementation chose to set it at -1 if start > end, but it would break lot of codes assuming that code like:
  for i=1,#t do ... --[==[ operation on t[i]... ]==] ... end
where the end expression "#t" could be the limit=0 (which is lower start=1) and where it is normally expected that there would be no loop performed (backward direction with an implied step=-1 should be explicitly prohibited, in the numeric for version) That same loop could be written using a generic loop (with an iterator):
  for i in ipairs(t) do ...   --[==[ operation on t[i]... ]==]  ... end"
Such precision is present only further down in notes ("If the third expression (the step) is absent, then a step of 1 is used."), but it should be integrated in the pseudo-code, unless the following Lua code:
 for i in 1,10,nil do ... end
which would generate a runtime error(), but not this one:
 for i in 1,10 do ... end



Le jeu. 15 nov. 2018 à 18:19, Andrew Gierth <[hidden email]> a écrit :
>>>>> "Philippe" == Philippe Verdy <[hidden email]> writes:

 Philippe> What is even worse is that the same page states

Why are you reading the online copy of PiL, which is for a long-obsolete
version of Lua, rather than the _actual documentation_?

https://www.lua.org/manual/5.3/manual.html#3.3.5

This makes it perfectly clear that:

 - the actual loop iteration variables are hidden and not accessible

 - any changes to the visible loop variable in the loop body have no
   effect beyond the end of the current iteration

 Philippe> The doc is not clear about the behavior of a numeric for
 Philippe> loop, when the optional stepping value is zero

The actual manual (as linked above) is precisely clear about this.

--
Andrew.

Reply | Threaded
Open this post in threaded view
|

Re: [ANN] Ravi-Distro 0.5 alpha release

Philippe Verdy
In reply to this post by Egor Skriptunoff-2
Le jeu. 15 nov. 2018 à 20:41, Egor Skriptunoff <[hidden email]> a écrit :
So, when parsing "for j = 1, 1e4 do", Ravi should conclude that "j" is integer, similar to how Lua 5.3 deduces type of loop variable.
This way there would be no reason to replace 1e4 with 10000

an integer yes, but in the value range of numbers (i.e. IEEE doubles...). Just retry with
  for j = 1, 1e99 do
and you'll conclude that j cannot be a 32-bit (or even 64-bit) integer because the upper limit is largely above MAXINT+1.

Note also that this loop would even be infinite in Lua (because adding incremental step of 1 will cease to be significant when j reaches 2^53 (if Lua "numbers" are compiled as IEEE 64-bit doubles) like in this example:
  for j = 2**53, 2**53+2**15-1 do
which you could expect perform (2**15)=32768 loops exactly, but will instead loop infinitely with j constantly set to the same start value (2**53), and the default step=1 has no effect (same here as step=0)... Lua does not check that (start+step != start) and that (limit-step != limit), i.e. that there will be an effective linear progression and that the limit will be reachable.



Reply | Threaded
Open this post in threaded view
|

Re: [ANN] Ravi-Distro 0.5 alpha release

Dibyendu Majumdar
In reply to this post by Philippe Verdy
On Thu, 15 Nov 2018 at 11:55, Philippe Verdy <[hidden email]> wrote:

>
>
>
> Le mer. 14 nov. 2018 à 21:55, Dibyendu Majumdar <[hidden email]> a écrit :
>>
>> On Wed, 14 Nov 2018 at 19:55, Egor Skriptunoff
>> <[hidden email]> wrote:
>> >
>> >
>> > OK, let's test it!
>> >
>> > 1)
>> > A bug: correct Lua 5.3 program doesn't run on Ravi.
>> >    C:\Software\ravi\bin>ravi -e"for x = 1, 2 do x = 42.0 end"
>> >    ravi: (command line):1: Invalid assignment: integer expected near 'end'
>> >
>>
>> In this case Ravi is deciding that x is an integer type and hence
>> doesn't like that you are assigning a floating point value.
>
>
> That's because it attempts to optimize the integer loop unsafely: when compiling x=42.0, which changes the loop variable, it forgets to evaluate the loop condition (x<=42) which would normally imply that this assignment to x causes a break to the loop; but as this x variable is local to the loop and this assigned value is then not used after breaking, the assignment has no other effect than breaking the loop, so this code would be nearly like "for x = 1, 2 do break end" i.e. it will do nothing if compiled properly; if the code is interpreted, the for loop will be executed only once (local x=1 when entering the first loop which sets x=42.0, and exiting immediately which deletes the x variable).
> There is code where modifying the loop control variable is perfectly valid, even if in general this is done by assigning a value of the same type.

Hi, to be honest the for num loop variable should be treated as
'readonly' inside the loop body as it is a copy of the real index
variable, and changing it inside the body doesn't affect the loop, and
is just bad practice in my view. Anyway I take the liberty of
optimising the for num index here, and require that the variable is
not assigned a non-integer value. I would forbid assignment but this
is harder to do.

Regards
Dibyendu

Reply | Threaded
Open this post in threaded view
|

Re: [ANN] Ravi-Distro 0.5 alpha release

Philippe Verdy


Le jeu. 15 nov. 2018 à 21:19, Dibyendu Majumdar <[hidden email]> a écrit :
On Thu, 15 Nov 2018 at 11:55, Philippe Verdy <[hidden email]> wrote:
Hi, to be honest the for num loop variable should be treated as
'readonly' inside the loop body

Not needed because you say yourself:
 
as it is a copy of the real index
variable, and changing it inside the body doesn't affect the loop,

This means that the value provided by the loop iterator can be transformed as you want to do the operations needed in your loop, you don't necessarily need to keep it unchanged.  A compiler can detect if it's assigned or not; and if not, it can suppress the copy into from the actual control variable (invisible, but not readonly) to the local variable.
and
is just bad practice in my view.

Given it is local, this is not bad practice at all, it's jsut a standard local variable, preinitialized, but still mutable as we want. So you don't need to declare another local varaible in the loop
 
Anyway I take the liberty of
optimising the for num index here, and require that the variable is
not assigned a non-integer value. I would forbid assignment but this
is harder to do.

The best you can do is to emit a warning because it may not be compatible with older versions of Lua. If you compile for Lua 5.3 only, nothing is needed, the actual control varaible is well protected, and it's just simpelr to manage all variables the same way everywhere in the code inside the loop.

 
Regards
Dibyendu
Reply | Threaded
Open this post in threaded view
|

Re: [ANN] Ravi-Distro 0.5 alpha release

Egor Skriptunoff-2
In reply to this post by Dibyendu Majumdar
On Thu, Nov 15, 2018 at 11:20 PM Dibyendu Majumdar wrote:
Hi, to be honest the for num loop variable should be treated as
'readonly' inside the loop body as it is a copy of the real index
variable, and changing it inside the body doesn't affect the loop, and
is just bad practice in my view.

IMO, it's not a "bad practice".
Mutability of loop variable (without affecting the loop) is quite useful.
Examples:

for name, value in str:gmatch"(%w+)=(%d+)" do
  value = tonumber(value)
  ....
end

for k = 1, 10 do
  k = tostring(k)
  ....
end

Reply | Threaded
Open this post in threaded view
|

Re: [ANN] Ravi-Distro 0.5 alpha release

Dirk Laurie-2
Op Vr. 16 Nov. 2018 om 07:26 het Egor Skriptunoff
<[hidden email]> geskryf:

>
> On Thu, Nov 15, 2018 at 11:20 PM Dibyendu Majumdar wrote:
>>
>> Hi, to be honest the for num loop variable should be treated as
>> 'readonly' inside the loop body as it is a copy of the real index
>> variable, and changing it inside the body doesn't affect the loop, and
>> is just bad practice in my view.
>
>
> IMO, it's not a "bad practice".
> Mutability of loop variable (without affecting the loop) is quite useful.
> Examples:
>
> for name, value in str:gmatch"(%w+)=(%d+)" do
>   value = tonumber(value)
>   ....
> end
>
> for k = 1, 10 do
>   k = tostring(k)
>   ....
> end

+1.

12