[ANN] Lua 5.4.0 (work1) now available

classic Classic list List threaded Threaded
164 messages Options
123456 ... 9
Reply | Threaded
Open this post in threaded view
|

Re: [ANN] Lua 5.4.0 (work1) now available

Luiz Henrique de Figueiredo
> Building on freebsd doesn't work without adding CC=cc

Thanks for the feedback.

We're specially interested in feedback on the src/Makefile targets
because we don't have access to many platforms listed there (aix, bsd,
freebsd, solaris).

Reply | Threaded
Open this post in threaded view
|

Re: [ANN] Lua 5.4.0 (work1) now available

Coda Highland
In reply to this post by Russell Haley
On Wed, Mar 14, 2018 at 1:04 AM, Russell Haley <[hidden email]> wrote:

>> u = table.move(t,1,#t,1,{})
>> for i,v in pairs(u) do print(i,v) end
> 1       one
> 2       two
> 3       four
> 4       nil
> 5       five
>> #t
> 5
>> t[4] = undef
>> for i,v in pairs(t) do print(i,v) end
> 1       one
> 2       two
> 3       four
> 5       five
>> #t
> 3  --<<<<<< I Expected 4 here?
>>

This is expected. You have a table with a hole in it -- and you
explicitly constructed it that way. The length of the sequence part of
t is, in fact, 3.

/s/ Adam

Reply | Threaded
Open this post in threaded view
|

Re: [ANN] Lua 5.4.0 (work1) now available

Hisham
On 14 March 2018 at 09:04, Coda Highland <[hidden email]> wrote:

> On Wed, Mar 14, 2018 at 1:04 AM, Russell Haley <[hidden email]> wrote:
>>> u = table.move(t,1,#t,1,{})
>>> for i,v in pairs(u) do print(i,v) end
>> 1       one
>> 2       two
>> 3       four
>> 4       nil
>> 5       five
>>> #t
>> 5
>>> t[4] = undef
>>> for i,v in pairs(t) do print(i,v) end
>> 1       one
>> 2       two
>> 3       four
>> 5       five
>>> #t
>> 3  --<<<<<< I Expected 4 here?
>>>
>
> This is expected. You have a table with a hole in it -- and you
> explicitly constructed it that way. The length of the sequence part of
> t is, in fact, 3.

But if I follow correctly, "#t" wasn't changed to mean "the length of
the sequence part" (i.e. highest integer n for which [1, n] are all
existing keys). See:

> #t
4
> t[3] = undef
> for i,v in pairs(t) do
>> print(i,v)
>> end
1       one
2       two
4       four
> #t
4

In the presence of holes, #t seems to still have the same
easy-to-define/hard-to-understand semantics from Lua 5.1-5.3. (Note I
haven't checked the sources or played with this at all — this is just
guessing from Russell's examples.)

-- Hisham

Reply | Threaded
Open this post in threaded view
|

Re: [ANN] Lua 5.4.0 (work1) now available

pocomane
In reply to this post by Roberto Ierusalimschy
Some opinions about undef. Right now, nil is needed for:
1) skip some arguments or return values in a function call
2) check presence in tables or remove something from them
3) Other ?

IMHO, the mixed solution (nil/value for 1 while undef/keyword for 2) is very
little lua-ish. It is complex and difficult to explain, also if it just adds an
handfuill of exception to care of. This because both 1 and 2 in our human mind
are recognized to model the same thing: something "Missing".

I am not saying that undef should be removed as a test feature. On the
contrary, it would be nice to have the possibility to play with a full solution
that works also for 1. I also theoretically prefer "Keyword/no-value" semantic.
But I really do not see any simple way to keep this semantic in 1.

I mean: if I can pass something to a function, and I can get it back from a
call... well it is a value!

Reply | Threaded
Open this post in threaded view
|

Re: [ANN] Lua 5.4.0 (work1) now available

Dirk Laurie-2
2018-03-14 14:46 GMT+02:00 pocomane <[hidden email]>:

