CSC 415
John Imboden
10/27/2011
A Short History of Lua
Lua was developed as a lightweight embeddable scripting language for the purpose of a small in house project for PETROBRAS (a Brazilian oil company) for a data entry program. It was designed by a committee consisting of Roberto Lerusalimschy, Luiz Henrique de Figueiredo, and Waldemar Celes. Lua is a modified mixture of two other languages created by the same people called Sol, and DEL. Something of importance to note is the fact that Lua was "raised" following a bottom up design. This sets it apart from many of the larger languages that are created using a top down design and thus it is highly specialized in its functionality. Unfortunately an issue with something designed to be small is that it may quickly outgrow its initial purpose as its user base grows, since each user has his/her own individual needs. "In December 1996, the magazine Dr. Dobb's featured an article about Lua."[1] This is the start of a major exposure for the language. Soon after the language was used in a LucasArts game called "Grim Fandango" that was released in 1997. Now in 2011 there are several game companies that use Lua in their productions, including Blizzard and BioWare. Even though Lua is known mostly for its uses in game programming it is not limited to just that realm of game development. "Its uses range from adventure games to web-servers to telephony-network testing to Ethernet switches."[1]
Names, Bindings, and Scopes
"Names (also called identifiers) in Lua can be any string of letters, digits, and underscores, not beginning with a digit. This coincides with the definition of names in most languages. "[4] Lua also contains several keywords that are reserved and cannot be used as identifiers, these are very similar to most other language's reserved words.[see appendix a for a list of reserved words] "Since extension languages are not for writing large pieces of software, mechanisms for supporting programming-in-the-large, like static type checking and information hiding, are not essential."[2] This means that all variables in Lua are global unless explicitly declared as local. Thanks to Lua's built in garbage collection feature it throws away unused variables so as to lower as much memory usage as possible. " Lua is a lexically scoped language. The scope of variables begins at the first statement after their declaration and lasts until the end of the innermost block that includes the declaration."[4] "Lua is a case-sensitive language: and is a reserved word, but "And" and "AND" are two different, valid names. As a convention, names starting with an underscore followed by uppercase letters (such as _VERSION) are reserved for internal global variables used by Lua."[4]
Data Types
"Lua is a dynamically typed language. This means that values have types but variables don't, so there are no type or variable declarations. Internally, each value has a tag that identifies its type; the tag can be queried at run time with the built-in function type. "[3] Upon seeing this I had to do a double take. The idea of not having variable types seems kind of alien. It feels as though the writability of the language might suffer when it is time to write expressions and not having a way of making sure that floats are not being added to strings seems to be an issue. "Lua provides automatic conversion between string and number values at run time. Any arithmetic operation applied to a string tries to convert this string to a number, following the usual conversion rules. Conversely, whenever a number is used where a string is expected, the number is converted to a string, in a reasonable format."[4] " Lua provides the types nil, string, number, user data, function, and table. nil is the type of the value nil; its main property is that it is different from any other value."[2] Nil is a great asset to Lua since it was originally developed as a data entry language using nil for variables that have not been assigned an actual value. With the release of Lua 5.0 two new types were introduced, boolean and thread.[3] The creators of Lua were reluctant to add boolean values because the language already supported it through the nil values being false and any other value being true for the purpose of keeping the language as small as possible; however there were occasions where table values needed an explicit false and since nil is more of an initial value it led to errors.[3] Expressions and Assignment Statements
Expressions in Lua are pretty conventional, they resemble statements in Pascal and C and include assignments, control structures, function calls, and variable declarations.[4] The mathematical operators are also standard and include binary + (addition), - (subtraction), * (multiplication), / (division), % (modulo), ^ (exponentiation) and unary - (negation).[4] The relational operators are also pretty standard but are implemented slightly differently since unlike many languages the variables do not have types the language must first compare the operand types before any values can be compared.[4] The relational operators in Lua are
== ~= < > <= >=.[4] The conversion rules used with different types do not come into effect with relational operators so when two operands of different types are compared it will always equate to false, therefore the relational expression 5>"4" will be false even though the value 5 is obviously more than 4 based on the fact that one is of type number and the other is of type string.[4] " Lua supports multiple assignment; for example, x, y = y, x swaps the values of x and y. Likewise, functions can return multiple values."[2]
Statement-Level Control Structures
Lua supports all conventional control structures including If, elseif, For, While, and Repeat.[4] There are two types of for loops supported by Lua. The first type of for loop is the standard numeric for loop that starts at some initial value and increments until a target value is reached. The other type is known as a generic for loop and it increments over functions called iterators and will run the iterator function that will produce a new value on each iteration until the value produced by the function is nil.[4] [see apendix b for an example of these for loops] "To avoid dangling elses, control structures like ifs and whiles finish with an explicit end. Comments follow the Ada convention, starting with "--" and run until the end of the line." [2] Subprograms
Lua supports subprograms only in the form of functions. These functions may be native to Lua or C. "Being an extension language, Lua has no notion of a "main" program: it only works embedded in a host client, called the embedding program or simply the host. This host program can invoke functions to execute a piece of Lua code, can write and read Lua variables, and can register Cfunctions to be called by Lua code."[4]
Abstract Data Types and Encapsulation Constructs
"The type userdata is provided to allow arbitrary Cdata to be stored in Lua variables. This type corresponds to a block of raw memory and has no pre-defined operations in Lua, except assignment and identity test. However, by using metatables, the programmer can define operations for userdata values (see §2.8). Userdata values cannot be created or modified in Lua, only through the CAPI. This guarantees the integrity of data owned by the host program."[4] The ability of Lua to read and manipulate data in C is one of the most important features in defining it as an extensible language. Oddly enough, the Userdata type has not undergone any changes since the first implementation of Lua.[3]
Support for Object-Oriented Programming
Originally Lua was not meant to be an Object Oriented language but its ability to become one developed over time as more features were added to accommodate its growing user base and the addition of a fallback meta-mechanism allowing several new kinds of inheritance between different objects.[1] "Because functions are first-class values, table fields can refer to functions. This is a step toward object-oriented programming, and one made easier by simpler syntax for defining and calling methods."[2] Objects in Lua are defined as a table, userdata, a thread, or a function, and as such they may all call on one another lending to the over object oriented nature of the Language[4]
Concurrency
At its creation Lua had no true built in form of concurrency as it had no concept of threads. A thesis by Eleftherios Chatzimparmpas about how to achieve concurrency in Lua and other interpreted scripting languages shed some light on to how to force concurrency when necessary, and is included in the bibliography for extra reading.[5] This is no longer true as of the release of Lua 5.0 and the addition of the thread data type.[2] The concurrency provided by the thread data type is still not a "true" concurrency in the sense as it does not make use of multiple processors working on different instructions. The form of concurrency supported is a co routine that represents its own thread of execution. These co routines are also called collaborative multithreading.[4] " Unlike threads in multithread systems, however, a coroutine only suspends its execution by explicitly calling a yield function."[4]
Exception Handling and Event Handling
Because Lua is an embedded extension language, all Lua actions start from Ccode in the host program calling a function from the Lua library. Whenever an error occurs during Lua compilation or execution, control returns to C, which can take appropriate measures (such as printing an error message).[4] One of the issues with this is that when the error is thrown and the control is returned back to the host language that language may react in unfavorable ways such as aborting. Lua's defense against this is through it's use of fallbacks. "Fallbacks are used for handling situations that are not strictly error conditions, such as accessing an absent field in a table and signaling garbage collection. Lua provides default fallback handlers, but you can set your own handlers by calling the built-in function setfallback with two arguments: a string identifying the fallback condition (see Table 1), and the function to be called whenever the condition occurs. setfallback returns the old fallback function, so you can chain fallback handlers if necessary."[2] In this sense the fallbacks work much like try catch blocks in C.
Other Issues of Lua
Lua can lead to memory issues as the programmer has no direct control over releasing memory back to the system due to Lua’s garbage collection system. It allows for less time being spent trying to manage memory but problems still arise from poorly constructed data structures or code that simply generates too much garbage to clean up with the built in garbage collection.[6]
Evaluation
Readability – Reading code written in Lua is not terribly difficult, or so I have found. I think the biggest issue is the horrid use of the <type>.<function> lines used repeatedly. One thing improving readability is the color coding of commands. Reserved words show up in dark blue, types and their functions show up in pink and constant string text shows up in a light blue.
Writability – Because Lua is based on C its writability is quite good. It is designed to be used in conjunction with C++ and its syntax is very similar to lessen the learning curve as much as possible. The garbage collection functionality provided by Lua also helps quite a bit by removing altogether the effort required to manually manage memory.
Reliability – The common consensus that I can find is that Lua is not very good as a standalone language. It is missing data types and other common functions that most programmers are used to using as well as having no true support for pointers. My response to this is that Lua was never designed to be a standalone language and doing so is like using a wrench for a hammer, you can do it but don’t be surprised when the result is ugly…
D. Cost – Lua is free and open source, Lua’s only cost is the time spent learning the language, which in theory should not be too long or difficult as it is based on C so most programmers should already have some form of basic knowledge. “Lua is free software: it may be used for any purpose, including commercial purposes, at absolutely no cost. No paperwork, no royalties, no GNU-like "copyleft" restrictions, either.”[7]
Bibliography and References
[1]http://www.lua.org/history.html (Reprint from Proceedings of V Brazilian Symposium on Programming Languages (2001))
[2] http://www.lua.org/ddj.html (Reprint from Dr. Dobb's Journal 21 #12 (Dec 1996) 26–33. Copyright © 1996 Miller Freeman, Inc.)
[3] http://www.lua.org/doc/hopl.pdf (The Evolution of Lua, by Roberto Ierusalimschy, Luiz Henrique de Figueiredo, Waldemar Celes)
[4] http://www.lua.org/manual/5.1/manual.html (Lua 5.1 Reference Manual by R. Ierusalimschy, L. H. de Figueiredo, W. Celes Lua.org, August 2006 ISBN 85-903798-3-3)
[5]http://web.it.kth.se/~johanmon/theses/eleftherios.pdf
[6]http://bitsquid.blogspot.com/2011/08/fixing-memory-issues-in-lua.html
[7] http://www.lua.org/license.html
All appendices are directly taken from the Lua version 5.1 manual located at lua.org and is freely available under the terms of the Lua license.
Appendix "a" List of reserved words in Lua
and break do else elseif
end false for function if
in local nil not or
repeat return then true until while
Appendix "b" For Loops
A numeric for loop like
for v = e1, e2, e3 do block end