Proposal: Trailing comma in function calls

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

Re: Proposal: Trailing comma in function calls

Axel Kittenberger
Alternately allow `nil` as a lvalue that acts as the bit bucket.
 
While I'd appreciate something like that can we please keep some focus on the original proposal? And you know the rule, make a proposal, provide a patch.

This was just a very simply lexical relaxation, it doesn't even the warrant "extension", where the patch consists of just one line and albeit it happens less frequently than the trailing comma in tables it still bites some people as there has been provided some anecdotal evidence beside me in this conversation (thanks).

There is no implicit nil by lexical void in Lua, so there is no ambiguity and even if there is ever going to be, the solution would be simple as been explained by hisham to define lexical voids to exist only before commas and locial as one comma creates one void and not two.

- Axel
Reply | Threaded
Open this post in threaded view
|

Re: Proposal: Trailing comma in function calls

Dirk Laurie-2
2014-06-05 9:50 GMT+02:00 Axel Kittenberger <[hidden email]>:

> While I'd appreciate something like that can we please keep some focus on
> the original proposal?

I'm happy with the table constructor allowing an extra delimiter precisely
because {a,b,c}, {a,b,c,} and {a,b,c,nil} all do the same thing, and I am
not happy with the original proposal because for f(...), the difference
between f(a,b,c) and f(a,b,c,nil) can be detected by select('#',...).

Reply | Threaded
Open this post in threaded view
|

nil as lvalue (was Re: Proposal: Trailing comma in function calls)

Tom N Harris
In reply to this post by Axel Kittenberger
On Thursday, June 05, 2014 09:50:30 AM Axel Kittenberger wrote:
> > Alternately allow `nil` as a lvalue that acts as the bit bucket.
>
> While I'd appreciate something like that can we please keep some focus on
> the original proposal? And you know the rule, make a proposal, provide a
> patch.

Actually, I can't say I know that rule. But ignorance of the law is not an
excuse.

In any case, I hacked a bit and got this to (seemingly) work

    a,nil,c = foo()

nil in a `local` declaration list is going to take a while longer because of
the optimization that occurs. And I haven't looked at `for` yet. But this is
what I'm aiming towards:

    stat ::= varlist '=' explist |
             local varnamelist ['=' explist] |
             for varnamelist in explist do block end

    varlist ::= var {',' var}

    var ::= Name | prefixexp '[' exp ']' | prefixexp '.' Name | nil

    varnamelist ::= varname {',' varname}

    varname ::= Name | nil

And the patch right now (against Lua 5.3work2):

diff --git a/src/lcode.c b/src/lcode.c
index 2e8b3fb..6d719ee 100644
--- a/src/lcode.c
+++ b/src/lcode.c
@@ -613,6 +613,10 @@ luaK_storevar
       luaK_codeABC(fs, op, var->u.ind.t, var->u.ind.idx, e);
       break;
     }
+    case VNIL: {
+      freeexp(fs, ex);
+      return;
+    }
     default: {
       lua_assert(0);  /* invalid var kind to store */
       break;
diff --git a/src/lparser.c b/src/lparser.c
index 9349149..cec3198 100644
--- a/src/lparser.c
+++ b/src/lparser.c
@@ -871,6 +871,11 @@ primaryexp
       luaK_dischargevars(ls->fs, v);
       return;
     }