> Some opinions about undef. Right now, nil is needed for:
> 1) skip some arguments or return values in a function call
> 2) check presence in tables or remove something from them
> 3) Other ?
>
> IMHO, the mixed solution (nil/value for 1 while undef/keyword for 2) is very
> little lua-ish. It is complex and difficult to explain, also if it just adds an
> handfuill of exception to care of. This because both 1 and 2 in our human mind
> are recognized to model the same thing: something "Missing".
>
> I am not saying that undef should be removed as a test feature. On the
> contrary, it would be nice to have the possibility to play with a full solution
> that works also for 1. I also theoretically prefer "Keyword/no-value" semantic.
> But I really do not see any simple way to keep this semantic in 1.
>
> I mean: if I can pass something to a function, and I can get it back from a
> call... well it is a value!

If you enable LUA_NILINTABLES (as explain in detail in a new thread),
there is another value of type nil, call it 'empty'. You can't tell
the difference between the values 'nil' and 'empty' at the level of
the API, let alone in Lua.

But for the sake of the argument, suppose you could. When you say
"t[4]=nil", what really happens is the equivalent of
"rawset(t,4,empty)", and when you say "t[4]=undef", what really
happens is the equivalent of "rawset(t,4,nil)".

At the level where '#' is calculated, 'empty' is distinct from 'nil'
and so the table does not have a hole there.

[1] Nils in tables in Lua 5.4.0 (worki1) (Was: [ANN] ...now available

Reply | Threaded
Open this post in threaded view
|

Re: [ANN] Lua 5.4.0 (work1) now available

Andrew Starks-2

On Wed, Mar 14, 2018 at 08:14 Dirk Laurie <[hidden email]> wrote:
2018-03-14 14:46 GMT+02:00 pocomane <[hidden email]>:
> Some opinions about undef. Right now, nil is needed for:
> 1) skip some arguments or return values in a function call
> 2) check presence in tables or remove something from them
> 3) Other ?
>
> IMHO, the mixed solution (nil/value for 1 while undef/keyword for 2) is very
> little lua-ish. It is complex and difficult to explain, also if it just adds an
> handfuill of exception to care of. This because both 1 and 2 in our human mind
> are recognized to model the same thing: something "Missing".
>
> I am not saying that undef should be removed as a test feature. On the
> contrary, it would be nice to have the possibility to play with a full solution
> that works also for 1. I also theoretically prefer "Keyword/no-value" semantic.
> But I really do not see any simple way to keep this semantic in 1.
>
> I mean: if I can pass something to a function, and I can get it back from a
> call... well it is a value!

If you enable LUA_NILINTABLES (as explain in detail in a new thread),
there is another value of type nil, call it 'empty'. You can't tell
the difference between the values 'nil' and 'empty' at the level of
the API, let alone in Lua.

But for the sake of the argument, suppose you could. When you say
"t[4]=nil", what really happens is the equivalent of
"rawset(t,4,empty)", and when you say "t[4]=undef", what really
happens is the equivalent of "rawset(t,4,nil)".

At the level where '#' is calculated, 'empty' is distinct from 'nil'
and so the table does not have a hole there.

