The "I Love Lua, but..." post
Posted: Wed Apr 27, 2011 9:59 am
I've been thinking about writing a post like this for a while now.
Lua is very likable. I'm sure all of you guys love it, otherwise you'd probably would spend your time with pygame or some other engine in some other language.
But I'm sure that there are things here and there that you don't like.
Yesterday I spoke about Lua on an agile meeting, and today someone from that meeting sent me this article about Lua. Which links to this other article.
I'm not saying that I agree to what those articles say - but I think that inspecting your tools, and knowing their (potential) short comings, is usually a healthy idea.
So I thought - hey, we should start a thread about the "things that we don't like" in Lua.
So here's the list of things that I don't like. I've more or less sorted them out in descendant order of importance.
Disclaimer: I still love Lua.
Lua is very likable. I'm sure all of you guys love it, otherwise you'd probably would spend your time with pygame or some other engine in some other language.
But I'm sure that there are things here and there that you don't like.
Yesterday I spoke about Lua on an agile meeting, and today someone from that meeting sent me this article about Lua. Which links to this other article.
I'm not saying that I agree to what those articles say - but I think that inspecting your tools, and knowing their (potential) short comings, is usually a healthy idea.
So I thought - hey, we should start a thread about the "things that we don't like" in Lua.
So here's the list of things that I don't like. I've more or less sorted them out in descendant order of importance.
Disclaimer: I still love Lua.
- Lua's "global by default" idea. I think a "local by default" or even a "nothing by default" (i.e. you always have to specify either "global" or "local" are better, except for maybe trivial programs.
- The : operator. I would have preferred that foo.bar(baz) included foo as the first parameter of bar by default. I would not mind that the : operator was put there for the opposite case. Incidentally, I would not mind if "self" was implicit in all functions. In short: I prefer the Javascript way.
- Lua doesn't handle directories natively. This makes using require() very frustrating, because you can't use relative paths. The fact that folders are not supported on ANSI C doesn't justify that they aren't in LUA IMHO. If you are not going to acknowledge that there's a filesystem underneath, then don't give me a require() function, and make me require stuff from C. Or at the very least, give me a require function that can be used with relative paths.
- That the standard libs offer so little - specially table and string. I don't like inconsistency on what is provided and what not. math for example has sin and cos, but then it has foor but not round.
- Related to the previous one: Lua invents its own regexp, and then bases most of its string-related stuff on it.
- list-returning function calls used as parameter only "expand" if they are the last parameter. Otherwise, they return the first value only. I think this is done because some functions in the standard lib actually return two values, and people can use them without noticing anything, treat them as returning one value, and the code will work. I would prefer having two versions of the methods in the library - the "usual" one returning just the first value, and an "extended" version returning all of them, and expanding all functions.
- Local variables are second-class citizens. You have to use the debug lib for manipulating them. That should be built-in: if I have a _G, I'd also like to have a _L.
- metamethods aren't looked up using __index. This is kind of a edge case, but it's giving me lots of trouble with middleclass-extras: if table t1 has t2 as its index table (getmetatable(t1).__index=t2), and t2 has an index in t3, and t3 defines a method called __tostring, then tostring(t1) should use that method. Well, it doesn't, because in Lua metamethods are looked up differently than regular methods (with a rawget on the metatable, not with metatable.methodname)
- Not being able to use the dot notation on table members when the keys are reserved words. I'd really like to be able to say my.function = function() instead of my['function'] = function() ... . And yes, I can say my.func instead. I still don't like it. This bugs me because it is a trivial parsing problem.
- ~= instead of !=, and .. instead of +