A Look at Lua

An overview of the compact yet powerful Lua programming language.
Object-Oriented Programming

Lua has some basic OOP capabilities. The self parameter is an integral concept in any object-oriented language, and it is one of the few OOP concepts that Lua has. Many object-oriented languages tend to hide the self mechanism from you so that you do not have to declare this parameter. Lua hides this parameter with the colon operator. You also can use the colon, a function and a table to emulate a class. Because Lua does not have the class concept, each object defines its own behavior and shape:

Earth = {martians = 5389}
function Earth:casualties (survivors)
 Earth.martians = Earth.martians - survivors
 print("Earth is free! "..Earth.martians.." martians survived!")
end

Earth:casualties(5380)

The colon in the above example is used to add an extra parameter in the method definition. It also adds an extra argument in the method call. You don't have to use the colon. Lua programmers can define a function with the dot syntax and call it with the colon syntax, or vice versa if they add an extra parameter:

Earth = {martians = 5389,
 casualties = function (self, survivors)
  self.martians = self.martians - survivors
  print("Earth is free! "..self.martians.." martians survived!")
 end
}

Earth.casualties(Earth, 5380)
Earth.martians = 5389
Earth:casualties(5380)

In this case, the function had to be part of the table so that it could be called via the dot or the colon syntax. Note that I also had to give the function the self parameter for either calling method to work. Although these are simple OOP examples that scratch only the surface of OOP, you can find out about inheritance and other OOP implementations in the Lua Reference Manual or in the book Programming in Lua (both are available for free from the Lua Web site).

Show and Tell

Now, let's compare programming in Lua to programming in Python. First, let's write a trivia game. Here is some simple Lua code that uses a table as a dictionary to store both the questions and the answers:

print("What's your name?")
name = io.read()
questions = {
  ["Which came first? Minix or Unix?"] = "Unix", 
  ["Who created Linux?"] = "Linus Torvalds",
  ["In what year was Linux created?"] = "1991"
}

correct_answers = 0
for key,value in pairs(questions) do
print(key)
answer = io.read()
if answer == value then
  correct_answers = correct_answers + 1