[1] Nils in tables in Lua 5.4.0 (worki1) (Was: [ANN] ...now available

Doesn’t it make tables behave closer to multiple return values? Now, if you store return values in a table, you have a way to know the number of values returned, even if there are trailing nils. You can also reliably get this answer if the nils aren’t trailing. 

‘t.n’ was the other way to do this, but from a symmetry standpoint, it appears to be a little cleaner. 

If you had some datamodel where you were storing large objects as keys, you would need to update your code. 
Reply | Threaded
Open this post in threaded view
|

Re: [ANN] Lua 5.4.0 (work1) now available

Roberto Ierusalimschy
In reply to this post by Daurnimator
> I get a few warnings with gcc 7.3.0.
>
> gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_3 -DLUA_USE_LINUX
> -c -o lcode.o lcode.c
> In file included from lcode.h:12:0,
>                  from lcode.c:19:
> lcode.c: In function ‘luaK_finish’:
> lopcodes.h:108:30: warning: this statement may fall through
> [-Wimplicit-fallthrough=]
>  #define SET_OPCODE(i,o) ((i) = (((i)&MASK0(SIZE_OP,POS_OP)) | \
>                          ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>    ((cast(Instruction, o)<<POS_OP)&MASK1(SIZE_OP,POS_OP))))
>    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> lcode.c:1698:9: note: in expansion of macro ‘SET_OPCODE’
>          SET_OPCODE(*pc, OP_RETURN);
>          ^~~~~~~~~~
> lcode.c:1701:7: note: here
>        case OP_RETURN: case OP_TAILCALL: {
>        ^~~~

Well, fallthrough is a regular part of C. When we write

  case A:  case B: { ... }

we have a fallthrough, too. That code in Lua has an explicit comment
/* FALLTHROUGH */ there, to satisfy lint. What else does gcc 7.3 need
to be happy?

BTW, there are many other cases of fallthroughs in the code. Why gcc
only complained about those two?

-- Roberto

Reply | Threaded
Open this post in threaded view
|

Re: [ANN] Lua 5.4.0 (work1) now available

Roberto Ierusalimschy
In reply to this post by Rena
> So, how do we store 'undef' in a table? ;-)

How do you store a 'while' in a table?

-- Roberto

Reply | Threaded
Open this post in threaded view
|

Re: [ANN] Lua 5.4.0 (work1) now available

Roberto Ierusalimschy
In reply to this post by Tomás Guisasola-2
> > t[i]=undef is a special syntax form that means "remove the key 'i'
> > from table 't'".
>
> But it seems like an assignment.  Wouldn't be better to create a special
> syntax for removing a key from a table instead pretending it as an
> assingment?
>
> You should have considered a pair of functions, such as table.undefine(t,
> i) to undefine a key, and table.defined(t, i) to check whether the table
> has the key.  Why did you choose the assignment?

Mainly because of compatibility with older versions. As I said, I like
the idea of using 't[i]=undef' even in older versions, as a idiom to
better document things being removed from a table.

We fully agree that it may be confusing; that is why we are testing it
in this work release.

A new syntax (such as "delete a[k]" or anything like that) would be
the worst for compatibility, as new programs using it would not even
compile in older Lua. Functions are not that bad; with something
like

      table.undefine = table.undefine or function(t,k) t[k] = nil end

we get compatibility in older Lua. But with 't[i=undef' we have
compatibility without any work :-)

-- Roberto

Reply | Threaded
Open this post in threaded view
|

Re: [ANN] Lua 5.4.0 (work1) now available

Roberto Ierusalimschy
In reply to this post by pocomane
> I mean: if I can pass something to a function, and I can get it back from a
> call... well it is a value!

That is true. But you cannot pass 'undef' to a function or return
an 'undef' from a function (anymore than you can pass 'while' to a
function).

-- Roberto

Reply | Threaded
Open this post in threaded view
|

Re: [ANN] Lua 5.4.0 (work1) now available

Roberto Ierusalimschy
In reply to this post by Dirk Laurie-2
> If you enable LUA_NILINTABLES (as explain in detail in a new thread),
> there is another value of type nil, call it 'empty'. You can't tell
> the difference between the values 'nil' and 'empty' at the level of
> the API, let alone in Lua.

I don't think these implementation details help this discussion, on the
contrary.

The implementation could be completely different, for instance an extra
field in each table entry telling whether it is empty or not. Actually,
this second implementation gives a much better mental model of the
semantics then the real implementation, but it would be more expensive.

-- Roberto

Reply | Threaded
Open this post in threaded view
|

Re: [ANN] Lua 5.4.0 (work1) now available

Roberto Ierusalimschy
In reply to this post by Hisham
> In the presence of holes, #t seems to still have the same
> easy-to-define/hard-to-understand semantics from Lua 5.1-5.3.

I said this in my first post:

  You still can create tables with holes, but you must get out of your
  way to do it.

Once you get out of your way and create holes, all the "standard
behavior" are back. But you asked for it...

-- Roberto

Reply | Threaded
Open this post in threaded view
|

Re: [ANN] Lua 5.4.0 (work1) now available

