The Evolution of Lua
|
|
|
- Dominick Gordon
- 5 years ago
- Views:
From this document you will learn the answers to the following questions:
Who was the author of the paper about Lua?
What has the influence of Scheme on Lua had on the evolution of Lua?
What is the definition of an extensible language?
Transcription
1 The Evolution of Lua Roberto Ierusalimschy Luiz Henrique de Figueiredo Waldemar Celes CONTENTS 1 Introduction Overview of Lua Pre-history The birth of Lua History Feature evolution Lua in retrospect Submitted to HOPL III. Updated on November 30, 2005 at 2:33pm. Department of Computer Science, PUC-Rio, Rio de Janeiro, Brazil. ([email protected]) IMPA Instituto de Matemática Pura e Aplicada, Rio de Janeiro, Brazil. ([email protected]) Department of Computer Science, PUC-Rio, Rio de Janeiro, Brazil. ([email protected]) 1
2 1 Introduction Lua is a scripting language born in 1993 at PUC-Rio, the Pontifical Catholic University of Rio de Janeiro in Brazil. Since then, Lua has evolved to become one of the leading scripting languages in the world. Lua is widely used for game development 1 and in many other industrial applications, such as robotics, literate programming, distributed business applications, image processing, extensible text editors, Ethernet switches, bioinformatics, finite-element packages, and more [2]. Lua has gone far beyond our most optimistic expectations. Lua is the only language developed outside the industrialized world to have achieved global relevance. From the start, Lua was designed to be simple, small, portable, fast, and easily embedded into applications. Those design principles are still in force, and we believe they account for Lua s success in industry. Probably the most important of those principles is simplicity, and perhaps the main expression of simplicity in Lua is that it has a single data structure: tables, which is how Lua implements associative arrays [8]. Although most scripting languages offer associative arrays, no other language offers them with the same expressiveness as Lua. Lua tables provide simple and efficient implementations for modules, prototype-based objects, class-based objects, records, arrays, sets, bags, lists, etc. In this paper, we report on the birth and evolution of Lua. We discuss how the language moved from its simple origins to a powerful (but still simple) language that now supports extensible semantics, anonymous functions, full lexical closures, proper tail recursion, and coroutines. Section 2 contains an overview of the main concepts in Lua, which we use in the other sections for discussing how Lua evolved. In Section 3 we relate the pre-history of Lua, that is, the setting that led to its creation. In Section 4 we relate how Lua was born, what its original design goals were, and what features its first version had. A summary of how Lua evolved is given in Section 5. A detailed discussion of the evolution of selected features is given in Section 6. The paper ends in Section 7 with a retrospective look at the evolution of Lua. 2 Overview of Lua In this section we give a brief overview of the Lua language and introduce the concepts that we shall discuss in Sections 5 and 6. For a complete definition of Lua, see its reference manual [22]. For a detailed introduction to Lua, see [19]. Syntactically, Lua is reminiscent of Modula, with familiar keywords. Figure 1 shows two implementations for the factorial function in Lua. We believe anyone with a basic knowledge of programming can understand those examples without explanation. Semantically, Lua has strong similarities with Scheme. Lua has even been described as Scheme with Tables. The influence of Scheme on Lua has increased during the evolution of Lua: Scheme started just as a language in the background, but later it became increasingly important as a source of inspiration, specially after the introduction of anonymous functions and full lexical closures. 1 An informal poll [5] conducted in September 2003 by gamedev.net (an important site for game programmers) showed Lua as the most popular scripting language for game development. There is a whole book on game development with Lua [30] and several other books on game development devote chapters to Lua [16, 17, 29, 31]. 2
3 function factorial (n) function factorial (n) if n == 0 then local a = 1 return 1 for i = 1,n do else a = a*i return n*factorial(n-1) end end return a end end Figure 1: Two implementations of the factorial function in Lua. On occasion, during the development of new features in Lua, we have looked at the semantics of Scheme for guidance. Because Lua and Scheme are syntactically very different, the semantic similarities between them are not immediately clear. Surprisingly, however, if we take Section 1.1 ( Overview of Scheme Semantics ) from the Revised 5 Report on the Algorithmic Language Scheme [24] and change Scheme to Lua, the only inaccuracies are the following: Lua does have special iteration constructs (although Lua is also properly tail-recursive); Lua does not have first-class full continuations (although it does have first-class one-shot continuations in the form of coroutines [15]); and the representation of numbers in Lua is restricted to the double floating-point format (so Lua also avoids the distinction between integer and real arithmetic). Like Scheme, Lua is dynamically typed: Variables do not have types; only values have types. As in Scheme, variables in Lua never contain structured values, only references to them. As in Scheme, function names have no special status in Lua; they are regular variables that happen to refer to a function value. Actually, the syntax for function definition function f() body end (used above to define factorial) is just syntactic sugar for the assignment of an anonymous function to a variable: f = function () body end. Like Scheme, Lua has first-class functions with lexical scoping and performs proper tail calls. The main semantic difference between Lua and Scheme and probably the main distinguishing feature of Lua is that Lua offers tables as its sole data-structuring mechanism. Lua tables are associative arrays [8], but with some important features. Like all other Lua values, tables are first-class values in Lua: a table is not bound to a specific variable name, unlike Awk and Perl. Lua tables can have any Lua value as key and can store any Lua value. Tables allow simple and efficient implementation of records (using field names as keys), sets (using the set elements as keys), generic linked structures, etc. Moreover, we can implement arrays by using natural numbers as indices. A careful implementation [23] ensures that those tables use the same amount of memory that an array would use (because they are represented internally as actual arrays) and perform better than arrays in similar languages (as independent benchmarks show [1]). Lua also offers an expressive syntax for creating tables, in the form of constructors. The simplest constructor is the expression {}, which creates a new empty table. There are also constructors to create lists (or arrays), such as {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"} 3
4 and also to create records, such as { x = 10, y = 20 } Constructors turn Lua into a procedural data-description language. For instance, the following description is a valid Lua program, even though it looks like a data file in a format similar to the one used in BibTEX databases [25]: article{ authors = {"Roberto Ierusalimschy", "Luiz Henrique de Figueiredo", "Waldemar Celes"}, title = "Lua: an Extensible Extension Language", journal= "Software: Practice & Experience", year= 1996, } The syntax article{...} is syntactic sugar for article({...}), that is, a function call with the result of a constructor as its single argument. It is not uncommon to have Lua data files comprised of a single constructor spanning thousands of lines. Other distinguishing features of Lua come from its implementation: Portability: Lua is implemented in ANSI C. It compiles out-of-the-box in most platforms (Linux, Unix, Windows, Windows CE, Mac OS X, etc.), and runs with small adjustments in virtually all platforms we know, including mobile devices, such as handheld computers and cell phones, and embedded microprocessors like ARM and Rabbit. Easiness of embedding: Lua has been designed from scratch to be easily embedded into applications. A main part of Lua is a well-defined API that allows full communication between Lua code and external code. It is very easy to interface Lua not only with C/C++, but also with other languages, such as Fortran, Java, Smalltalk, Ada, and even with other scripting languages: there are Lua interfaces for both Perl and Ruby. Small size: The whole Lua distribution, including source code, documentation, and binaries for some platforms, fits comfortably in a floppy disk. Efficiency: Independent benchmarks show Lua as one of the fastest languages in the realm of interpreted scripting languages. Although those features come from a specific implementation, they are possible only due to the design of Lua [23]. In particular, Lua s simplicity is a key factor in allowing a small and efficient implementation. 4
5 3 Pre-history Lua was born in 1993 inside Tecgraf, the Computer Graphics Technology Group of PUC-Rio in Brazil. The creators of Lua were Roberto Ierusalimschy (then an assistant professor of the Department of Computer Science of PUC-Rio), Luiz Henrique de Figueiredo (then a post-doctoral fellow at IMPA and later at Tecgraf), and Waldemar Celes (then a Ph.D. student at PUC-Rio). All three were members of Tecgraf, working on different projects there before getting together to work on Lua. Roberto was a computer scientist whose main interest was already in programming languages. Luiz Henrique was a mathematician interested in software tools and computer graphics. Waldemar was an engineer interested in applications of computer graphics. Tecgraf is a large research-and-development laboratory with several industrial partners. During the first ten years since its creation in May 1987, Tecgraf focused mainly on producing basic software tools to enable it to produce the interactive graphical programs its clients needed. Accordingly, the first Tecgraf products were drivers for graphical terminals, plotters, and printers; graphical libraries; and graphical interface toolkits. From 1977 until 1992, Brazil had an official market reserve policy for computer hardware and software. There was a general feeling that Brazil could and should produce its own hardware and software. In that atmosphere, access to existing software and to high-end hardware was very difficult in Brazil. Tecgraf s clients could not afford, either politically or financially, to buy customized software from abroad: they would have to go through a complicated process of proving that their needs could not be met by the Brazilian industry. Added to the natural geographical isolation of Brazil from other research centers, those reasons led Tecgraf to implement from scratch the basic tools it needed. One of Tecgraf s largest partners was (and still is) Petrobras, the Brazilian oil company. Several Tecgraf products were (and still are) interactive graphical programs for engineering applications at Petrobras. By 1993, Tecgraf had developed little languages for two of those applications: a data-entry application and a configurable report generator for lithology profiles. These languages, called DEL and Sol, were the ancestors of Lua. We describe them briefly here to show where Lua came from. 3.1 DEL The engineers at Petrobras needed to prepare input data files for numerical simulators several times a day. This process was boring and error-prone because the simulation programs were legacy code that needed strictly formatted input files typically bare columns of numbers, with no indication of what each number meant, a format that came from the days of punched cards. Of course, each number in the file had a precise meaning, which the engineers could readily grasp just by glancing at a diagram of the particular simulation. In early 1992, Petrobras asked Tecgraf to create at least a dozen graphical front-ends for this kind of data entry. The numbers would be input interactively, just by clicking on the relevant parts of the diagram a much easier and more meaningful task for the engineers than editing columns of numbers. The data file, in the correct format for the simulator, would be created automatically. Moreover, such front-ends opened the opportunity to add data validation and also to compute derived quantities from the input data, thus reducing the amount of data needed from the user and 5
6 increasing the reliability of the whole process. To simplify the development of those front-ends, a team led by Luiz Henrique de Figueiredo and Luiz Cristovão Gomes Coelho decided to code them in a uniform way, and so designed DEL ( data-entry language ), a simple declarative language to describe each data-entry task [14]. Figure 2 shows a section of a typical DEL program. The statement :e defines an entity, which can have several fields. In the example, the entity is called gasket and has four fields: mat is a string, m and y are real numbers (floats), and t is an integer. All fields except mat are given default values. The statement :p defines predicates that impose restrictions on the values of entities, and so implements data validation. DEL had several other statements, including statements to specify how data was to be input and output. :e gasket "gasket properties" mat s # material m f 0 # factor m y f 0 # settlement stress t i 1 # facing type :p gasket.m>30 gasket.m<3000 gasket.y>335.8 gasket.y< Figure 2: A section of a DEL program. An entity in DEL is essentially a structure or record in conventional programming languages. The important difference and what made DEL suitable for the data-entry problem is that entity names also appeared in a separate graphical metafile, which contained the associated diagram over which the engineer did the data entry, as described above. A single interactive graphical interpreter called ED ( entrada de dados, which means data entry in Portuguese) was written to interpret DEL programs. All data-entry front-ends were then DEL programs that ran under this single graphical application. DEL was what is now called a domain-specific language, but was then simply called a little language [9]. DEL proved to be a success, both among the developers at Tecgraf and among the users at Petrobras. At Tecgraf, DEL simplified the development of those front-ends. At Petrobras, DEL made it easy for users to tailor data-entry applications. Soon users began to demand more power from DEL, such as boolean expressions for controlling whether an entity was active for input or not, and DEL became heavier. When users began to ask for flow control, with conditionals and loops, it was clear that ED needed a real programming language instead of DEL. 6
7 3.2 Sol At about the same time that DEL was created, a team lead by Roberto Ierusalimschy started working on PGM, a configurable report generator for lithology profiles, also for Petrobras. The reports generated by PGM are highly configurable: the user can create and position the tracks; can choose colors, fonts, and labels; each track may have a grid, which also has its set of options (log/linear, vertical and horizontal ticks, etc.); each curve has its own scale, which has to be changed automatically in case of overflow; and so on. All this configuration was to be done by the end-users, typically geologists or engineers at Petrobras, and the configuration had to be stored in files, for reuse. The team decided that the best way to configure PGM was through a specialized description language, which they called Sol (an acronym for Simple Object Language). Sol also means sun in Portuguese. Because the report generator had to deal with many different objects, each one with many different attributes, the Sol team decided not to fix those objects and attributes into the language. Instead, Sol allowed type declarations. The main task of the Sol interpreter was to read a report description, check whether the given objects and attributes were correctly typed, and then present the information to the main program (PGM). To allow this communication between the main program and the Sol interpreter, the latter was implemented as a C library, which was linked to the main program. The main program could access all configuration information through an API in this library. Moreover, the main program could register a callback function for each type, which the interpreter would call whenever it created an object of that type. Figure 3 shows a typical piece of code in Sol. The syntax of Sol was strongly influenced by BibTEX [25] and UIL, a language for describing user interfaces in Motif [27]. -- defines a type track, with numeric attributes x and y, -- plus an untyped attribute z. y and z have default values. { x:number,y:number= 23, z=0} -- defines a type line, with attributes t (a track) and z (a list -- of numbers). t has as default value a track with x=8, y=23, and z=0. { t:@track=@track{x=8},z:number*} -- creates an object t1, of type track t1 { y = 9, x = 10, z="hi!"} -- creates a line l, with t=@track{x=9, y=10} and z=[2,3,4] (a list) l { y=t1.x}, z=[2,3,4] } Figure 3: A Sol program. 7
8 4 The birth of Lua The Sol team finished an initial implementation of Sol in March 1993, but they never delivered it. Around mid-1993, Roberto, Luiz Henrique, and Waldemar got together and realized that both DEL and Sol could be replaced by a single, more powerful language. Thus the Lua team was born and has not changed since. As mentioned before, ED users had requested more power from DEL. ED also needed descriptive facilities for programming its user interface. At the same time, the program for visualizing lithology profiles (PGM) would soon require support for procedural programming to allow the creation of more sophisticated layouts. So, we decided that we needed a real programming language, with assignments, control structures, sub-routines, etc. The language should also offer data-description facilities, such as those offered by Sol. Moreover, because many potential users of the language were not professional programmers, the language should avoid cryptic syntax and semantics. Finally, the implementation of the new language should be highly portable, because Tecgraf s clients had a very diverse collection of computer platforms. Since we expected that other Tecgraf products would also need to embed a scripting language, the new language should be provided as a library with a C API, like Sol. At that point, we could have adopted an existing scripting language, instead of creating a new one. In 1993, the only real contender was Tcl [28], which had been designed to be embedded into applications. However, Tcl had unfamiliar syntax, did not offer good support for data description, and ran only on Unix platforms. We did not know any embeddable implementations of LISP or Scheme, and we did not know about Python (which was still in its infancy). In the do-ityourself atmosphere that then reigned in Tecgraf, it was natural that we should try to develop our own scripting language. So, we started working on a new language, which we hoped would be even simpler to use than those languages. Our original design decisions were: keep the language simple and small, and keep the implementation simple and portable. Because the new language was a modified version of Sol (sun, in Portuguese), a friend at Tecgraf (Carlos Henrique Levy) suggested the name Lua (moon, in Portuguese), and Lua was born. DEL did not influence Lua as a language: The main influence of DEL on the birth of Lua was rather the realization that we needed embeddable scripting languages. Lua inherited from Sol the syntax for record and list constructions, but unified their implementation using tables: Records use strings (the field names) as indices; lists use natural numbers. Apart from those data-description facilities, Lua had no new concepts; we just wanted a light full language. So we borrowed (even unconsciously) things that we had seen or read about in other languages. We did not reread old papers to remember details on existing languages. We just started from what we knew about other languages and reshaped that according to our tastes and needs. Thus, although Lua was created inside an academic laboratory, Lua was not created as an academic language. We quickly settled on a small set of control structures, with syntax mostly borrowed from Modula (while, if, and repeat until). From CLU we took multiple assignment and multiple returns from function calls, because we wanted to avoid pointers and references. We saw multiple returns as a simpler alternative to in-out parameters used in Pascal, Ada and Modula, and to reference parameters, used in C and C++. From C++ we took the neat idea of allowing a local variable to 8
9 be declared only where we need it. From Awk we took associative arrays, which we called tables. However, tables are objects in Lua, not attached to variables as in Awk. As in VDM, tables in Lua can be indexed by any type of value. For our purposes, the language did not need type declarations. Instead, we could use the language itself to write type-checking routines, provided that we offered basic reflexive facilities (such as run-time type information). An assignment like t1 {y = 9, x = 10, z="hi!"} which was valid in Sol, would be also valid in Lua, but with a different meaning: It created an object (that is, a table) with the given fields, and then called the function track to validate the object or perhaps to provide default values to some fields. The value of the expression in the right was that table. One of the few (and rather minor) innovations in Lua was the syntax for string concatenation. The natural + operator would be ambiguous, because Lua performed automatic coercion of strings to numbers. So, we invented the syntax.. (two dots) for string concatenation. A polemic point was the use of semicolons. We thought that requiring semicolons could be a little confusing for engineers with a Fortran background, but not allowing them could confuse those with a C or Pascal background. In a typical committee fashion, we settled on optional semicolons. Initially, Lua had seven types: numbers (implemented solely as floats), strings, tables, nil, userdata (pointers to represent C structures inside Lua), Lua functions, and C functions. To keep the language small, we did not initially include a boolean type. As in Lisp, nil represented false, and any other value represented true. Over 12 years of continuous evolution, the only changes in Lua types were the unification of Lua functions and C functions into a single function type in Lua 3.0 and the introduction of booleans and threads in Lua 5.0. Waldemar did the first implementation of Lua as a course project supervised by Roberto. That first version of Lua already featured powerful data-description constructs, simple syntax, and a bytecode virtual machine. The implementation followed a tenet that is now central to Extreme Programming: the simplest thing that could possibly work [6]. The lexical scanner was written with lex and the parser with yacc. The parser translated Lua programs to a bytecode form, which was then executed by a simple stack-based interpreter. The C API made it easy to add new functions to Lua, and so this first version provided only a very small library of built-in functions. Despite this simple implementation or possibly because of it Lua surpassed our expectations. Both PGM and ED used Lua successfully (PGM is still in use today; ED was replaced by EDG [10], which was mostly written in Lua). Lua was an immediate success in Tecgraf; this was reported in a brief talk at the VII Brazilian Symposium on Software Engineering, in October 1993 [20]. 5 History Figure 4 shows a timeline of the releases of Lua and summarizes the chronological history of Lua. The long times between versions since Lua 3.0 reflect our perception that Lua was becoming a mature product and needed stability, due to the growth of the Lua community. Nevertheless, the 9
10 Figure 4: Timeline of Lua releases. need for stability has not hindered progress. Major new versions of Lua, such as Lua 4.0 and Lua 5.0, have been released since then. The long times between releases also reflects our release model. Unlike other projects, our alpha versions are quite stable and beta versions are essentially final, except for uncovered bugs. (The number of bugs in final versions has been consistently small: only around 10 in both Lua 4.0 and Lua 5.0, and all of them just minor bugs.) This release model has proved to be good for Lua stability. Several products have been shipped with alpha or beta versions of Lua and worked fine. However, this release model does not give users much chance for experimentation with the new version and deprives us from useful feedback on proposed changes. So, during the development of Lua 5.0 we started to release work versions, which are just snapshots of the current development of Lua. These work versions give us a chance to field-test new features and give users a chance to see the direction the Lua is heading much earlier than an alpha version. (This brings our current release model closer to the Release Early, Release Often motto of the open-source community.) For instance, the first work version of Lua 5.1 was released in March 2004; the last work version of Lua 5.1 was released in May 2005; Lua 5.1-alpha was released in September 2005, Lua 5.1-beta was released in November 2005, with Lua 5.1-final scheduled for December In the remainder of this section we discuss some milestones in the evolution of Lua. Details on the evolution of several specific features are given in Section 6. Lua 1.1 The initial implementation of Lua was a success in Tecgraf and Lua got real users from other projects. New users create new demands. Not surprisingly, one of the first demands was for better performance. We wanted to use Lua as the support language for large graphics metafiles, which abounded in Tecgraf. Compared with other programmable metafiles, Lua metafiles have the advantage of being based on a truly procedural language. The VRML format, for instance, uses Javascript to model procedural objects, resulting in a heterogeneous code [7]. With Lua, it is natural to incorporate procedural objects in a scene description. Procedural code fragments can be combined with declarative statements to model complex objects. The use of Lua for this kind of data description posed challenges that were unusual for typical scripting languages. The data-entry program ED was the first one to use Lua for its graphics metafiles. It was not uncommon for a diagram to have several thousand parts, which were described with a Lua table constructor with several thousand items. That meant that Lua had to cope with huge programs and huge expressions. Because Lua pre-compiled all programs to bytecode on the fly, it also meant that the Lua compiler had to run very fast. So, we replaced the lex-generated scanner by a handwritten one and almost doubled the speed of the Lua compiler. Since then, we have always tried to reduce the time spent on pre-compilation. We also modified Lua s virtual machine to handle long 10
11 constructors. We released a new version of Lua, with those optimizations, in July 1994, with the name Lua 1.1. The previous version, which was never publicly released, then got the name Lua 1.0. Around that time, we also published the first paper describing Lua [12]. Lua 1.1 was publicly released as software available in source code by ftp, even before the opensource movement got its current momentum. Lua 1.1 had a restrictive user license: it was freely available for academic purposes, but commercial uses had to be negotiated. That license did not work: although we had a few initial contacts, no commercial uses were ever negotiated. Moreover, other competing scripting languages, such as Tcl, were free. Restrictions on commercial uses may discourage even academic uses, since several academic projects plan to eventually go to the market. So, when the time came to release the next version of the language (Lua 2.1), we chose to release it as unrestricted free software. However, we did make the mistake of trying to write our own license text, as a slight collage and rewording of existing licenses. This was a source of noise among users and their lawyers. Finally, in Lua 5.0, we adopted the well-known and very liberal MIT license [3]. Legal concerns about using Lua have practically vanished since then. Lua 2.1 Lua 2.1 was released in February 1995 and introduced extensible semantics and support for objectoriented programming. Extensible semantics was provided by fallbacks: user-setable hooks called when Lua did not know how to proceed. (See Section 6.7 for a fuller discussion of fallbacks and their later incarnations.) Object-oriented programming was supported by the following changes: adding syntactic sugar for calling methods : a:f() became sugar for a.f(a) ; 2 adding a virtual machine instruction to handle method calls; and using the index fallback to implement inheritance. Lua 2.1 also simplified the syntax and semantics of table constructors, unifying the use of curly brackets for both records and lists and introducing another instance of syntactic sugar in Lua: f{...} became sugar for f({...}). (See Section 6.2 for how tables evolved.) These changes were a big incompatibility with Lua 1.1 (hence the change in the major version number). Since at that time all Lua users were probably from Tecgraf, these incompatibilities were not fatal and existing programs were easily converted with the aid of some tools that we wrote for this task. Lua 2.1 also introduced a debug API for introspection. Instead of providing a debugger, we chose to provide the means for users to write own introspective tools. Lua 2.1 is the version described in a paper published in June 1996 in Software: Practice & Experience [21]. (By that time, the current version was Lua 2.4.) External attention to Lua began with the publication of that paper, at least within academic circles. Lua 2.4 In May 1996 we released Lua 2.4. A main feature of this new version was an external compiler, called luac. This program pre-compiles Lua code and saves bytecode and string tables to a binary 2 a.f() was already the syntax for calling a function stored in a table field. 11
12 file. The format of this file was chosen to be easily loaded and reasonably portable. With luac, programs can avoid parsing and code generation at run-time, which in the early days were costly for large, static programs such as graphical metafiles. Our first paper about Lua [12] already anticipated the possibility of an external compiler, but we only needed it after Lua became widely used at Tecgraf and large graphical metafiles were written in Lua, as the output of graphical editors. Besides faster loading, luac also allows off-line syntax checking and the protection of source code from user changes. However, pre-compiling does not imply faster execution because Lua chunks 3 are always compiled into bytecodes before being executed luac simply allows those bytecodes to be saved in a file for later execution. During the implementation of luac, we re-structured Lua s core into clearly separated modules. In particular, it is now easy to remove the parsing modules (lexer, parser, and code generator), which represent 35% of the core code in Lua 5.0, leaving just the tiny module that loads precompiled chunks. This can be useful for tiny implementations of Lua to be embedded in small devices such as mobile devices or robots. 4 Lua 2.4 brought an improved debug API, with hooks for user-defined functions to be called at line changes and function calls. Lua 2.4 also introduced pattern matching in the string library. Lua 2.5 In December 1996, the magazine Dr. Dobb s Journal featured an article about Lua [13]. (By that time, the current version was Lua 2.5.) That was a popular publication aimed directly at programmers and that article started to make Lua internationally known outside academic circles. Soon after that publication, we received several messages praising Lua. In January 1997, we received a message from Bret Mogilefsky, the lead programmer of Grim Fandango, a hit adventure game released by LucasArts in October Bret told us that he had read about Lua in Dr. Dobb s and that they planned to replace their home-brewed scripting language with Lua. They went on to use Lua and in May 1999 Bret told us that a tremendous amount of the game was written in Lua (his emphasis) [26]. Since then, Lua has been probably used in hundreds of games (game companies tend to be secretive about the technologies they use). Knowledge of Lua is definitely a marketable skill in the game industry. We can only attribute this unexpected spread of Lua among game developers to word-of-mouth recommendation. We never directly targeted the game market (or any other market for that matter). Lua 3.0 Lua 3.0 (released in July 1997) replaced fallbacks with the more powerful concept of tag methods. Fallbacks were global by nature: User functions were called every time an event occurred, and there was only one function for each event. This made it hard to combine Lua modules that had different notions of inheritance, for instance. Although it was possible to chain fallbacks, 3 The unit of execution of Lua is called a chunk. It is simply a sequence of statements. 4 Crazy Ivan, a robot that won RoboCup in 2000 and 2001 in Denmark, had a brain implemented in Lua. 12
13 chaining was slow and error-prone, and in practice nobody did it. In Lua 3.0, the programmer could create tags and attach them to tables and userdata. Tag methods were essentially fallbacks that were selected according to the tag of the operands. With tags and tag methods, different tables and userdata could have different fallbacks for their operations. We regarded the tag concept as important enough to warrant the change of the major version number. The tag concept essentially provided Lua with user-defined types. A tag was simply a number that represented a new type. Basic types had tags as well, but they could not be changed. When programmers attached a tag to a table or userdata, they were actually defining a new type for that object: the corresponding tag methods determined how the object responded to primitive operations and so described the behavior of the new type. Lua 3.0 also brought support for conditional compilation, in the form of a C-like preprocessor. Although it did complicate the lexer, it was easy to add. Soon programmers began to use it and requests for more power came almost at once. One of the most frequent requests was the addition of macro expansion, but no clean proposal emerged from the long discussions in the mailing list and among ourselves. Every proposal made would imply a large change in the lexer and parser, and the benefits were not clear. So, the preprocessor remained static for two years, from Lua 3.0 to Lua 3.2. In Lua 4.0, we decided that the preprocessor was causing more harm than good, making the code bulkier and inviting endless discussions from users, and we removed it. (See Section 6.4 for a fuller discussion.) We feel that Lua is now cleaner without the preprocessor. Over the years, we have striven to make Lua simpler and have removed dark corners of the language that we once regarded as features, but which few programmers really used and which were later recognized as misfeatures. Lua 3.1 Lua 3.1 was released in July 1998 and brought functional programming to Lua by introducing anonymous functions and function closures via upvalues. (Full lexical scoping had to wait until Lua 5.0.) Lua 3.1 also provided support for multiple global contexts, but the C API was not fully reentrant (this had to wait until Lua 4.0). Finally, Lua 3.1 also saw a major code re-organization and clean-up, with much reduced module interdependencies. Lua 3.2 Lua 3.2 was released in July 1999 and brought a debug library. Introspective tools, which could already be written in C since Lua 2.1, could then be written directly in Lua. Lua 3.2 was also an important version because it was the last one to use the original C API. Lua 4.0 completely changed the C API, and not everyone migrated to Lua 4.0. For instance, Tecgraf never migrated to Lua 4.0 and is only now completing a migration of its basic tools to Lua
14 Lua 4.0 The C API was redesigned in Lua 4.0 (released in November 2000) to support multiple states and a clear stack metaphor for exchanging values with C. Until version Lua 3.2, only one Lua state could be active at a time. For simplicity, when we designed the API, we did not include an explicit state parameter in the functions there was a single, global state. By the time Lua 3.2 was out, it was clear that some applications would be simpler if they could run multiple Lua states in a convenient way. For instance, we had to make a special version of Lua 3.2 for CGILua [18], an extension of web browsers for dynamic page serving and CGI programming in Lua. LucasArts had done something similar for Grim Fandango. When we were discussing our plans for Lua 3.3, a modified API with explicit states was our highest priority. However, that raised serious compatibility questions. In the end, because there would have to be several incompatibilities, we decided to rewrite the API completely and the next version became Lua 4.0 instead of Lua 3.3. The API now not only includes explicit states, but it is also easier to use and is more efficient. We feared that the transition to the new API would be a little traumatic, since it was the first time that we really changed the API since Lua 1.1. We did have a few complaints in the mailing list, but on the whole the change was not too bad for those that chose to migrate. Most Lua programmers have no contact with the API, many use it only through automatic tools, and many considered that the benefits justified the transition costs. The new API is now seen as simpler and easier to use. Lua 4.0 also introduced a for statement, an item in the wish-list of most Lua users then. We had not included a for statement earlier because while loops were more general. 5 Also, we could not agree on a good syntax. We considered that the Modula for was too restrictive: it did not contemplate iterations over the elements of a table nor over the lines of a file. A for loop in the C tradition did not fit with the rest of Lua. With the introduction of closures and anonymous functions in Lua 3.1, we decided to use higher-order functions for implementing iterations. (In fact, the need for iterators was one of the main reasons for introducing anonymous functions in Lua.) So, Lua 3.1 provided pre-defined functions for iteration over tables. These were high-order functions that called a user-supplied function over all pairs in a table. In Lua 4.0 we finally designed a for loop, in two variants: a numeric loop and a tabletraversal loop. These two variants covered most common loops; for a really generic loop, there was still the while loop. Instructions were added to the virtual machine to implement for loops efficiently. That was possible because the two variants had a rigid format. The for statement was one of the most successful changes in the language since its first version. Lua 5.0 Lua 5.0 was released in April 2003; it is still the current version. (Lua 5.1 is planned for late 2005.) The main new features in Lua 5.0 are booleans, coroutines, full lexical scoping instead of upvalues (which makes Lua quite apt for functional programming), proper tail calls, weak tables, and a 5 However, users complained that they kept forgetting to add the increment or to update the step at the end of while loops, thus leading to infinite loops. 14
15 register-based virtual machine (such machines are only now being considered in other scripting languages). Starting with Lua 5.0, Lua is distributed under the MIT license [3]. Lua 5.0 organized the standard library functions into proper modules, as fields inside tables. It also included a system-dependent dynamic loading library. These two additions were also meant to encourage the development of libraries by the community. Lua 5.0 is a sophisticated and mature language. This sophistication, which started in Lua 3.0, is still possible within our original design goals of simplicity and portability. 6 Feature evolution In this section, we describe in detail the evolution of some of the features in Lua. Where appropriate, we also include a critique of the current state of affairs. 6.1 Types Types in Lua have been fairly stable. For a long time, Lua had only six basic types: nil, number, string, table, function, and userdata. (Actually, until Lua 3.0, C functions and Lua functions had different types, but they have always been handled transparently at call time.) Lua 5.0 introduced two new types: threads, as a consequence of the introduction of coroutines, and booleans. We resisted for a long time to introduce boolean values: nil was false and anything else was true. This state of affairs was simple and seemed sufficient for our purposes. However, nil was also used for absent fields in tables and for undefined variables. In some applications, it is important to allow table fields to be marked as false but still be seen as present; an explicit false value could be used for this. In Lua 5.0 we finally introduced boolean values true and false. Nil is still treated as false. In retrospect, it would probably have been better if nil had raised an error in boolean expressions. This would be more consistent with its role as the value of undefined values, but would probably break many programs. LISP has similar problems, with the empty list representing both nil and false. Scheme explicitly represents false and treats the empty list as true, but some implementations of Scheme still treat the empty list as false. 6.2 Tables Lua 1.1 had three syntactical constructs to @{}. The simplest form which created an empty table. An optional size could be given at creation time, as an efficiency hint. The was used to create arrays or lists, in which the keys were natural numbers starting at 1 and were implicit, as The was used to create records, as a set of key-value pairs, in which the keys were strings and were explicit, as All three forms created the same kind of table. Tables created with any of those forms could be modified dynamically after creation, regardless of how they had been created. Moreover, it was possible to provide user functions when creating lists and records, as This syntax was inherited from Sol and is the expression of procedural data description, a major feature of Lua. The semantics was that a table was created and then the function 15
16 was called with the table as its single argument. The function was allowed to check and modify the table at will, but its return value was ignored: The table was the value of the expression. In particular, the function was not allowed to wrap the original table inside another table, for instance. In Lua 2.1, the syntax for table creation was unified and simplified: the was removed and the only constructor became {}, which could be optionally prefixed with a function to be called with the table, as in person{name="john",age=35}. Actually, f{...} became sugar for f({...}). As a consequence, the function must explicitly return the table (or whatever value it chose). Dropping from constructors was a trivial change, but it actually changed the feel of the language, not merely its looks. Trivial changes that improve the feel of a language are not to be overlooked. This simplification in the syntax and semantics of table constructors was good but it had a side-effect. In Lua 1.1, the equality operator was =. With the unification of table constructors in Lua 2.1, an expression like {a=3} became ambiguous, because it could mean a table with either a pair ("a", 3) or a pair (1, b), where b is the value of the boolean expression a=3. To solve this ambiguity, Lua 2.1 also changed the equality operator from = to ==. With this change, {a=3} meant a table with the pair ("a", 3), while {a==3} meant a table with the pair (1, b). Finally, Lua 2.1 allowed the two parts to be combined in table constructors: { array ; record }. Note the semicolon to indicate the end of one part and the start of another. Within each part, commas were used, as before. The syntax for table constructors has since remained largely unchanged. Lua 3.1 introduced a minor change and a major change: The minor change was that it became possible to switch the two parts, as in { record ; array }, but they still had to be separated explicitly by a semicolon. The major change was that keys in the record part could be given by any expression, as in {[10*x+f(y)]=47}. In particular, this allowed arbitrary strings as keys, such as strings with spaces and reserved words. Thus, {function=true } is not valid (because function is a reserved word), but {["function"]=true} is valid. Since Lua 5.0, it is now possible to freely intermix the array part and the record part, and there is no need to use semicolons in table constructors. Table constructors are now even easier and more intuitive to use. While the syntax of tables has evolved, the semantics of tables in Lua has not changed at all: Tables are still associative tables, which can store arbitrary pairs of values. However, frequently in practice tables are used solely as arrays (that is, with consecutive integer keys) or solely as records (that is, with string keys). Because tables are the only data-structuring mechanism in Lua, we have invested much effort in implementing them efficiently inside Lua s core. Until Lua 4.0, Lua implemented tables as strict hash tables, with all pairs stored explicitly. Lua 5.0 introduced a new algorithm that detects whether tables are being used as arrays and automatically stores the values associated to numeric indices in an actual array, instead of adding them to the hash table [23]. Thus, tables are now implemented as hybrid data structures: they contain a hash part and an array part. This division is made only at a low implementation level; access to table fields is transparent, even to the virtual machine. Tables automatically and dynamically adapt their two parts according to their contents. This hybrid scheme has two advantages. First, access to values with integer keys is faster because no hashing is needed. Second, and more important, the array part takes roughly half the 16
17 memory it would take if it were stored in the hash part, because the keys are implicit in the array part but explicit in the hash part. As a consequence, if a table is being used as an array, it performs as an array, as long as its integer keys are densely distributed. Moreover, no memory or time penalty is paid for the hash part, because it does not even exist. The converse holds: if the table is being used as a record and not as an array, then the array part is likely to be empty. These memory savings are important because it is common for a Lua program to create many small tables, for instance when tables are used to implement objects. Another reason for investing effort into an efficient implementation of tables is that we can use them for all kinds of tasks, both inside and outside Lua s core. For instance, before Lua 4.0, the global environment, which keeps all global variables, was represented in a special data structure inside the core. Lua 4.0 introduced the table of globals, which is an ordinary Lua table that can be manipulated like any other table, both from C and from Lua. Lua 5.0 introduced environment tables that can be attached to Lua functions; they are the tables where global names in Lua functions are resolved at run time. This scheme will be extended to userdata and C functions in Lua 5.1, simplifying the creation of libraries by allowing all C functions in a library to share a set of values. Another example of the prominent role of tables in Lua was in the move from tags and tag methods to metatables and metamethods in Lua 5.0. (See Section 6.7.) Tag methods had their own private representation inside the Lua core and needed explicit interface functions to manipulate them. Metatables are just ordinary Lua tables and so can be manipulated within Lua without the need for special functions. This move simplified the implementation of Lua and the API for both Lua and C programmers. Finally, in Lua 5.0, the standard library functions, which existed since Lua 1.1, were moved from the global environment to fields inside tables. For instance, sin became math.sin. Lua 5.1 will also bring a complete package and module system based on tables. 6.3 Strings Strings play a major role in scripting languages and so the facilities to create strings are an important part of the usability of such a language. The syntax for literal strings in Lua has had an interesting evolution. Since Lua 1.1, literal strings can be delimited by matching single or double quotes, and can contain C-like escape sequences. (Lua 3.1 introduced numerical escape sequences in decimal.) The use of both single and double quotes to delimit strings is a bit unusual. While these dual quotes allow strings to contain one kind of quote without having to escape it, escape sequences are still needed for arbitrary text. Lua 2.2 introduced long strings, a feature not present in classical programming languages, but present in most scripting languages. Long strings provide a convenient way to include arbitrary text as a string, without having to worry about its contents. In Lua, a long string is a text wrapped inside matching [[ and ]]. Long strings may run for several lines, may contain nested [[ and ]], and do not interpret escape sequences. Unfortunately, the sequence that signals the end of long strings can easily be part of a valid Lua program in an unbalanced way, as in a[b[i]] or in other constructs, such as <[!CDATA[...]]> from XML. So, it was hard to reliably wrap arbitrary text as a string. (Other languages that provide long strings have similar problems.) 17
18 Lua 5.1 will support a new, simpler form for long strings: text delimited by matching [===[ and ]===], where the number of = is arbitrary (including zero) and the string only closes when the right number of = are seen. These new long strings will not nest, but it will be easy to wrap arbitrary text, even if it contains ]===] sequences: simply use an adequate number of =. We feel that the new scheme is much simpler than the current scheme. Nesting delimited text is always a messy subject; the same kind of problems happen in block comments. 6.4 Block comments Comments in Lua are signalled by -- and continue to the end of the line. This is the simplest kind of comment, and is very effective. Several other languages use single-line comments, with different marks. Languages that use -- for comments include Ada and Haskell. We never felt the need for multi-line comments, or block comments, except as a quick way to disable code. There was the question of which syntax to use: the usual /*... */ does not mesh well with the Lua s single-line comments. There was also the question of whether block comments nest or not, always a source of noise for users and of complexity for the lexer. Nested block comments happen when the programmer wants to comment out some block of code, to disable it. Naturally, the programmer expects that comments inside the block of code are handled correctly. Hence the need for handling nested block comments. Note the parallel with long strings (Section 6.3). ANSI C supports block comments but does not allow nesting. C programmers disable code by using the C preprocessor idiom #if 0... #endif. This scheme has the clear advantage that it does not interfere with existing comments or preprocessor code in the disabled code. It is also easy to enable the code again by changing 0 to 1, which is very handy during testing and debugging. With this motivation and inspiration, we addressed the need for disabling blocks of code in Lua not the need for block comments by introducing conditional compilation in Lua 3.0 in the form $if var, $ifnot var, $else, $end. (The pragmas followed the syntax of $debug and $nodebug, which existed since Lua 1.1 for controlling the generation of debug information.) If var was defined when Lua began loading the chunk, then the code between $if var and $else was compiled. Otherwise, the code between $else and $end was compiled. The reverse happened for $ifnot var. These constructions could be nested and they meshed well with comments. As special cases, var could also be nil or 1, in anticipation that full expressions would be allowed in $if, but this never happened. In this scheme, a block of code could be disabled by surrounding it with $if nil... $end. Re-enabling it meant simply changing nil to 1. There was also $endinput, which signalled a fake end of file. But there was no $include because Lua already provided a dofile built-in function which did almost the same thing, from the point of view of the user. Unlike the C preprocessor, which works on C tokens only, Lua s conditional compilation could be used for block comments: the text inside $if nil... $end did not need to be composed of valid Lua text. In particular, text containing English sentences such as Don t do this were skipped correctly. However, we do not think that conditional compilation was ever used for block comments; it was only used for disabling code and naturally for actual conditional compilation, as originally intended. 18
19 Once a feature has been offered in a language, it will find someone who uses it and then requests enhancements. Even people that do not use that feature will request enhancements! Conditional compilation brought many such requests, specially for a full macro processor like the C preprocessor. If we were to add a full macro facility, then we would like it to be programmable in Lua, not in some other specialized language. Moreover, we did not want to add such macro facility directly into the lexer, to avoid bloating it and slowing compilation. So endless discussions ensued in the mailing list and within the Lua team. But there was no consensus and no solution emerged. Also, we could not simply add support for full expressions in $if: they would have to evaluated at compilation time and the Lua parser was not fully reentrant until Lua 5.1. So there was no way to call Lua from within the lexer. Finally, conditional compilation did not mesh well with long strings. It was impossible to create long strings containing Lua code that had pragmas because those pragmas would be evaluated. During the work on Lua 4.0, we decided that the support for conditional compilation was not worth the complexity in the lexer and in its semantics for the user, specially after not having reached any consensus about a full macro facility. So, in Lua 4.0 we removed support for conditional compilation. (A further motivation was that by that time we had found a better way to generate and use debugging information, and $debug and $nodebug pragmas were no longer needed. So, removing conditional compilation allowed us to get rid of all pragmas.) We feel that Lua is much better without conditional compilation. Moreover, since the parser will be fully reentrant in Lua 5.1, the door will be open to user-controlled macro processing. (Already in Lua 5.0, with the introduction of callback functions for loading chunks, it became possible for users to implement conditional compilation themselves.) Block comments were only introduced in Lua 5.0, in the form --[[... ]]. Because they intentionally mimic the syntax of long strings, block comments were really a simple addition to the lexer. This similarity also helps users to grasp both concepts and their syntax. Block comments are easy to use for disabling Lua code: The idiom is to surround the code between two lines containing --[[ and --]]. The code inside those lines can be re-enabled by simply adding a single - at the start of the first line. Both lines then become harmless single-line comments. Like long strings, block comments did nest, but they had the same problems as long strings (block comments and long strings are recognized by essentially the same code in the lexer.) In particular, valid Lua chunks that contained unbalanced ]] s, such as a[b[i]], could not be reliably commented out in Lua. The new scheme for long strings in Lua 5.1 will also apply to block comments, in the form of matching --[===[ and ]===], and so will provide a robust solution for this problem. 6.5 Functions Functions in Lua have always been first-class values: they can be assigned to any kind of variable, can be stored in tables (both as keys and values), can be passed as arguments to functions, and can be returned from functions. Functions can also be created at run time by compiling and executing 19
20 a string containing a function definition. 6 However, it was only in Lua 3.1, with the introduction of anonymous functions, that programmers were able to create functions at run time without resorting to compilation from text. The introduction of anonymous functions naturally also brought closures and the need to access outer local variables, not only global variables. Lua 3.1 introduced the notion of upvalue as the frozen value of an outer variable. This restriction was removed in Lua 5.0 with the introduction of full lexical scoping. Function closures can now change the value of their outer variables at will. This is very natural and meets programmer expectations, even if they do not think about it. We did not provide full lexical scoping earlier because we did not know a simple implementation. Chunks in Lua are like main programs in other languages. Before Lua 5.0, Lua started the execution of chunks by doing some internal magic. Chunks were not explicitly called, despite having exactly the same kind of bytecode as ordinary Lua functions. Chunks began to look like ordinary functions in Lua 2.2 when locals outside functions were allowed as an undocumented feature (which only became official in Lua 3.1). In Lua 2.5 chunks were allowed to return values. Lua 3.0 allowed function nesting and chunks became functions internally, except that they were executed right after being compiled; they did not exist as functions at the user level. This final step had to wait until Lua 5.0, which broke the loading and execution of chunks into two steps. In Lua 5.0 chunks became just ordinary anonymous functions. In Lua 5.1 chunks will become anonymous vararg functions and thus can be passed values at execution time. Those values are accessed via the new in... mechanism (see below). This evolution of the status of functions is also related to the fact that function definitions were special until Lua 2.2, when they became ordinary assignments. Before that, these assignments occurred magically before the chunk started executing. This is a subtle difference between the semantics of Lua 2.1 and that of Lua 2.2. Nevertheless, it did not create many incompatibility problems in practice. From a different point of view, chunks are like modules in other languages: they usually provide functions and variables to the global environment. Originally, we did not intend Lua to be used for large-scale programming and so we did not feel the need to add an explicit notion of modules to Lua. Moreover, we have always felt that tables would be sufficient for building modules, if needed. In Lua 5.0 we made that explicit by packaging all standard libraries into tables. This encourages other people to do the same and makes it easier to share libraries. We now feel that Lua may be used for large-scale programming and so, as further encouragement, Lua 5.1 will also bring a package system and a module system based on tables. Functions in Lua, whether written in C or in Lua, are not declared and so at call time they behave as accepting a variable number of arguments: excess arguments are discarded and missing arguments are given the value nil. (This is exactly the semantics for handling multiple assignment as well.) C functions have always been able to handle a variable number of arguments, but not Lua functions until Lua Some people maintain that the ability to evaluate code from text at run time and within the environment of the running program is what characterizes scripting languages. 20
21 Lua 2.5 introduced vararg functions, marked by a parameter list ending in.... (Actually, in Lua 2.5 this was an experimental feature; it only became official in Lua 3.0.) When a vararg function was called, the arguments corresponding to the dots were collected into a table called arg. There was no way to pass those arguments to another function, except via this table. Lua 5.1 will allow... to be used in argument lists and in assignments. It will also not create the arg table if all that the function does is pass those arguments to other functions. (Since Lua 4.0, in a expression like f(g(),h()), all the values returned by h are passed as arguments to f, but only the first value returned by g. A similar thing happens in assignments.) 6.6 Lexical scoping From an early stage in the development of Lua we started thinking about first-class functions with lexical scoping. This is an elegant construct that fits well within Lua s philosophy of providing few but powerful constructs. However, we could not figure out a reasonable implementation. Since the beginning Lua has used a simple array stack to keep activation records (where all local variables and temporaries live). This implementation had proven to be simple and efficient, and we did not want to change it. When we allow nested functions, a variable used by an inner function may outlive the function that created it, and so we cannot use a stack discipline for such variables. We could not use more advanced compiler techniques, such as data-flow analysis, because Lua uses a one-pass compiler that generates code for the virtual machine on-the-fly, as it parses the source. We wanted to keep this attractive design for implementing Lua, because of its simplicity and efficiency. Thus, when the compiler generates code to access a local variable, it cannot know whether that variable will be used by an inner function. For a long time those difficulties kept us from introducing nested first-class functions with lexical scoping in Lua. Finally, in Lua 3.1 we settled on a compromise that we called upvalues. With upvalues, an inner function cannot access and modify external variables, but it can access their values at the time it is created. Upvalues allowed a simple implementation: all local variables live in the stack; when a function is created, Lua creates a closure for the function where it stores the values of the external variables that the function uses. In other words, upvalues are the frozen values of external variables. 7 To avoid misunderstandings and clearly mark frozen values, we created a new syntax for accessing upvalues: %varname. This syntax made it clear that the code was accessing the frozen value of that variable, not the variable itself. Upvalues proved very useful. When necessary, we could simulate mutable external variables by using a table as the upvalue: although we cannot change the table itself, we can change a field inside it. In the first draft of the book Programming in Lua [19], Roberto wrote that functions in Lua have a form of proper lexical scoping through upvalues. In July 2001 John D. Ramsdell argued in the mailing list that a language is either lexically scoped or it is not; adding the adjective proper to the phrase lexical scoping is meaningless. That message stirred us to search for a 7 One year later Java adopted a similar solution to allow inner classes. Instead of freezing the value of an external variable, Java insists that you can only access final variables in inner classes, thereby ensuring that the variable is frozen. 21
22 better solution and a way to implement real lexical scoping. By October 2001 we had a first implementation of full lexical scoping and described it to the list. The idea was to access upvalues through an indirection that pointed to the stack while the variable was in scope; at the end of the scope a special instruction closed the upvalue, moving the variable s value to a heap-allocated space and correcting the indirection to point there. Open closures (that is, with upvalues still pointing to the stack) were kept in a list to allow their correction. Edgar Toering, an active member of the list, misunderstood our description. It turned out that the way he thought lexical scoping worked was better than the original idea: Instead of keeping the closures in a list, keep the upvalues in a list parallel to the stack. That solution was more efficient than the previous one and easier to adapt to coroutines, which were being implemented at around the same time. (The article on the implementation of Lua 5.0 describes this algorithm [23].) 6.7 Extensible semantics Lua was designed to be an extension language. It only works embedded in a host program (which may be the standalone Lua interpreter). On the other hand, like any other language, Lua is subject to run-time errors: What happens when a variable is undefined? What happens when you add values that are not numbers? What happens when you index a value that is a not a table? In such cases, the standalone Lua interpreter can afford to simply halt the execution of the faulty Lua program, print an error message, and exit. A more general host program has no such privilege. Since Lua is embedded into the host program, the polite thing to do in case of errors is to let the host know that something wrong has happened and let it take an appropriate action. In Lua 1.1 we simply provided a single hook for handling errors. In Lua 2.1 we decided to allow the host program to set Lua functions as handlers for each type of error. We called those error handlers fallbacks. They were called when Lua did not know how to proceed and so provided a restricted form of resumable exception handling. Fallbacks were the expression of what we call extensible semantics. Using fallbacks, we could make values respond to operations not originally meant for them or make values of one type behave like values of another type. For instance, we could make userdata or tables respond to arithmetic operations, userdata behave as tables, strings behave as functions, etc. We could also make a table respond to keys that are absent in it. All this became under the programmer s control in Lua 2.1. One of the main uses of fallbacks was the implementation of inheritance in Lua. With fallbacks for table indexing and a little syntax sugar, object-oriented programming with inheritance became possible in Lua. Moreover, the programmer controls how the objects behave. Although objects, classes, and inheritance were not core concepts in Lua, they could be implemented in many flavors directly in Lua, according to the needs of the application. In others words, Lua provides mechanisms, not policy a tenet that we have tried to follow closely ever since. The code in Figure 5 implements inheritance by delegation, the simplest kind of inheritance, by setting the index fallback to follow a chain of parents upwards, until a table has the required field or the chain ends. (The index fallback was triggered when a table was accessed for an absent field.) With that index fallback, the code below prints red even though b does not have a color field: 22
23 function Index (a,i) if i == "parent" then return nil end local p = a.parent if type(p) == "table" then return p[i] else return nil end end setfallback("index", Index) -- avoid loops -- may trigger Index again -- set Index as a fallback Figure 5: Inheritance by delegation. a=window{x=100, y=200, color="red"} b=window{x=300, y=400, parent=a} print(b.color) There was nothing magical or hard-coded about delegation through a parent field. Programmers had complete freedom: they could use a different name for the parent field, they could implement a more complicated multiple inheritance by allowing the parent field to be itself a table of parents that are tried in order, etc. Our decision not to hard-code any of those possible behaviors led to one of the main design concepts of Lua: meta-mechanisms. Instead of littering the language with lots of features, we provided ways so that users could program the features themselves, in the way they want them, and only for those features they need. Mechanisms, not policy. Fallbacks were global handlers. It was difficult to mix objects of different classes, because there was only one hook for implementing inheritance (the table indexing fallback). Hooks for different classes could be chained, but this process was slow, complicated, and not very polite. It did not encourage code sharing and reuse. In Lua 3.0, we introduced tags that could be given to userdata and tables, and we replaced fallbacks by tag methods. Tag methods were fallbacks that operated only on values of a given type, that is, with a given tag. The tag method scheme worked very well, and lasted until Lua 4.0, but it was limited. In Lua 5.0 we replaced tags and tag methods by metatables and metamethods. Tag methods had their own private representation inside the Lua core and needed explicit interface functions to manipulate them. Metatables are just ordinary Lua tables and so can be manipulated within Lua without the need for special functions. Like tags, metatables can be used to represent user-defined types. All objects of the same type share the same metatable. Unlike tags, metatables and their contents are naturally collected when no references remain to them. Tags and their tag methods had to live until the end of the program. 23
24 6.8 C API Until Lua 3.0, only one Lua state existed and it was implemented as many static variables scattered throughout the code. Lua 3.1 introduced multiple independent Lua states; all static variables were collected into a single C struct. However, only one Lua state could be active at a given moment. The C API functions operated over this Lua state, which remained implicit, that is, did not appear in the calls. Explicit separate Lua states had to wait until Lua 4.0, which brought a completely new API that used a virtual stack for interfacing C and Lua. This is essentially the C API that we have now. The virtual stack provides a much clearer model for C Lua communication. Before Lua 4.0, C Lua communication was based on opaque lua_objects, which were actually indices into a hidden internal stack, but the API tried to maintain an illusion of separate arguments and results. In retrospect, we could have used explicit Lua states from the start, but we wanted the simplest thing that could work. The C API has slowly evolved to complete transparency, to the point that all standard library functions could be written using only the C API. This happened in Lua 4.0. Until then, Lua had a number of built-in functions (from 7 in Lua 1.1 to 35 in Lua 3.2), most of which could have been written using the C API but were not because of a perceived need for speed. A few built-in functions could not have been written using the C API because the C API was not complete. For instance, until Lua 3.2 it was not possible to iterate over a table contents using the C API, although it was possible to do it in Lua using the built-in function next! Since Lua 4.0 everything that can be done in Lua can be done in C (but not the other way around). 7 Lua in retrospect 7.1 Critique In this section we do a brief critique of the evolution of Lua, discussing what has worked well, what we regret, and what do not really regret but could have done differently. The thing that worked really well was the early decision (in Lua 1.0!) to have tables as the sole data-structuring mechanism in Lua. Tables have proved to be powerful and efficient. The central role of tables in the language (and its implementation) is one of the main characteristics of Lua. Another thing that worked well was our insistence on portability, which was initially motivated by the needs of Tecgraf s clients. This allowed Lua to be compiled for platforms that we had never dreamed of supporting. In particular, Lua s portability is probably one of the reasons Lua has been widely adopted for developing games: game consoles are restricted environments, both in memory and in support from the operating system. In particular, those environments tend not to support the complete semantics of the full standard C library. We have gradually reduced the dependency of Lua s core on the standard C library. mainly for embedding flexibility, but this also increases portability. For instance, Lua allows host programs to use their own memory allocator, instead of relying on malloc and friends. Since Lua 3.1 it is easy to change a few macros in the code to make Lua use your own memory allocator. Starting with Lua 5.1, the memory allocator can be provided dynamically when creating a Lua state. 24
25 Functions also became more flexible as Lua evolved. Although functions have always been first-class values, the introduction of anonymous functions and full lexical scoping has turned Lua into a very powerful and sophisticated language. Another aspect of this sophistication was the introduction of coroutines in Lua 5.0, which we hope marks a revival of coroutines as powerful control structures [15]. In particular, coroutines can be much exploited in the development of games [11]. No other scripting language has full coroutines in its core. The only other effort we know of is Stackless Python [4], which is an experimental fork of the Python implementation. With hindsight, we consider that being raised 8 by a small committee was very positive for the language. We only include a new feature when we reach unanimity; otherwise, it is left for the future. It is much easier to add features later than to remove them. This development process has been essential to keep the language simple, and simplicity is our most important asset. Most other qualities of Lua speed, small size, and portability derive from its simplicity. Since its first version Lua has had real users, that is, users others than ourselves, who care not about the language itself but how to use it productively. Users have always given important contributions to the language, through suggestions, complaints, use reports, and questions. Again, our small committee plays an important role in managing these: its structure gives us enough inertia to listen closely to the users without having to follow all their suggestions. We should have introduced booleans from the start, but we wanted to start with the simplest possible language. Not introducing booleans from the start had the unfortunate side-effect that a common protocol for signalling errors is for functions to return nil followed by an error message. It would have been better if false had been used instead of nil. Automatic coercion of strings to numbers in arithmetic operations, which we took from Awk, could have been avoided. (Coercion of numbers to strings in string operations is convenient and less troublesome.) Despite our mechanisms, not policy rule which we find valuable to guide the evolution of Lua we should have provided a precise set of policies for modules and packages earlier. The lack of a common policy for building modules and installing packages prevents different groups from sharing code and discourages the development of a community code base. Starting in Lua 5.1, Lua defines a set of policies for modules and packages which we hope will remedy this situation. 7.2 Lua in games The wide adoption of Lua in games came as a surprise to us. We did not have games as a target for Lua. With hindsight, however, that success is understandable, because all features that make Lua special are important to games: Portability: Many games run on non-conventional platforms, namely game consoles like Microsoft XBox and Sony PlayStation. 8 Languages designed by large committees tend to be too complicated and never quite fulfill the expectations of their sponsors. Most successful languages are raised rather than designed. They follow a slow bottom-up process, starting as a small language with modest goals. The language evolves as a consequence of actual feedback from real users, from which design flaws surface and new features are identified. 25
26 Easiness of embedding: Games are demanding applications. They need both performance, for its graphics and simulations, and flexibility for the creative staff. Not by chance, many games are coded in (at least) two languages, one for scripting and the other for coding the engine. Within that framework, the ease of integrating Lua with another language (mainly C++, in the case of games) is a big advantage. Simplicity: Most game designers are not professional programmers. For them, a language with a simple syntax and a simple semantics is particularly important. Efficiency and small size: Games are demanding applications, and game consoles are less powerful than typical microcomputers. Therefore, the script interpreter should be parsimonious with resources. Besides those points, other characteristics of Lua have made it specially attractive to games: Unlike most other software enterprises, games production involves little evolution. Once a game is released, there are no updates or new versions, only new games. So, it is easier to risk using a new language in a game. Game developers do not care whether the language will evolve or how it will evolve. All they need is the version they used in the game. The Lua license is also convenient for games. Most big games are not open source (some game companies even refuse to use any kind of open-source code). The competition is hard, and game companies tend to be secretive about their technologies. For them, a liberal license like the MIT license is quite convenient. (Prior to version 5, Lua used a MIT-like license; since version 5 it uses the MIT license.) Finally, Lua has features that should be really attractive to games but we do not have first-hand knowledge that they are indeed used in games: coroutines, as a means to implement multi-tasking in games; and Lua data files, which can replace textual data files with many benefits. Acknowledgements Lua would never be what it is without the help of many people. Everyone in Tecgraf contributed in different forms using the language, discussing it, disseminating it outside Tecgraf. Special thanks go to Marcelo Gattass, head of Tecgraf, who always encouraged us and gave us complete freedom over the language and its implementation. Lua is no longer a Tecgraf product but it is still developed inside PUC-Rio, in a new laboratory which we call Lua.org. Without users Lua would be just yet another language. Users and their uses are the ultimate test for a language. Special thanks go to the members of our mailing list, for their suggestions, complaints, and patience. The mailing list is relatively small (it has around 1000 participants), but it is very friendly and contains some very strong technical people that are not part of the Lua team but who generously share their expertise with the whole community. We thank Norman Ramsey for suggesting that we write a paper on Lua for HOPL III and for making the initial contacts with the conference chairs. We also thank PUC-Rio, IMPA, and CNPq for their continued support. 26
27 References [1] The computer language shootout benchmarks. [2] Lua projects. [3] The MIT license. [4] Stackless Python. [5] Which language do you use for scripting in your game engine? Sept [6] K. Beck. Extreme Programming Explained: Embrace Change. Addison-Wesley, [7] G. Bell, R. Carey, and C. Marrin. The Virtual Reality Modeling Language Specification Version Aug (ISO/IEC CD 14772). [8] J. Bentley. Programming pearls: associative arrays. Commun. ACM, 28(6): , [9] J. Bentley. Programming pearls: little languages. Commun. ACM, 29(8): , [10] W. Celes, L. H. de Figueiredo, and M. Gattass. EDG: uma ferramenta para criação de interfaces gráficas interativas. In Proceedings of SIBGRAPI 95 (Brazilian Symposium on Computer Graphics and Image Processing), pages , [11] L. H. de Figueiredo, W. Celes, and R. Ierusalimschy. Programming advanced control mechanisms with Lua coroutines. In Game Programming Gems 6. Charles River Media, [12] L. H. de Figueiredo, R. Ierusalimschy, and W. Celes. The design and implementation of a language for extending applications. In Proceedings of XXI SEMISH (Brazilian Seminar on Software and Hardware), pages , Caxambu, [13] L. H. de Figueiredo, R. Ierusalimschy, and W. Celes. Lua: an extensible embedded language. Dr. Dobb s Journal, 21(12):26 33, Dec [14] L. H. de Figueiredo, C. S. Souza, M. Gattass, and L. C. G. Coelho. Geração de interfaces para captura de dados sobre desenhos. In Proceedings of SIBGRAPI 92 (Brazilian Symposium on Computer Graphics and Image Processing), pages , [15] A. de Moura, N. Rodriguez, and R. Ierusalimschy. Coroutines in Lua. Journal of Universal Computer Science, 10(7): , [16] T. Gutschmidt. Game Programming with Python, Lua, and Ruby. Premier Press,
28 [17] M. Harmon. Building Lua into games. In Game Programming Gems 5, pages Charles River Media, [18] A. Hester, R. Borges, and R. Ierusalimschy. Building flexible and extensible web applications with Lua. Journal of Universal Computer Science, 4(9): , [19] R. Ierusalimschy. Programming in Lua. Lua.org, [20] R. Ierusalimschy, W. Celes, L. H. de Figueiredo, and R. de Souza. Lua: uma linguagem para customização de aplicações. In VII Simpósio Brasileiro de Engenharia de Software Caderno de Ferramentas, page 55, Rio de Janeiro, Brazil, [21] R. Ierusalimschy, L. H. de Figueiredo, and W. Celes. Lua: an extensible extension language. Software: Practice & Experience, 26(6): , [22] R. Ierusalimschy, L. H. de Figueiredo, and W. Celes. Lua 5.0 reference manual. Monografias em Ciência da Computação 14/03, Department of Computer Science, PUC-Rio, Rio de Janeiro, Brazil, [23] R. Ierusalimschy, L. H. de Figueiredo, and W. Celes. The implementation of Lua 5.0. Journal of Universal Computer Science, 11(7): , [24] R. Kelsey, W. Clinger, and J. R. (Editors). Revised 5 Report on the Algorithmic Language Scheme. ACM SIGPLAN Notices, 33(9):26 76, [25] L. Lamport. L A TEX: A Document Preparation System. Addison-Wesley, [26] B. Mogilefsky. Lua in Grim Fandango. May [27] Open Software Foundation. OSF/Motif Programmer s Guide. Prentice-Hall, Inc., [28] J. Ousterhout. Tcl: an embeddable command language. In Proc. of the Winter 1990 USENIX Technical Conference. USENIX Association, [29] D. Sanchez-Crespo. Core Techniques and Algorithms in Game Programming. New Riders Games, [30] P. Schuytema and M. Manyen. Game Development with Lua. Delmar Thomson Learning, [31] A. Varanese. Game Scripting Mastery. Premier Press,
The Evolution of Lua
The Evolution of Lua Roberto Ierusalimschy Department of Computer Science, PUC-Rio, Rio de Janeiro, Brazil [email protected] Luiz Henrique de Figueiredo IMPA Instituto Nacional de Matemática Pura
The Evolution of Lua. Waldemar Celes Luiz Henrique de Figueiredo Roberto Ierusalimschy
The Evolution of Lua Waldemar Celes Luiz Henrique de Figueiredo Roberto Ierusalimschy The Beginning Data Entry Programs 1992: Tecgraf - partnership between PUC and PETROBRAS (CENPES) Graphical data entry
Chapter 5 Names, Bindings, Type Checking, and Scopes
Chapter 5 Names, Bindings, Type Checking, and Scopes Chapter 5 Topics Introduction Names Variables The Concept of Binding Type Checking Strong Typing Scope Scope and Lifetime Referencing Environments Named
Chapter 12 Programming Concepts and Languages
Chapter 12 Programming Concepts and Languages Chapter 12 Programming Concepts and Languages Paradigm Publishing, Inc. 12-1 Presentation Overview Programming Concepts Problem-Solving Techniques The Evolution
Managing Variability in Software Architectures 1 Felix Bachmann*
Managing Variability in Software Architectures Felix Bachmann* Carnegie Bosch Institute Carnegie Mellon University Pittsburgh, Pa 523, USA [email protected] Len Bass Software Engineering Institute Carnegie
An overview of Lua. Julia Lawall. February 7, 2008 DIKU
An overview of Lua Julia Lawall DIKU February 7, 2008 Lua Pre-history (1992) DEL (Data-Entry Language) The problem: programmers had to enter data in columns. The goal: programmers type data into a relevant
Chapter 1. Dr. Chris Irwin Davis Email: [email protected] Phone: (972) 883-3574 Office: ECSS 4.705. CS-4337 Organization of Programming Languages
Chapter 1 CS-4337 Organization of Programming Languages Dr. Chris Irwin Davis Email: [email protected] Phone: (972) 883-3574 Office: ECSS 4.705 Chapter 1 Topics Reasons for Studying Concepts of Programming
Introduction to Python
WEEK ONE Introduction to Python Python is such a simple language to learn that we can throw away the manual and start with an example. Traditionally, the first program to write in any programming language
Organization of Programming Languages CS320/520N. Lecture 05. Razvan C. Bunescu School of Electrical Engineering and Computer Science bunescu@ohio.
Organization of Programming Languages CS320/520N Razvan C. Bunescu School of Electrical Engineering and Computer Science [email protected] Names, Bindings, and Scopes A name is a symbolic identifier used
Embedded Systems. Review of ANSI C Topics. A Review of ANSI C and Considerations for Embedded C Programming. Basic features of C
Embedded Systems A Review of ANSI C and Considerations for Embedded C Programming Dr. Jeff Jackson Lecture 2-1 Review of ANSI C Topics Basic features of C C fundamentals Basic data types Expressions Selection
Topics. Introduction. Java History CS 146. Introduction to Programming and Algorithms Module 1. Module Objectives
Introduction to Programming and Algorithms Module 1 CS 146 Sam Houston State University Dr. Tim McGuire Module Objectives To understand: the necessity of programming, differences between hardware and software,
Chapter 13: Program Development and Programming Languages
15 th Edition Understanding Computers Today and Tomorrow Comprehensive Chapter 13: Program Development and Programming Languages Deborah Morley Charles S. Parker Copyright 2015 Cengage Learning Learning
Bachelors of Computer Application Programming Principle & Algorithm (BCA-S102T)
Unit- I Introduction to c Language: C is a general-purpose computer programming language developed between 1969 and 1973 by Dennis Ritchie at the Bell Telephone Laboratories for use with the Unix operating
Chapter 13: Program Development and Programming Languages
Understanding Computers Today and Tomorrow 12 th Edition Chapter 13: Program Development and Programming Languages Learning Objectives Understand the differences between structured programming, object-oriented
Parsing Technology and its role in Legacy Modernization. A Metaware White Paper
Parsing Technology and its role in Legacy Modernization A Metaware White Paper 1 INTRODUCTION In the two last decades there has been an explosion of interest in software tools that can automate key tasks
A Comparison of Programming Languages for Graphical User Interface Programming
University of Tennessee, Knoxville Trace: Tennessee Research and Creative Exchange University of Tennessee Honors Thesis Projects University of Tennessee Honors Program 4-2002 A Comparison of Programming
Building Applications Using Micro Focus COBOL
Building Applications Using Micro Focus COBOL Abstract If you look through the Micro Focus COBOL documentation, you will see many different executable file types referenced: int, gnt, exe, dll and others.
Semantic Analysis: Types and Type Checking
Semantic Analysis Semantic Analysis: Types and Type Checking CS 471 October 10, 2007 Source code Lexical Analysis tokens Syntactic Analysis AST Semantic Analysis AST Intermediate Code Gen lexical errors
Advanced compiler construction. General course information. Teacher & assistant. Course goals. Evaluation. Grading scheme. Michel Schinz 2007 03 16
Advanced compiler construction Michel Schinz 2007 03 16 General course information Teacher & assistant Course goals Teacher: Michel Schinz [email protected] Assistant: Iulian Dragos INR 321, 368 64
Name: Class: Date: 9. The compiler ignores all comments they are there strictly for the convenience of anyone reading the program.
Name: Class: Date: Exam #1 - Prep True/False Indicate whether the statement is true or false. 1. Programming is the process of writing a computer program in a language that the computer can respond to
Language Evaluation Criteria. Evaluation Criteria: Readability. Evaluation Criteria: Writability. ICOM 4036 Programming Languages
ICOM 4036 Programming Languages Preliminaries Dr. Amirhossein Chinaei Dept. of Electrical & Computer Engineering UPRM Spring 2010 Language Evaluation Criteria Readability: the ease with which programs
Chapter 3.2 C++, Java, and Scripting Languages. The major programming languages used in game development.
Chapter 3.2 C++, Java, and Scripting Languages The major programming languages used in game development. C++ C used to be the most popular language for games Today, C++ is the language of choice for game
language 1 (source) compiler language 2 (target) Figure 1: Compiling a program
CS 2112 Lecture 27 Interpreters, compilers, and the Java Virtual Machine 1 May 2012 Lecturer: Andrew Myers 1 Interpreters vs. compilers There are two strategies for obtaining runnable code from a program
Symbol Tables. Introduction
Symbol Tables Introduction A compiler needs to collect and use information about the names appearing in the source program. This information is entered into a data structure called a symbol table. The
Chapter 13 Computer Programs and Programming Languages. Discovering Computers 2012. Your Interactive Guide to the Digital World
Chapter 13 Computer Programs and Programming Languages Discovering Computers 2012 Your Interactive Guide to the Digital World Objectives Overview Differentiate between machine and assembly languages Identify
The programming language C. sws1 1
The programming language C sws1 1 The programming language C invented by Dennis Ritchie in early 1970s who used it to write the first Hello World program C was used to write UNIX Standardised as K&C (Kernighan
1/20/2016 INTRODUCTION
INTRODUCTION 1 Programming languages have common concepts that are seen in all languages This course will discuss and illustrate these common concepts: Syntax Names Types Semantics Memory Management We
C# and Other Languages
C# and Other Languages Rob Miles Department of Computer Science Why do we have lots of Programming Languages? Different developer audiences Different application areas/target platforms Graphics, AI, List
Evolution of the Major Programming Languages
142 Evolution of the Major Programming Languages Object Oriented Programming: Smalltalk Object-Oriented: It s fundamental characteristics are: Data abstraction, Inheritance and Dynamic Binding. The essence
Jonathan Worthington Scarborough Linux User Group
Jonathan Worthington Scarborough Linux User Group Introduction What does a Virtual Machine do? Hides away the details of the hardware platform and operating system. Defines a common set of instructions.
Functional Programming
FP 2005 1.1 3 Functional Programming WOLFRAM KAHL [email protected] Department of Computing and Software McMaster University FP 2005 1.2 4 What Kinds of Programming Languages are There? Imperative telling
Moving from CS 61A Scheme to CS 61B Java
Moving from CS 61A Scheme to CS 61B Java Introduction Java is an object-oriented language. This document describes some of the differences between object-oriented programming in Scheme (which we hope you
Interpreters and virtual machines. Interpreters. Interpreters. Why interpreters? Tree-based interpreters. Text-based interpreters
Interpreters and virtual machines Michel Schinz 2007 03 23 Interpreters Interpreters Why interpreters? An interpreter is a program that executes another program, represented as some kind of data-structure.
1. Overview of the Java Language
1. Overview of the Java Language What Is the Java Technology? Java technology is: A programming language A development environment An application environment A deployment environment It is similar in syntax
Programming Languages
Programming Languages Qing Yi Course web site: www.cs.utsa.edu/~qingyi/cs3723 cs3723 1 A little about myself Qing Yi Ph.D. Rice University, USA. Assistant Professor, Department of Computer Science Office:
The Java Series. Java Essentials I What is Java? Basic Language Constructs. Java Essentials I. What is Java?. Basic Language Constructs Slide 1
The Java Series Java Essentials I What is Java? Basic Language Constructs Slide 1 What is Java? A general purpose Object Oriented programming language. Created by Sun Microsystems. It s a general purpose
LittleCMS: A free color management engine in 100K.
LittleCMS: A free color management engine in 100K. Background One of the main components of a color management solution is the Color Matching Module, or CMM, which is the software engine in charge of controlling
White Paper. Java versus Ruby Frameworks in Practice STATE OF THE ART SOFTWARE DEVELOPMENT 1
White Paper Java versus Ruby Frameworks in Practice STATE OF THE ART SOFTWARE DEVELOPMENT 1 INTRODUCTION...3 FRAMEWORKS AND LANGUAGES...3 SECURITY AND UPGRADES...4 Major Upgrades...4 Minor Upgrades...5
McGraw-Hill The McGraw-Hill Companies, Inc., 20 1. 01 0
1.1 McGraw-Hill The McGraw-Hill Companies, Inc., 2000 Objectives: To describe the evolution of programming languages from machine language to high-level languages. To understand how a program in a high-level
VHDL Test Bench Tutorial
University of Pennsylvania Department of Electrical and Systems Engineering ESE171 - Digital Design Laboratory VHDL Test Bench Tutorial Purpose The goal of this tutorial is to demonstrate how to automate
1 Introduction. 2 An Interpreter. 2.1 Handling Source Code
1 Introduction The purpose of this assignment is to write an interpreter for a small subset of the Lisp programming language. The interpreter should be able to perform simple arithmetic and comparisons
CS 106 Introduction to Computer Science I
CS 106 Introduction to Computer Science I 01 / 21 / 2014 Instructor: Michael Eckmann Today s Topics Introduction Homework assignment Review the syllabus Review the policies on academic dishonesty and improper
Characteristics of Java (Optional) Y. Daniel Liang Supplement for Introduction to Java Programming
Characteristics of Java (Optional) Y. Daniel Liang Supplement for Introduction to Java Programming Java has become enormously popular. Java s rapid rise and wide acceptance can be traced to its design
6.170 Tutorial 3 - Ruby Basics
6.170 Tutorial 3 - Ruby Basics Prerequisites 1. Have Ruby installed on your computer a. If you use Mac/Linux, Ruby should already be preinstalled on your machine. b. If you have a Windows Machine, you
Programming Languages
Programming Languages Programming languages bridge the gap between people and machines; for that matter, they also bridge the gap among people who would like to share algorithms in a way that immediately
Database Programming with PL/SQL: Learning Objectives
Database Programming with PL/SQL: Learning Objectives This course covers PL/SQL, a procedural language extension to SQL. Through an innovative project-based approach, students learn procedural logic constructs
1 The Java Virtual Machine
1 The Java Virtual Machine About the Spec Format This document describes the Java virtual machine and the instruction set. In this introduction, each component of the machine is briefly described. This
Comp 411 Principles of Programming Languages Lecture 34 Semantics of OO Languages. Corky Cartwright Swarat Chaudhuri November 30, 20111
Comp 411 Principles of Programming Languages Lecture 34 Semantics of OO Languages Corky Cartwright Swarat Chaudhuri November 30, 20111 Overview I In OO languages, data values (except for designated non-oo
Design Patterns in Parsing
Abstract Axel T. Schreiner Department of Computer Science Rochester Institute of Technology 102 Lomb Memorial Drive Rochester NY 14623-5608 USA [email protected] Design Patterns in Parsing James E. Heliotis
Concepts and terminology in the Simula Programming Language
Concepts and terminology in the Simula Programming Language An introduction for new readers of Simula literature Stein Krogdahl Department of Informatics University of Oslo, Norway April 2010 Introduction
Object Oriented Software Design
Object Oriented Software Design Introduction to Java - II Giuseppe Lipari http://retis.sssup.it/~lipari Scuola Superiore Sant Anna Pisa September 14, 2011 G. Lipari (Scuola Superiore Sant Anna) Introduction
1-04-10 Configuration Management: An Object-Based Method Barbara Dumas
1-04-10 Configuration Management: An Object-Based Method Barbara Dumas Payoff Configuration management (CM) helps an organization maintain an inventory of its software assets. In traditional CM systems,
Object Oriented Software Design
Object Oriented Software Design Introduction to Java - II Giuseppe Lipari http://retis.sssup.it/~lipari Scuola Superiore Sant Anna Pisa October 28, 2010 G. Lipari (Scuola Superiore Sant Anna) Introduction
IEC 61131-3. The Fast Guide to Open Control Software
IEC 61131-3 The Fast Guide to Open Control Software 1 IEC 61131-3 The Fast Guide to Open Control Software Introduction IEC 61131-3 is the first vendor-independent standardized programming language for
Johannes Sametinger. C. Doppler Laboratory for Software Engineering Johannes Kepler University of Linz A-4040 Linz, Austria
OBJECT-ORIENTED DOCUMENTATION C. Doppler Laboratory for Software Engineering Johannes Kepler University of Linz A-4040 Linz, Austria Abstract Object-oriented programming improves the reusability of software
What is a programming language?
Overview Introduction Motivation Why study programming languages? Some key concepts What is a programming language? Artificial language" Computers" Programs" Syntax" Semantics" What is a programming language?...there
In this Lecture you will Learn: Implementation. Software Implementation Tools. Software Implementation Tools
In this Lecture you will Learn: Implementation Chapter 19 About tools used in software implementation How to draw component diagrams How to draw deployment diagrams The tasks involved in testing a system
Programming Languages & Tools
4 Programming Languages & Tools Almost any programming language one is familiar with can be used for computational work (despite the fact that some people believe strongly that their own favorite programming
AP Computer Science A - Syllabus Overview of AP Computer Science A Computer Facilities
AP Computer Science A - Syllabus Overview of AP Computer Science A Computer Facilities The classroom is set up like a traditional classroom on the left side of the room. This is where I will conduct my
Glossary of Object Oriented Terms
Appendix E Glossary of Object Oriented Terms abstract class: A class primarily intended to define an instance, but can not be instantiated without additional methods. abstract data type: An abstraction
CE 504 Computational Hydrology Computational Environments and Tools Fritz R. Fiedler
CE 504 Computational Hydrology Computational Environments and Tools Fritz R. Fiedler 1) Operating systems a) Windows b) Unix and Linux c) Macintosh 2) Data manipulation tools a) Text Editors b) Spreadsheets
[Refer Slide Time: 05:10]
Principles of Programming Languages Prof: S. Arun Kumar Department of Computer Science and Engineering Indian Institute of Technology Delhi Lecture no 7 Lecture Title: Syntactic Classes Welcome to lecture
HEP data analysis using jhepwork and Java
HEP data analysis using jhepwork and Java S. Chekanov HEP Division, Argonne National Laboratory, 9700 S.Cass Avenue, Argonne, IL 60439 USA 1 Introduction Abstract A role of Java in high-energy physics
Handout 1. Introduction to Java programming language. Java primitive types and operations. Reading keyboard Input using class Scanner.
Handout 1 CS603 Object-Oriented Programming Fall 15 Page 1 of 11 Handout 1 Introduction to Java programming language. Java primitive types and operations. Reading keyboard Input using class Scanner. Java
An Incomplete C++ Primer. University of Wyoming MA 5310
An Incomplete C++ Primer University of Wyoming MA 5310 Professor Craig C. Douglas http://www.mgnet.org/~douglas/classes/na-sc/notes/c++primer.pdf C++ is a legacy programming language, as is other languages
The Smalltalk Programming Language. Beatrice Åkerblom [email protected]
The Smalltalk Programming Language Beatrice Åkerblom [email protected] 'The best way to predict the future is to invent it' - Alan Kay. History of Smalltalk Influenced by Lisp and Simula Object-oriented
Lab 4.4 Secret Messages: Indexing, Arrays, and Iteration
Lab 4.4 Secret Messages: Indexing, Arrays, and Iteration This JavaScript lab (the last of the series) focuses on indexing, arrays, and iteration, but it also provides another context for practicing with
Generalizing Overloading for C++2000
Generalizing Overloading for C++2000 Bjarne Stroustrup AT&T Labs, Florham Park, NJ, USA Abstract This paper outlines the proposal for generalizing the overloading rules for Standard C++ that is expected
A Static Analyzer for Large Safety-Critical Software. Considered Programs and Semantics. Automatic Program Verification by Abstract Interpretation
PLDI 03 A Static Analyzer for Large Safety-Critical Software B. Blanchet, P. Cousot, R. Cousot, J. Feret L. Mauborgne, A. Miné, D. Monniaux,. Rival CNRS École normale supérieure École polytechnique Paris
CSE 373: Data Structure & Algorithms Lecture 25: Programming Languages. Nicki Dell Spring 2014
CSE 373: Data Structure & Algorithms Lecture 25: Programming Languages Nicki Dell Spring 2014 What is a Programming Language? A set of symbols and associated tools that translate (if necessary) collections
Instruction Set Architecture (ISA)
Instruction Set Architecture (ISA) * Instruction set architecture of a machine fills the semantic gap between the user and the machine. * ISA serves as the starting point for the design of a new machine
Sources: On the Web: Slides will be available on:
C programming Introduction The basics of algorithms Structure of a C code, compilation step Constant, variable type, variable scope Expression and operators: assignment, arithmetic operators, comparison,
How to test and debug an ASP.NET application
Chapter 4 How to test and debug an ASP.NET application 113 4 How to test and debug an ASP.NET application If you ve done much programming, you know that testing and debugging are often the most difficult
Programming Language Concepts for Software Developers
Programming Language Concepts for Software Developers Peter Sestoft IT University of Copenhagen, Denmark [email protected] Abstract This note describes and motivates our current plans for an undergraduate
Introduction to Programming System Design. CSCI 455x (4 Units)
Introduction to Programming System Design CSCI 455x (4 Units) Description This course covers programming in Java and C++. Topics include review of basic programming concepts such as control structures,
ASSEMBLY LANGUAGE PROGRAMMING (6800) (R. Horvath, Introduction to Microprocessors, Chapter 6)
ASSEMBLY LANGUAGE PROGRAMMING (6800) (R. Horvath, Introduction to Microprocessors, Chapter 6) 1 COMPUTER LANGUAGES In order for a computer to be able to execute a program, the program must first be present
Parameter Passing in Pascal
Parameter Passing in Pascal Mordechai Ben-Ari Department of Science Teaching Weizmann Institute of Science Rehovot 76100 Israel [email protected] Abstract This paper claims that reference parameters
PART-A Questions. 2. How does an enumerated statement differ from a typedef statement?
1. Distinguish & and && operators. PART-A Questions 2. How does an enumerated statement differ from a typedef statement? 3. What are the various members of a class? 4. Who can access the protected members
The V8 JavaScript Engine
The V8 JavaScript Engine Design, Implementation, Testing and Benchmarking Mads Ager, Software Engineer Agenda Part 1: What is JavaScript? Part 2: V8 internals Part 3: V8 testing and benchmarking What is
Parrot in a Nutshell. Dan Sugalski [email protected]. Parrot in a nutshell 1
Parrot in a Nutshell Dan Sugalski [email protected] Parrot in a nutshell 1 What is Parrot The interpreter for perl 6 A multi-language virtual machine An April Fools joke gotten out of hand Parrot in a nutshell
Thomas Jefferson High School for Science and Technology Program of Studies Foundations of Computer Science. Unit of Study / Textbook Correlation
Thomas Jefferson High School for Science and Technology Program of Studies Foundations of Computer Science updated 03/08/2012 Unit 1: JKarel 8 weeks http://www.fcps.edu/is/pos/documents/hs/compsci.htm
Test Automation Architectures: Planning for Test Automation
Test Automation Architectures: Planning for Test Automation Douglas Hoffman Software Quality Methods, LLC. 24646 Heather Heights Place Saratoga, California 95070-9710 Phone 408-741-4830 Fax 408-867-4550
How do Users and Processes interact with the Operating System? Services for Processes. OS Structure with Services. Services for the OS Itself
How do Users and Processes interact with the Operating System? Users interact indirectly through a collection of system programs that make up the operating system interface. The interface could be: A GUI,
Figure 1: Graphical example of a mergesort 1.
CSE 30321 Computer Architecture I Fall 2011 Lab 02: Procedure Calls in MIPS Assembly Programming and Performance Total Points: 100 points due to its complexity, this lab will weight more heavily in your
2) Write in detail the issues in the design of code generator.
COMPUTER SCIENCE AND ENGINEERING VI SEM CSE Principles of Compiler Design Unit-IV Question and answers UNIT IV CODE GENERATION 9 Issues in the design of code generator The target machine Runtime Storage
Part 1 Foundations of object orientation
OFWJ_C01.QXD 2/3/06 2:14 pm Page 1 Part 1 Foundations of object orientation OFWJ_C01.QXD 2/3/06 2:14 pm Page 2 1 OFWJ_C01.QXD 2/3/06 2:14 pm Page 3 CHAPTER 1 Objects and classes Main concepts discussed
Formal Languages and Automata Theory - Regular Expressions and Finite Automata -
Formal Languages and Automata Theory - Regular Expressions and Finite Automata - Samarjit Chakraborty Computer Engineering and Networks Laboratory Swiss Federal Institute of Technology (ETH) Zürich March
The Implementation of Lua 5.0
The Implementation of Lua 5.0 Roberto Ierusalimschy (Department of Computer Science, PUC-Rio, Rio de Janeiro, Brazil [email protected]) Luiz Henrique de Figueiredo (IMPA Instituto de Matemática Pura
Taboret Management Application Builder
Taboret Management Application Builder INTRODUCTION Management Application Builders allow network-knowledgeable people to build their own solutions to management problems. More important, these new tools
Component visualization methods for large legacy software in C/C++
Annales Mathematicae et Informaticae 44 (2015) pp. 23 33 http://ami.ektf.hu Component visualization methods for large legacy software in C/C++ Máté Cserép a, Dániel Krupp b a Eötvös Loránd University [email protected]
An Easier Way for Cross-Platform Data Acquisition Application Development
An Easier Way for Cross-Platform Data Acquisition Application Development For industrial automation and measurement system developers, software technology continues making rapid progress. Software engineers
Programming Exercises
s CMPS 5P (Professor Theresa Migler-VonDollen ): Assignment #8 Problem 6 Problem 1 Programming Exercises Modify the recursive Fibonacci program given in the chapter so that it prints tracing information.
Analysis of Micromouse Maze Solving Algorithms
1 Analysis of Micromouse Maze Solving Algorithms David M. Willardson ECE 557: Learning from Data, Spring 2001 Abstract This project involves a simulation of a mouse that is to find its way through a maze.
Excel & Visual Basic for Applications (VBA)
Excel & Visual Basic for Applications (VBA) The VBA Programming Environment Recording Macros Working with the Visual Basic Editor (VBE) 1 Why get involved with this programming business? If you can't program,
#820 Computer Programming 1A
Computer Programming I Levels: 10-12 Units of Credit: 1.0 CIP Code: 11.0201 Core Code: 35-02-00-00-030 Prerequisites: Secondary Math I, Keyboarding Proficiency, Computer Literacy requirement Semester 1
IF The customer should receive priority service THEN Call within 4 hours PCAI 16.4
Back to Basics Backward Chaining: Expert System Fundamentals By Dustin Huntington Introduction Backward chaining is an incredibly powerful yet widely misunderstood concept, yet it is key to building many
We will learn the Python programming language. Why? Because it is easy to learn and many people write programs in Python so we can share.
LING115 Lecture Note Session #4 Python (1) 1. Introduction As we have seen in previous sessions, we can use Linux shell commands to do simple text processing. We now know, for example, how to count words.