end
end
if correct_answers == 0 then
print("You need to browse Wikipedia!")
else
print("\nGood job, "..name.."!")
print("Correct answers: "..correct_answers..")
end

Next, let's break it down and analyze it line by line. On the second line, the variable name is given the value io.read(). The io library has many functions that handle all sorts of input and output, but I'm using it only for keyboard input.

On the next line is the variable questions. The questions variable's value is a table that I have used like a dictionary to store both the questions and the answers. The questions are in brackets to tell Lua that they are the table's key.

Skipping the third line, there is a for loop whose function here is to use pairs() to find the key and the values of each item in the table. It then needs to place the value of the key and the value of the key's value into the variables key and value.

After printing the key (which contains the question), Lua places the user's answer through io.read() into the answer variable and checks to see whether it equals the proper answer. If the answer is correct, it adds 1 to the value of the correct_answers variable and repeats the process until there are no more items in the table to go through.

Next, Lua checks to see whether users got any of the questions correct and then prints a message telling users to learn more about UNIX (and its variants) hacker history or congratulates users on how many questions they answered correctly. Notice the concatenation operators on the 16th line.

In Python, the easiest way to do the above game would be like this:

name = raw_input("What's your name?\n")
questions = {"Which came first? Minix or Unix?":"Unix",
"Who created Linux?":"Linus Torvalds",
"In what year was Linux created?":"1991"}
correct_answers = 0

for key in questions:
  print key
  answer = raw_input()
  if answer == questions[key]:
    correct_answers += 1
	
if correct_answers == 0:
  print "You need to browse Wikipedia!"
else:
  print "\nGood job, " + name + "!"
  print "Correct answers: ", correct_answers

You may notice that it's easier to get keyboard input in Python than in Lua, but dictionaries are easier to identify and look much prettier in Lua. The for loop is a little more complex in Python than it is in Lua, because Python needs to know the key to be able to get the key's value. In Lua, the pairs() function breaks apart the key and its value from the dictionary table, making it much cleaner and easier to get data from tables than in Python. As for lines of code, not counting the many “ends”, Lua wins hands down with 13 lines of code versus 17 in Python. Even though Lua programmers would be typing more, their code is much easier to sift through, especially when it's thousands of lines long, because of Lua's use of end rather than colons (as in Python).

Now, how about a GUI? Is programming a GUI in Lua the same, easier or more difficult than in Python? Before you try to answer that question, determine which program in the two languages will be easier to maintain, read and understand without comments. Here, I use the WxGTK library for a GUI. The only hitch with wxLua is that it is an entirely separate program. A wxLua application will not run with the regular Lua interpreter, so you must run it with the wxlua program.

Here's a GTK GUI program made with wxLua:

frame = wx.wxFrame(wx.wxNull, wx.wxID_ANY, 
  "wxLua App", wx.wxDefaultPosition, 
  wx.wxSize(250, 50),
  wx.wxDEFAULT_FRAME_STYLE)

frame:Show(true)

Now, here's the code for a program that does the same job in GTK, but with wxPython:

from wxPython.wx import *
class Main(wxApp):
  def OnInit(wxApp):
    frame = wxFrame(NULL, -1, "wxPython App")
    frame.Show(true)
    return true

Main().MainLoop()

This time, Lua's lack of necessary formatting and full-fledged OOP makes an easy job easier. Rather than create a class and function, wxLua incorporates everything needed for this GUI application in a single system function, whereas Python and wxPython require a Class as well as a function. Also note that Lua imports system libraries automatically. This wxLua application exercises some of Lua's OOP features that I discussed previously. The application creates the frame, sets the frame's name and the frame values, and then it calls the Show() function from within the wxFrame method using the colon. You also can call the frame with the period syntax rather than the colon:

frame.Show(frame, true)

______________________

Comments

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

Not really a fair treatment of Python though, is it?

magnus's picture
  1. "There is no need to worry about different types of integers." There is no need to do that in Python either nowadays. The conversion between "regular integers" and long ones is done automagically. Take the following function:


    def frac(n):
    if n == 0: return 1
    else: return n * frac(n - 1)

    Evaluating frac(10) gives the result 3628800 while frac(30) returns 265252859812191058636308480000000L.

  2. "You can add a float, long integer or a double to any other type of integer or number without a hitch in Lua. In contrast, doing this can cause programs written in Python 2.4 or older versions to crash." Really? I've never heard of this problem. Do you have any references?
  3. "In contrast to Python, Lua does not focus on 100% backward compatibility." That Python would focus on 100% backward compatibility is just plain wrong. Code I've written broke when moving from version 2.4 to 2.5 due to changes in generators. This is the only time I've personally been bitten by it but every version of Python has broken something from earlier versions. AFAIU Python 3000 will break a whole lot of older Python programs.
  4. "Unlike Python, global variables do not need to be declared." They don't need to be declared at all, not on a global level. If a function wants to access a global variable then _it_ has to declare it as global. Contrast that to the following point.
  5. "Exactly the opposite of Python, most variables in Lua are global by default, and you must declare the variable "local" to make it a local variable rather than assuming that all variables are local." Variables in Python are local by default, which in my experience better reflect how variables are used by programmers.
  6. The for loop is a little more complex in Python than it is in Lua, because Python needs to know the key to be able to get the key's value." It's possible to iterate over both key and value in Python as well:


    h = {1:'hello', 2:'world'}
    for k, v in h.iteritems():
    print k, v

In general it's a good article, it shows off some interesting points in Lua. In order to make a comparison between two languages it's necessary to have very good knowledge of both languages, otherwise there's a real risk that one language is the favourite simply because the author knows that one the best. This piece definitely suffers from that.

I also believe it would have been better without the author's personal opinions on aesthetics sprinkled across the piece.

Webinar
One Click, Universal Protection: Implementing Centralized Security Policies on Linux Systems

As Linux continues to play an ever increasing role in corporate data centers and institutions, ensuring the integrity and protection of these systems must be a priority. With 60% of the world's websites and an increasing share of organization's mission-critical workloads running on Linux, failing to stop malware and other advanced threats on Linux can increasingly impact an organization's reputation and bottom line.

Learn More

Sponsored by Bit9

Webinar
Linux Backup and Recovery Webinar

Most companies incorporate backup procedures for critical data, which can be restored quickly if a loss occurs. However, fewer companies are prepared for catastrophic system failures, in which they lose all data, the entire operating system, applications, settings, patches and more, reducing their system(s) to “bare metal.” After all, before data can be restored to a system, there must be a system to restore it to.

In this one hour webinar, learn how to enhance your existing backup strategies for better disaster recovery preparedness using Storix System Backup Administrator (SBAdmin), a highly flexible bare-metal recovery solution for UNIX and Linux systems.

Learn More

Sponsored by Storix