Pierre Chapuis
In reply to this post by Roberto Ierusalimschy
On Wed, Mar 14, 2018, at 14:59, Roberto Ierusalimschy wrote:

> BTW, there are many other cases of fallthroughs in the code. Why gcc
> only complained about those two?

It does not like where they are.

This fixes it:

diff --git a/src/lcode.c b/src/lcode.c
index 838d03a..2877d25 100644
--- a/src/lcode.c
+++ b/src/lcode.c
@@ -1696,8 +1696,8 @@ void luaK_finish (FuncState *fs) {
           break;  /* no extra work */
         /* else use OP_RETURN to do the extra work */
         SET_OPCODE(*pc, OP_RETURN);
-        /* FALLTHROUGH */
       }
+      /* FALLTHROUGH */
       case OP_RETURN: case OP_TAILCALL: {
         if (p->sizep > 0 || p->is_vararg) {
           SETARG_C(*pc, p->is_vararg ? p->numparams + 1 : 0);
diff --git a/src/lgc.c b/src/lgc.c
index 6ab04f7..d4bd059 100644
--- a/src/lgc.c
+++ b/src/lgc.c
@@ -301,8 +301,8 @@ static void reallymarkobject (global_State *g, GCObject *o) {
         gray2black(o);  /* nothing else to mark */
         break;
       }
-      /* else *//* FALLTHROUGH */
     }
+    /* FALLTHROUGH */
     case LUA_TLCL: case LUA_TCCL: case LUA_TTABLE:
     case LUA_TTHREAD: case LUA_TPROTO: {
       linkobjgclist(o, g->gray);

--
Pierre Chapuis

Reply | Threaded
Open this post in threaded view
|

Re: [ANN] Lua 5.4.0 (work1) now available

Roberto Ierusalimschy
In reply to this post by Andrew Starks-2
> My reaction was: What would you call this new language?

I think "Lua" would be a great name :-)

Every year or so the list has its recurrent discussion about the length
operator and holes in sequences. Quite often, this discussion leads some
people to propose that Lua needs an array type, different from tables.

My current view is quite the opposite. The implementation of arrays on
top of tables is not the source of the problem with holes. The tendency
to view them as a different type is what blinds us to the real problem,
which is that tables cannot have nils. Tables also have problems with
holes, but they are less annoying, and so we think about it as a problem
with arrays.

Many years ago, we added booleans to the language exactly because we
could not store nil in tables. 'false' is just a 'nil' that we can store
in tables. ('true' is useless in Lua.) If tables could store nils, the
language would not need 'false'.

We will not make this change now, because of compatibility. But, the
next time the list gets its annual discussion about length, it would
be good to recall this proposal.

-- Roberto

Reply | Threaded
Open this post in threaded view
|

Re: [ANN] Lua 5.4.0 (work1) now available

Roberto Ierusalimschy
In reply to this post by Pierre Chapuis
> > BTW, there are many other cases of fallthroughs in the code. Why gcc
> > only complained about those two?
>
> It does not like where they are.

Thanks!

-- Roberto

Reply | Threaded
Open this post in threaded view
|

Re: [ANN] Lua 5.4.0 (work1) now available

Oliver Kroth
In reply to this post by Roberto Ierusalimschy



>> btw, I notice that there is a new keyword, "undef", not mentions in manual,
>> is that just a undocumented feature or the doc just not the latest?
Why is the new "undef" not used the other way round:

A[2] = nil removes the entry from the table
A[2] = undef  puts a value in A[2] that reads 'nil'

That would keep compatibility with Lua 5.3 and older
--
Oliver

Reply | Threaded
Open this post in threaded view
|

Re: [ANN] Lua 5.4.0 (work1) now available

Roberto Ierusalimschy
>
>
>
> >>btw, I notice that there is a new keyword, "undef", not mentions in manual,
> >>is that just a undocumented feature or the doc just not the latest?
> Why is the new "undef" not used the other way round:
>
> A[2] = nil removes the entry from the table
> A[2] = undef  puts a value in A[2] that reads 'nil'
>
> That would keep compatibility with Lua 5.3 and older

We thought about something like that.

The problem is neither 'a[t]=nil' nor 'a[t]=undef', but 'a[t]=x' when
'x' happens to be nil. This is what creates surreptitious holes in
tables that leads to all the problems with '#t'. In the end, we would
have something like this:

x = nil; t[1] = x;    -- adds element
         t[1] = nil;  -- remove element

Rather strange...

-- Roberto

Reply | Threaded
Open this post in threaded view
|

Re: [ANN] Lua 5.4.0 (work1) now available

Rena
In reply to this post by Roberto Ierusalimschy
On Wed, Mar 14, 2018, 10:27 Roberto Ierusalimschy, <[hidden email]> wrote:
> In the presence of holes, #t seems to still have the same
> easy-to-define/hard-to-understand semantics from Lua 5.1-5.3.

I said this in my first post:

  You still can create tables with holes, but you must get out of your
  way to do it.

Once you get out of your way and create holes, all the "standard
behavior" are back. But you asked for it...

-- Roberto

Well, it seems like now that tables can contain nil, it makes little sense that sequences can't.

Reply | Threaded
Open this post in threaded view
|

Re: [ANN] Lua 5.4.0 (work1) now available

Oliver Kroth
In reply to this post by Roberto Ierusalimschy

>> Why is the new "undef" not used the other way round:
>>
>> A[2] = nil removes the entry from the table
>> A[2] = undef  puts a value in A[2] that reads 'nil'
>>
>> That would keep compatibility with Lua 5.3 and older
> We thought about something like that.
>
> The problem is neither 'a[t]=nil' nor 'a[t]=undef', but 'a[t]=x' when
> 'x' happens to be nil. This is what creates surreptitious holes in
> tables that leads to all the problems with '#t'. In the end, we would
> have something like this:
>
> x = nil; t[1] = x;    -- adds element
>           t[1] = nil;  -- remove element
>
> Rather strange...
>
> -- Roberto
>
Not sure if I did understand;
using Lua5.3 semantics:

x = nil; t[1] = x;  -- removes element

proposed new 'value' undef:
            t[1] = nil;   -- removes element, creates hole, reads nil
x = undef; t[1] = x;     -- removes element, creates hole, reads nil
            t[1] = undef; -- keeps element, no hole, reads nil

I have read that there are two subtypes being used; that may help here
as well:

nil   = nil.remove
undef = nil.keep

            t[1] = nil;   -- removes element, creates hole, reads nil
x = undef; t[1] = x;     -- stores nil.keep in x, assignment to t[1]
stores nil.keep, no hole, reads nil
            t[1] = undef; -- keeps element, no hole, reads nil (is nil.keep)

Would that work ?

--
Oliver

Reply | Threaded
Open this post in threaded view
|

Re: [ANN] Lua 5.4.0 (work1) now available

Paul K-2
In reply to this post by Roberto Ierusalimschy
>> Why is the new "undef" not used the other way round:
>>
>> A[2] = nil removes the entry from the table
>> A[2] = undef  puts a value in A[2] that reads 'nil'
>>
>> That would keep compatibility with Lua 5.3 and older
>
> We thought about something like that.
>
> The problem is neither 'a[t]=nil' nor 'a[t]=undef', but 'a[t]=x' when
> 'x' happens to be nil. This is what creates surreptitious holes in
> tables that leads to all the problems with '#t'. In the end, we would
> have something like this:
>
> x = nil; t[1] = x;    -- adds element
>          t[1] = nil;  -- remove element

I interpreter Oliver's proposal differently: in both cases the element
would be removed (the same behavior as with the current version of
Lua).

Only `t[1] = undef` will add `nil` without creating a hole (empty
value). So, you'd need to be explicit by using "undef" when you want
to remove the element, but keep its spot in the table and not when you
simply want to remove the element (as it is in the current undef
proposal). You don't need a new compile switch, as the behavior in the
new version is the same as in the current version unless `undef` is
used.

I also find this approach more consistent and easier to explain
(assuming I got it right).

Paul.

123456 ... 9