[PUZZLE] Appending to a list

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

[PUZZLE] Appending to a list

Dirk Laurie-2
I used to have the following statement in nearly all of my programs.

    local append = tinsert

where tinsert is a local variable with value table.insert. The idea is
that when the `pos` parameter is omitted, I prefer for the sake of
easy reading to use a different name.

Today, I needed to do this instead:

local append = function(tbl,x) tinsert(tbl,x) end

Why would that be?

Once you have figured it out, the next question is: should I have
expected table.insert to behave that way or is it a deviation from
what the manual says?

Reply | Threaded
Open this post in threaded view
|

Re: [PUZZLE] Appending to a list

Daurnimator
On 8 September 2017 at 15:31, Dirk Laurie <[hidden email]> wrote:

> I used to have the following statement in nearly all of my programs.
>
>     local append = tinsert
>
> where tinsert is a local variable with value table.insert. The idea is
> that when the `pos` parameter is omitted, I prefer for the sake of
> easy reading to use a different name.
>
> Today, I needed to do this instead:
>
> local append = function(tbl,x) tinsert(tbl,x) end
>
> Why would that be?

You probably called something like:

append(t, s:gsub("foo", "bar"))

==> gsub returns two values, and the extra argument makes table.insert
do something that's not append.


> Once you have figured it out, the next question is: should I have
> expected table.insert to behave that way or is it a deviation from
> what the manual says?

What is the deviation from the manual?

The main take away is that optional middle arguments are evil.
See http://lua-users.org/lists/lua-l/2014-08/msg00061.html

We can find your reply here:
http://lua-users.org/lists/lua-l/2014-08/msg00063.html

Reply | Threaded
Open this post in threaded view
|

Re: [PUZZLE] Appending to a list

Dirk Laurie-2
2017-09-08 7:51 GMT+02:00 Daurnimator <[hidden email]>:

>
> On 8 September 2017 at 15:31, Dirk Laurie <[hidden email]> wrote:
> > I used to have the following statement in nearly all of my programs.
> >
> >     local append = tinsert
> >
> > where tinsert is a local variable with value table.insert. The idea is
> > that when the `pos` parameter is omitted, I prefer for the sake of
> > easy reading to use a different name.
> >
> > Today, I needed to do this instead:
> >
> > local append = function(tbl,x) tinsert(tbl,x) end
> >
> > Why would that be?
>
> You probably called something like:
>
> append(t, s:gsub("foo", "bar"))
>
> ==> gsub returns two values, and the extra argument makes table.insert
> do something that's not append.

Almost that: I called something like

append(t, myfunc(...))

where myfunc has nice explicit return statements returning one value,
except when none of them has been hit, so that at the end of the function
it returns nothing.

> > Once you have figured it out, the next question is: should I have
> > expected table.insert to behave that way or is it a deviation from
> > what the manual says?
>
> What is the deviation from the manual?

I take that reply to mean: there is no deviation from the manual.
Which is certainly correct in the situation you guessed.

> The main take away is that optional middle arguments are evil.

True, but it's too late now.

What the manual might have spelt out, IMHO, is that a function
with optional middle arguments behaves like a vararg function,
since the number of arguments is not constant.

Reply | Threaded
Open this post in threaded view
|

Re: [PUZZLE] Appending to a list

Andrew Starks-2
In reply to this post by Dirk Laurie-2
On Fri, Sep 8, 2017 at 12:31 AM, Dirk Laurie <[hidden email]> wrote:

> I used to have the following statement in nearly all of my programs.
>
>     local append = tinsert
>
> where tinsert is a local variable with value table.insert. The idea is
> that when the `pos` parameter is omitted, I prefer for the sake of
> easy reading to use a different name.
>
> Today, I needed to do this instead:
>
> local append = function(tbl,x) tinsert(tbl,x) end
>
> Why would that be?

It's as Daurnimator said.

While it does nothing toHowever, I like:


local function append(tbl, x, ...)
  if x == nil then
    return tbl
  else
    tinsert(tbl, x)
    return append(tbl, ...)
  end
end

or the golf version...

local function append(tbl, x, ...)
    return x == nil and tbl or append(tinsert(tbl, x) or tbl, ...)
end


Sorry. I saw puzzle and felt like participating. :)

>
> Once you have figured it out, the next question is: should I have
> expected table.insert to behave that way or is it a deviation from
> what the manual says?
>

I agree that optional middle parameters are extremely clever and
tricky and sometimes convenient.


- Andrew Starks

Reply | Threaded
Open this post in threaded view
|

Re: [PUZZLE] Appending to a list

Martin
In reply to this post by Dirk Laurie-2
On 09/08/2017 08:03 AM, Dirk Laurie wrote:
> Almost that: I called something like
>
> append(t, myfunc(...))
>
> where myfunc has nice explicit return statements returning one value,
> except when none of them has been hit, so that at the end of the function
> it returns nothing.
>

You may call "table.insert(t, (myfunc(...)))" with same results.

  Lua 5.3.4  Copyright (C) 1994-2017 Lua.org, PUC-Rio
  > f = function() return end
  > g = function() return nil end
  > f()
  > g()
  nil
  > (f())
  nil
  > t = {}
  > table.insert(t, f())
  stdin:1: wrong number of arguments to 'insert'
  stack traceback:
    [C]: in function 'table.insert'
    stdin:1: in main chunk
    [C]: in ?
  > table.insert(t, (f()))


-- Martin