Search FAQ

Gammon Forum

Notice: Any messages purporting to come from this site telling you that your password has expired, or that you need to verify your details, confirm your email, resolve issues, making threats, or asking for money, are spam. We do not email users with any such messages. If you have lost your password you can obtain a new one by using the password reset link.
 Entire forum ➜ MUSHclient ➜ Lua ➜ Having trouble with variable number of arguments

Having trouble with variable number of arguments

Posting of new messages is disabled at present.

Refresh page


Pages: 1 2  

Posted by Cage_fire_2000   USA  (119 posts)  Bio
Date Wed 10 Sep 2008 03:08 PM (UTC)
Message
Ok, from what I gathered from the manuals, you can define a function with a varying number of arguments like the example in the one manual:


    printResult = ""
    
    function print (...)
      for i,v in ipairs(arg) do
        printResult = printResult .. tostring(v) .. "\t"
      end
      printResult = printResult .. "\n"
    end


but when I try something similar to that, 'arg' is always nil, what am I doing wrong?

Top

Posted by Worstje   Netherlands  (899 posts)  Bio
Date Reply #1 on Wed 10 Sep 2008 03:51 PM (UTC)
Message
Funny that you ask. I had the same issue, and asked in the #lua irc channel around a week ago. Explanation is as follows:

The PIL is outdated, and describes Lua 5.0.x and not 5.1.x. In Lua 5.1.x the syntax changed so that arg does not exist anymore. Rather, you can get the various arguments through the {...} specifier. In my case, I solved it as follows:

printResult = ""
    
    function print (...)
      local arg = {...}
      for i,v in ipairs(arg) do
        printResult = printResult .. tostring(v) .. "\t"
      end
      printResult = printResult .. "\n"
    end


This because a literal replacement of all instances of arg by {...} does not work for some reason.
Top

Posted by Cage_fire_2000   USA  (119 posts)  Bio
Date Reply #2 on Wed 10 Sep 2008 04:09 PM (UTC)
Message
Thanks
Top

Posted by WillFa   USA  (525 posts)  Bio
Date Reply #3 on Wed 10 Sep 2008 10:40 PM (UTC)
Message
Quote:
This because a literal replacement of all instances of arg by {...} does not work for some reason.


function foo (...)
print (...)  -- works fine
for _,v in ipairs{...} do  -- works fine. Sugar for ipairs({...})
print (v)
end
end
print ( {...}[1] )  --does not work.


But then again, {1,2,3}[1] doesn't work either. I guess you can't index a table that is in the process of being constructed. :)


Top

Posted by David Haley   USA  (3,881 posts)  Bio
Date Reply #4 on Wed 10 Sep 2008 10:58 PM (UTC)
Message
That's because syntactically you can index identifiers, not table constructors. I guess it's the difference between the value and the symbol name (i.e. identifier).

Also, it's more efficient to assign {...} to a temporary variable: otherwise, you're creating a new table every time.

David Haley aka Ksilyan
Head Programmer,
Legends of the Darkstone

http://david.the-haleys.org
Top

Posted by Nick Gammon   Australia  (23,122 posts)  Bio   Forum Administrator
Date Reply #5 on Thu 11 Sep 2008 06:07 AM (UTC)
Message
This works:


print ( ({ 1, 2, 3, 4 }) [1] )    --> 1


The extra brackets seem to force it to stop constructing the table and make it useable as such.

Similarly:


print ( "testing" : upper ())   -- Error: ')' expected near ':'

but:

print ( ("testing") : upper ())  --> TESTING



- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

Posted by David Haley   USA  (3,881 posts)  Bio
Date Reply #6 on Thu 11 Sep 2008 02:00 PM (UTC)
Message
That's interesting. It looks like you can index on expressions (of course -- not just identifiers, silly me) and the curlies are table constructors whereas the parentheses bring you to the expression level.

David Haley aka Ksilyan
Head Programmer,
Legends of the Darkstone

http://david.the-haleys.org
Top

Posted by Worstje   Netherlands  (899 posts)  Bio
Date Reply #7 on Thu 11 Sep 2008 04:41 PM (UTC)
Message
Hrm, I don't really see the reasoning why one (with parentheses) would work while the other would not (without parentheses). My reasoning is as follows: when you get the closing curly } the table has been completed for as far initialization is concerned, so it should be indexable. I see no other way to 'further' initialize it once it's been closed.

Likewise, the way to specify keys with ["xxx"] confuses me. Why does "xxx" not work? I've always taken it as a weird but necessary quirk of Lua's to work around, but it -does- bug me.
Top

Posted by David Haley   USA  (3,881 posts)  Bio
Date Reply #8 on Thu 11 Sep 2008 06:14 PM (UTC)
Message
I agree that a table constructor should basically be an expression syntactically, because as-is you can assign it to variables etc.

Specifying keys with ["xxx"] is a very highly desirable feature, because [xxx] means something quite different from "xxx" -- the former means the variable xxx and the latter means the string. It would be kind of disastrous if you could only index by strings...

There is syntactic sugar for the string form: t.xxx is the same as t["xxx"].

David Haley aka Ksilyan
Head Programmer,
Legends of the Darkstone

http://david.the-haleys.org
Top

Posted by Worstje   Netherlands  (899 posts)  Bio
Date Reply #9 on Thu 11 Sep 2008 06:36 PM (UTC)

