Machine Learning Newsletter

Learning Lua as a Python Developer

This tutorial is not the millionth tutorial that walks you through basic concepts of Lua language. First there are quite excellent tutorials that actually aims to do exactly that. This post would be to tell a tutorial on Lua from a Pythonista, comparing Lua features with various Python features and try to create various associations. Make no mistake, I will actually go through basic concepts but somehow comparing the Lua with Python all the time. I think these two languages are very similar in various aspects and those associations may make the learning curve a little bit smoother.

(If you ask me the steeper the learning curve is better, as the slope is how fast you could learn(x axis is time). The steeper curve has higher slope, therefore you could learn faster. Not sure why steeper learning curve has connotation of hard concepts or hard to understand material. Contrarily, we should say steeper learning curve for easy concepts. But, hey. Nobody claimed that the languages are and should be consistent.)

Anyways, where was I? Yes, Lua it is. And of course Python. Making comparisons between languages not only makes you remember the syntax easily but also you could get a feeling of the language if the two languages are very similar in various aspects. If you learned Java as a your first language, then whenever you learn an OOP(Object Oriented Programming) focused programming language, you would get the same feeling. Classes and objects are kind of big deal. You’d better use it wherever you can.

But let’s step back for a second. Why Lua? It is compact, fast and dynamic. It is somehow easy to learn. You could also list a bunch of advantages of Lua as well, but my reason was quite pragmatist if there is a spectrum of reasons why you learn a new programming language. My aim is to learn more about tools in Deep Learning and more specifically Torch.

And Lua is all good, huh? Not really. It is not very popular so community support is not there and not good comparing to Python. The standard library is not very large. From Python’s batteries included approach, it gets hard to get used to DIY(Do It Yourself) from there should be a library for that if it does not exist in the standard library already.

Similarities

Strings

String definitions are same, or works and they do not have any difference. Python uses ””” for multi-line strings and Lua uses [[]]. Strings are immutable and can be concatenated to each other. Lua uses .. as concatenation operator where Python uses good old plus operator +. len, split and various functions in string module works as in the same way in Python.

Logical Operators

not, and, or works in the same way as you expect. Only difference is nil and false are evaluated as false in Lua where in Python empty string, list, set and even 0 are evaluated as False.

Table usage

Table syntax and usage of sets and lists are very similar to Python.

table = {first_key= 10, second_key= 20}
list = {a, b, c, d, e, f} -- They get automatically 1 upto 6 as keys
-- Under the hood it is still an associative array

print and type functions

They behave exactly the same way as in Python. You could get the type information via type function and print out the results with print function.

No braces and semicolons

There are no braces and semicolons. They made the compromise on the end keyword which is understandable. As long as developer adheres the indentation for his function definition and programming style, then it should be as readable as Python.

There is one way and prefereably only one way to do things

Since the language is compact and somehow barebone, there is generally only one way of doing things. Actually, sometimes there is not.(e.g. getting keys from a table) This makes it easy to read the code that other people wrote if they have not exploited the metatables quite a lot.

Explicit selfs

Both languages use explicit selfs in function definition. Lua even attempts to pass the object in a regular function call(so much object oriented after all). However, it provides a syntactic sugar which I will show in a bit.

Multiple Return values and multiple assignment

Both languages support returning multiple values in functions and you could assign multiple assignment as well. In Lua, it looks like this:

first_table, second_table = {}, {}
first_table.x = first_value
first_table, second_table = second_table, first_table

If there are more variables in the right hand side than the left hand side in the assignment operation, then Lua errors where Python raises ValueError exception, though.

Both Languages support unpacking lists

If you have a function, you could put all of the parameters into a list and then unpack them in Lua where in Python you would use * prefix to the list to unpack.

In Lua, the following

func(unpack(list))

is similar to

func(*ls)

in Python.

Enumeration on tables or dictionaries

Both languages provide a way to traverse lists with enumerated version. This holds true for dictionary or table as well.

In Lua, one could call pairs in the table to traverse both key-value in the table. If you call ipairs in the list, then you would get the enumerated indices along with the values that are in the list.

Iterators gonna iterate

for can be used for iterators in both languages. One can also define custom iterators as well which could be used in the for construct as well, which is pretty nice.

Differences

Whitespace vs end keyword

Lua opts in using end keyword for ending function definition or for loop where Python uses whitespace for function definition, control flows and so on.

Functions

Function definitions are somehow similar to Javascript dropping {} in favor of end keyword.

function factorial(n)
    if n <= 1 then
        return 1
    else
        return n * factorial(n-1)
    end
end
factorial = function (n)
    if n <= 1 then
        return 1
    else
        return n * factorial(n-1)
    end
end

could be also assigned to a variable similar to Javascript. You could define anoymous functions and assign them into a variable in Python to be fair. But more ofthen than not, people just pass the function itself rather than the variable that is assigned to.

Variable Scope

All of the variables are defaulted as global variables. Not sure why the language creators thought this is a good idea, but you could explicitly put local keyword in front of the variable declaration to make it “local”. Contrarily, you could explicitly make a global variable putting global in front of the variable declaration.

Tables vs Dictionaries, Lists and Sets

In Lua, we trust tables, Python needs to bring dictionaries, lists and sets. Tables are the only compound data structure(did anyone tell that Lua is a very compact language). Tables are associative arrays similar to dictionaries in Python, but they could be also used as lists(defaulting the keys as integers).

x,y “range” syntax includes beginning and end-point

The tables when they are used as lists, start indexing at 1. When you define a range of integers using 1,100, which produces 100 integers from 1 upto 100 including 1 and 100. If you have the list, you could get the length of the list via #list.

Objects

Lua does not support object oriented programming. They provide certain ways of doing OOP, similar to Javascript’s prototype based style, but even that requires somehow different syntax to call the object. Of course, there is no object by the way. It is a table which you could call functions from it. You could add almost any behavior on tables via “metatables” though.

function object:func(x)
    self.x = 5
end

is nothing but a syntactic sugar for the following for example:

object.func = function(self, x)
                self.x = 5
              end

Lua is fast

I meant LuaJIT is fast. Comparing to Python, it is quite faster, which is important if you are doing expensive numerical operations. Considering its dynamic nature, this is a little surprise to me,but it is a good surprise.

Lua assigns nil when a variable is not defined

If you are accessing a variable that you did not define in Lua, it does not error, it silently assigns a nil to the variable and does not complain where you would get a NameError in Python. In general, since most of the things are tables and if you access a non-existent key to the table, it simply returns nil, there would be less explicit error or exception but rather nil checking for those statements if the key actually exists in the first place in the table.

Lua does proper tail recursion

Lua does proper tail recursion where Python does not.

comments powered by Disqus