I have been writing a lot of Lua recently, and it hasn’t been a very pleasant experience.
The first thing that took a little while to get used to is the fact that table indices start at 1, not 0. Admittedly, it is possible to configure this, but the default is certainly confusing and I have been battling nil errors in tables that I knew couldn’t be empty.
But the worst was the following:
function f() print("f()") end f(2) function f(n) print("f(n):" .. n) end
This snippet will print "f()", indicating that when the interpreter read f(2) and couldn’t find a matching function (since it wasn’t defined yet), it decided to get rid of my parameter and call f() instead. And all this without any error or warning.
It doesn’t stop here:
function f(n) if n then print("f(n):" .. n) else print("f(nil)") end end f()
This will print… f(nil).
Here again, the interpreter couldn’t find a signature matching f() so it decided to pick f(n) and simply pass nil as parameter.
I am willing to suffer some discomfort when using a dynamically typed language, but this is really terrible and I dread the fact that it’s inevitably going to cause more bug hunting in the future….
A couple more things of interest:
- Writing in Lua has confirmed me in my conviction that using end as a
closing statement is really painful. Not only is it noise when I read a source but it just
makes it impossible to match a closing end to its opening statement (you will also notice that
there is not always such a thing: if requires a then but the declaration
of functions doesn’t require anything). If you’re going to create a language, do me
a favor and pick symmetric opening/closing tokens (or significant spacing, like Python). - Lua is doing something clever with its comment syntax, which I haven’t seen in any other
languages: comment blocks are defined by --[[ and --]] but if you add
a third hyphen on the opening part, then the commenting is disabled again:--[[ This is commented out --]] ---[[ ... but this is not --]]
I like the practicality of this idea.
What I find disappointing is that Lua is a language that’s more recent than Python, so it’s hard to understand why it’s being so lackdaisical about signaling errors. Having said that, there is no question that Lua is alive and well and used increasingly more often as an embedded languages, especially in video games, so it’s most likely here to stay…
#1 by Ignacio Burgueño on March 2, 2010 - 1:26 pm
Mmm, there’s no such thing as function signatures in Lua. Your first example is actually doing this:
f = function ()
print(“f()”)
end
f(2)
f = function (n)
print(“f(n):” .. n)
end
That is, a function is assigned to variable ‘f’, then it is called, then a different function is bound to ‘f’. I suppose you were expecting a behaviour similar to Javascript, but that’s not the case here.
#2 by Cedric on March 2, 2010 - 1:39 pm
Then how do you explain that once both functions are defined, if I invoke:
f()
f(2)
I get:
f(nil)
f(n):2
?
Based on your explanation, there is only ever one function called “f”, and it’s the last one that was defined. But the output above shows that there is overloading at work…
I’m confused.
#3 by Ignacio Burgueño on March 2, 2010 - 1:52 pm
I’m guessing what the code you’re running could be upon the output you posted.
I think it is something like this, right?
function f()
print(“f()”)
end
function f(n)
if n then print(“f(n):” .. n)
else print(“f(nil)”)
end
end
f()
f(2)
The last function bound to variable ‘f’ is the only one that gets called. The first time is called with no arguments:
f() — so that will print “f(nil)”
The second time, with 2:
f(2) — so the argument ‘n’ in your function is not nil, it is ‘2’
But in both cases, the function that is being called is always the second one. If that’s not clear, delete the first definition of f() and run the script again. You’ll have the same output.
#4 by Cedric on March 2, 2010 - 1:59 pm
You are correct, Ignacio, there is no overloading at all.
Again, it would be nice if LUA told me that one of my two functions is being ignored. It would be such a more friendly language to work with if they increased the syntactic and semantic checking…
#5 by Ignacio Burgueño on March 2, 2010 - 2:00 pm
BTW, I’ve posted the example code here:
http://ideone.com/buZOsGJb
#6 by Ignacio Burgueño on March 2, 2010 - 2:18 pm
Well, I don’t have much exposure to other scripting languages but it seems that this behaviour is the common one. Python does not warn about it either:
def f():
print “first definition”
def f():
print “second definition”
f()
Javascript does the same thing. Don’t know about Ruby.
Anyway, you can make Lua warn you about that, with the help of metatables. See this example:
http://ideone.com/fOjRSFvL
Some of these issues are covered in the (non official) Lua Faq:
http://batbytes.com/luafaq/
#7 by Cedric on March 2, 2010 - 2:28 pm
Ignacio, I’m both impressed and scared by the fact that it’s possible to do that 🙂
#8 by Anonymous on March 2, 2010 - 4:02 pm
Ignacio already covered your actual problems, but if you don’t like the “silent” overriding globals you should look at strict.lua in the distribution.
Also, it is Lua (note the case) 🙂
#9 by Cedric on March 2, 2010 - 4:10 pm
Oops, I corrected to “Lua”. Thanks.
I’m not sure I have the options to change these defaults since I’ve been writing this Lua code to run it as a World of Warcraft add-on…
Pingback: Lua and World of Warcraft « Otaku, Cedric's weblog
#10 by Bill K on March 3, 2010 - 12:58 pm
I’m not really comfortable at all with the idea of:
define function/method
code that executes
define function/method
This just seems really really wrong to me. I would think that to do anything where the code that executes wasn’t at the end would be really irritating no matter how you slice it.
In fact, I’d be a proponent of writing everything in functions and having a small launcher (like a java/c main) that kicked stuff off.
In general I guess I’d say If you are forced into using a language without structure or with too many ways to do something, the best you can do is rewrite the code to impose some structure/patterns that make it more predictable & readable and eliminate all the smart tricks that save a few keystrokes but do something that you have to think about when you first see it.
#11 by Gunjan Mukherjee on May 16, 2010 - 10:21 am
Hi,
i want to do programming in LUA for android phone.i know LUA but how i will start work on android.it will be good if u will send me the list of function and their use or if u have any URL where i can study this .
Thanks
Gunjan Mukherjee
#12 by air bear on October 1, 2010 - 4:32 am
Its very odd that Lua is a language that came out of Brazil (lua = moon in portuguese). I’ve had my share of Lua suffering in doing scripts for this program Ecotect, which models building performance criteria.
did i stumble on a support group?
-bear jaw
#13 by skolkovo on October 28, 2010 - 3:28 am
Getting this far with Lua has been a real struggle. I know no C, C++, Cocoa etc, so I dont know if Lua is easy for people with such a background (though it heartened me when he described Lua as horrid). But I do have a lot of experience of the various flavours of Microsoft VB and VBA, and of JavaScript, PHP, AppleScript, ActionScript 2 and 3, and other useful technologies like XML, SQL etc, all self taught. That brings a confidence that things should be possible, but it barely overcomes the why the bloody hell should I add features that should have been there in the first place?
#14 by Anonymous Bryan on November 6, 2010 - 8:10 am
Hey, I get an error that says brush:python not found. I think that this is the code formatter for python code that you are using for your lua examples? I also think that it is server side.