Amended on Thu 11 Sep 2008 06:38 PM (UTC) by Worstje

Message
I know that t.xxx == t["xxx"]. However, either I misunderstand your explanation, or you misunderstood my question. I understand the difference between t["xxx"] and t[xxx] very well. However, given this:


local xxx = "q"
a = { ["xxx"] = "a" }  -- assigns "a" to a.xxx
b = { xxx = "a" }      -- assigns "a" to b.xxx
c = { [xxx] = "a" }    -- assigns "a" to c.q
d = { "xxx" = "a" }    -- error: '}' expected near '='


I'd expect the last table to work and have (d.xxx == "a") as a result. Why is -that- assignment not supported?
Top

Posted by David Haley   USA  (3,881 posts)  Bio
Date Reply #10 on Thu 11 Sep 2008 06:50 PM (UTC)
Message
Oh. I thought you were talking about indexing in general, not keys in constructors.

Well, I think the reason is that if it sees a string value, it inserts it as into a list. Generally, the Lua authors do not like syntax that would require a complex grammar. You could infer that a string followed by an equal sign actually means a key, but that makes things more complicated. Furthermore it makes the syntax more visually complicated by adding extra sigils, which is another thing they tend to not like.

As for why ["xxx"] is allowed in the constructor, that is because it is a more general form of specifying a key by any value whatsoever, including "by accident" string values. It doesn't really strike me as odd that this is allowed but the straight string isn't.

Why is this really an issue though? Is the idea that the string form is more explicitly a string key than the identifier form?

David Haley aka Ksilyan
Head Programmer,
Legends of the Darkstone

http://david.the-haleys.org
Top

Posted by Worstje   Netherlands  (899 posts)  Bio
Date Reply #11 on Thu 11 Sep 2008 07:07 PM (UTC)
Message
Because it makes using tables as pre-initialized data-structures rather annoying. I switch between Lua and a bunch of other languages quite often, and I keep doing it wrong.

The form used in table a has two characters I never need to type in other languages, and I do it wrong atleast twice a week (to the point where I can dream the error I mentioned). The form in table b actually looks to me (in a simple glance) as if it should be assigning the contents of a variable, rather than a literal xxx. It directly opposes my gutfeeling.

While 'language X should be changed to be more like language Y' is a horrible (and flawed) argument, I find it hard to say that this syntax is very logical to me. I'm not too knowledgeable, but it seems to me you would only start to try and interpret what you've just read once you read the comma/ending brace that signifies the end of the previous entry. Lua is a very spartan scripting language, and I respect that (as much as I might hate it half the time), but in this case the decision not to support {"xx" = y} syntax boggles me kind of.
Top

Posted by David Haley   USA  (3,881 posts)  Bio
Date Reply #12 on Thu 11 Sep 2008 07:20 PM (UTC)
Message
I dunno, I guess I've never really found it counterintuitive. That might be because in Perl, you specify string keys in hash constructors as literals, not as strings. I also don't construct tables manually that often at all. Either I have a table that I want to save and use a serializer, in which case I don't care what it looks like under the hood, or I create a table and later populate its fields. From what you've written I can see where you're coming from though.

I don't know if there's a deeper reason behind their decision. Sometimes they have pretty good reasons (e.g. syntactic ambiguity) for not wanting such-and-such syntax. You could try bringing it up on the Lua mailing list. You might get a useful answer as to why they don't do it, or you might even get it considered as a feature request. :-)

David Haley aka Ksilyan
Head Programmer,
Legends of the Darkstone

http://david.the-haleys.org
Top

Posted by Worstje   Netherlands  (899 posts)  Bio
Date Reply #13 on Thu 11 Sep 2008 08:06 PM (UTC)
Message
Heh, I might do it. I'm not too fond of mailinglists though, but who knows. ^_^
Top

Posted by Nick Gammon   Australia  (23,122 posts)  Bio   Forum Administrator
Date Reply #14 on Thu 11 Sep 2008 09:21 PM (UTC)
Message
Quote:

Hrm, I don't really see the reasoning why one (with parentheses) would work while the other would not (without parentheses).


I asked that question on the Lua mailing list, as I was a bit puzzled too. Roberto Ierusalimschy replied as follows:




Because Lua does not enforce the use of semicollons, it needs other means to recognize statement boundaries. So, it is helpful to reduce the number of tokens that can start a statement. For instance, if the first syntax were allowed, people would expect the next one to be allowed too:


   {f, g, h}[1]("hi")    -- call 'f'


That would create ambiguities in the next fragment:


 a = i
 {f, g, h}[1]("hi")


It could mean any of these:


 a = i; {f, g, h}[1]("hi")
 a = i{f, g, h}[1]("hi")


Forcing the use of parentheses reduce the cases of ambiguity.



- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

The dates and times for posts above are shown in Universal Co-ordinated Time (UTC).

To show them in your local time you can join the forum, and then set the 'time correction' field in your profile to the number of hours difference between your location and UTC time.


46,067 views.

This is page 1, subject is 2 pages long: 1 2  [Next page]

Posting of new messages is disabled at present.

Refresh page

Go to topic:           Search the forum


[Go to top] top

Information and images on this site are licensed under the Creative Commons Attribution 3.0 Australia License unless stated otherwise.