+    case TK_NIL: {
+      init_exp(v, VNIL, 0);
+      luaX_next(ls);
+      return;
+    }
     case TK_NAME: {
       singlevar(ls, v);
       return;
@@ -1138,7 +1143,7 @@
 
 static void assignment (LexState *ls, struct LHS_assign *lh, int nvars) {
   expdesc e;
-  check_condition(ls, vkisvar(lh->v.k), "syntax error");
+  check_condition(ls, (vkisvar(lh->v.k) | (lh->v.k==VNIL)), "syntax error");
   if (testnext(ls, ',')) {  /* assignment -> ',' suffixedexp assignment */
     struct LHS_assign nv;
     nv.prev = lh;

--
tom <[hidden email]>

Reply | Threaded
Open this post in threaded view
|

Re: Proposal: Trailing comma in function calls

Andrew Starks
In reply to this post by Dirk Laurie-2


On Thursday, June 5, 2014, Dirk Laurie <[hidden email]> wrote:
2014-06-05 9:50 GMT+02:00 Axel Kittenberger <<a href="javascript:;" onclick="_e(event, &#39;cvml&#39;, &#39;axkibe@gmail.com&#39;)">axkibe@...>:

> While I'd appreciate something like that can we please keep some focus on
> the original proposal?

I'm happy with the table constructor allowing an extra delimiter precisely
because {a,b,c}, {a,b,c,} and {a,b,c,nil} all do the same thing, and I am
not happy with the original proposal because for f(...), the difference
between f(a,b,c) and f(a,b,c,nil) can be detected by select('#',...).


His suggestion is that the trailing comma does not result in an extra nil.  
Reply | Threaded
Open this post in threaded view
|

Re: Proposal: Trailing comma in function calls

Thomas Jericke
In reply to this post by Luiz Henrique de Figueiredo
On 06/04/2014 06:15 PM, Luiz Henrique de Figueiredo wrote:
>> However, I never understood, why trailing commas are not allowed in
>> function calls.
> One argument for not supporting this is that argument lists are almost never
> generated automatically, which was the original motivation for supporting
> trailing commas in table constructors, as this simplifies code generation.
>
> Another is that argument lists in practice are never very long.
>
Both assumtions are wrong for many Lua scripts I know.

I actually know explicit cases were I run in exactly this problem. Of
course I can always resort in using a table as argument list for all API
functions.

--
Thomas

Reply | Threaded
Open this post in threaded view
|

Re: Proposal: Trailing comma in function calls

Andrew Starks
In reply to this post by Coda Highland



On Thu, Jun 5, 2014 at 12:32 AM, Coda Highland <[hidden email]> wrote:
On Wed, Jun 4, 2014 at 9:56 PM, Tom N Harris <[hidden email]> wrote:
> Alternately allow `nil` as a lvalue that acts as the bit bucket.

I like this best.

/s/ Adam


I remember trying this once, hoping it the "way it worked."  So, I guess I like it too. 

Reply | Threaded
Open this post in threaded view
|

Re: Proposal: Trailing comma in function calls

Axel Kittenberger
In reply to this post by Dirk Laurie-2
I'm happy with the table constructor allowing an extra delimiter precisely
because {a,b,c}, {a,b,c,} and {a,b,c,nil} all do the same thing, and I am
not happy with the original proposal because for f(...), the difference
between f(a,b,c) and f(a,b,c,nil) can be detected by select('#',...).

This is a strawman you created yourself you are now tearing down. There is not implicit nil, there never was, it is not in the proposal and if there ever will be, it will be no difficulty to properly define where implicit nils will be inserted, as been explained, never more nils than there are commas.

( Instead of implicit nils, I'd rather have the comma completely optionally implicit, that would be very nice for Lua data files. but unfortunately there are cases where this might be ambiguous, like the unary minus, or the lua function call semantics without brackets. Thus I could not suggest that)
Reply | Threaded
Open this post in threaded view
|

Re: Proposal: Trailing comma in function calls

Jay Carlson


On Jun 10, 2014 6:10 AM, "Axel Kittenberger" <[hidden email]> wrote:
>>
>> I'm happy with the table constructor allowing an extra delimiter precisely
>> because {a,b,c}, {a,b,c,} and {a,b,c,nil} all do the same thing, and I am
>> not happy with the original proposal because for f(...), the difference
>> between f(a,b,c) and f(a,b,c,nil) can be detected by select('#',...).
>
>
> This is a strawman you created yourself you are now tearing down. There is not implicit nil [...] in the proposal

No, but what if there were? It's very Lua that nil and tables perfectly fit together in a way you don't have to remember which way the language design went for trailing comma. You can have either mental model, even if one is incorrect.

Trailing comma is a very traumatic subject for many of us, because JavaScript does the wrong thing. Switching between languages, I forget semicolons too. The C compiler catches that case, at least...

Anyway, given how often I screw up with f(a, b, c, g()) where g returns multiple values, I'm not sure trailing nil would hurt me much.

Reply | Threaded
Open this post in threaded view
|

Re: nil as lvalue (was Re: Proposal: Trailing comma in function calls)

Tom N Harris
In reply to this post by Tom N Harris
Brief summary in case you haven't been following along. I'm hacking Lua to
accept 'nil' instead of a variable name in an assignment. Like the way 'undef'
is used in Perl. It lets you drop values from a list without using a dummy
variable.

I've reached a stable point in the patch. Everything (seems to) work as
expected.

1. nil as an lvalue in regular assignment statements. This does what you'd
expect, it skips the corresponding rvalue without creating an unnecessary
local variable as assigning to '_' would.

2. nil as an lvalue in local statements. A local statement without 'nil' acts
exactly the same as before. When there is a 'nil', it acts like a local
declaration followed by an assignment statement. i.e.

    local a,nil,b = 1,2,3

is the same as

    local a,b
    a,nil,b = 1,2,3

3. nil as the lvalue in a for statement. A dummy variable(s) with the name
'(nil)' is created so there's no upside to doing it, except for consistency
with the other uses.

It doesn't generate the most ideal bytecode but that wasn't a primary goal. I
did see some opportunities for improving, particularly with for loops. The
current handling of loops uses a hidden control variable in addition to the
declared variable. The value is implicitly copied during the FORLOOP opcode.
If the control variable is not named, by assigning it to nil, then there is
only need to copy it. My idea is to make the copying from the hidden variable
explicit in the bytecode.

        4       [1]     FORPREP         0 3     ; to 8
        5       [1]     MOVE            3 0
        ...
        8       [1]     FORLOOP         0 -4    ; to 5

When the loop variable is unnamed, the MOVE opcode can be omitted.

The next question becomes, can we eliminate the assignment list in the syntax?

    for 1,10 do end

    for in io.lines() do end

Or is that getting too carried away?

Anyway, attached patch made against Lua 5.3work2
 src/lcode.c   |   4 +++
 src/lparser.c | 102
++++++++++++++++++++++++++++++++++++++++++++++------------
 2 files changed, 86 insertions(+), 20 deletions(-)


--
tom <[hidden email]>

patch-nilassignments-0612.txt (6K) Download Attachment
12