Lua (programming language)

From Bauman National Library
This page was last modified on 1 June 2016, at 16:32.
Lua
Lua-logo.png
Paradigm Multi-paradigm: imperative, functional, prototype-based, scripting
Designed by Roberto Ierusalimschy, Waldemar Celes, Luiz Henrique de Figueiredo
First appeared 1993
Typing discipline dynamic, strong, duck
Filename extensions .lua
Website None
Major implementations
Lua, LuaJIT, LLVM-Lua, LuaCLR, Nua, Lua Alchemy
Dialects
MetaLua
Influenced by
Scheme, SNOBOL, Modula, CLU, C++
Influenced
Io, GameMonkey, Squirrel, Dao, MiniD

Lua is a powerful, fast, lightweight, embeddable scripting language.

Lua combines simple procedural syntax with powerful data description constructs based on associative arrays and extensible semantics. Lua is dynamically typed, runs by interpreting bytecode for a register-based virtual machine, and has automatic memory management with incremental garbage collection, making it ideal for configuration, scripting, and rapid prototyping.

Where possible, the ideology and the implementation of the language closest to JavaScript, but Lua has a more powerful and much more flexible structures. Although Lua does not contain the concept of classes and objects explicitly, the mechanisms of object-oriented programming, including multiple inheritance can be implemented using the metatables. Implemented object model can be called a prototype (like in JavaScript).

Lua is free software with open source, licensed under the MIT. It can be used for any purpose, including commercial purposes, at absolutely no cost.

History

Lua was created in 1993 by Roberto Ierusalimschy, Luiz Henrique de Figueiredo, and Waldemar Celes, members of the Computer Graphics Technology Group (Tecgraf) at the Pontifical Catholic University of Rio de Janeiro, in Brazil.

Lua's historical "father and mother" were the data-description/configuration languages SOL (Simple Object Language) and DEL (data-entry language). They had been independently developed at Tecgraf in 1992–1993 to add some flexibility into two different projects (both were interactive graphical programs for engineering applications at Petrobras company). There was a lack of any flow-control structures in SOL and DEL, and Petrobras felt a growing need to add full programming power to them.

Lua 1.0 was designed in such a way that its object constructors, being then slightly different from the current light and flexible style, incorporated the data-description syntax of SOL (hence the name Lua – sol is Portuguese for sun; lua is moon). Lua syntax for control structures was mostly borrowed from Modula (if, while, repeat/until), but also had taken influence from CLU (multiple assignments and multiple returns from function calls, as a simpler alternative to reference parameters or explicit pointers), C++ ("neat idea of allowing a local variable to be declared only where we need it"), SNOBOL and AWK (associative arrays). In an article published in Dr. Dobb's Journal, Lua's creators also state that LISP and Scheme with their single, ubiquitous data structure mechanism (the list) were a major influence on their decision to develop the table as the primary data structure of Lua.

Versions of Lua prior to version 5.0 were released under a license similar to the BSD license. From version 5.0 onwards, Lua has been licensed under the MIT License. Both are permissive free software licences and are almost identical.

Tools

Stand-alone interpreter (also called lua.c named source file) is a small program that allows the direct use of Lua. When the interpreter loads a file, it ignores the first line if it starts with a "hash sign" ("#"). This feature allows the use of Lua as a script interpreter in Unix-based systems. If you have your code is preceded by a string of the form

    #!/usr/local/bin/lua

(assuming that the autonomous interpreter located in /usr/local/bin), or

    #!/usr/bin/env lua

you can call (execute) the program directly, without needing to run the Lua's interpreter.

Launch Lua with

    lua [options] [script [args]]

All parameters are optional. As we have seen, when run with no arguments lua interpreter enters interactive mode. The -e key allows you to enter the code directly in the command line.

For instance,

    prompt> lua -e "print(math.sin(12))"   --> -0.53657291800043

(On Unix, you must specify double quotes to separate shell commands from the actual executable code.) As mentioned above, the -l switch loads the file, and the interpreter translates -i as an interactive mode after processing other keys (or options). For example, the call

    prompt> lua -i -l a.lua -e "x = 10"

load file with name a.lua, then execute the assignment x = 10, and finally provides a command line entry.

Scripting language extension marking .lua. For the problems of time-critical, there is a JIT-compiler Lua, which is called LuaJIT. Also has been developed the compiler llvm-lua. It generates code for a virtual machine LLVM, provides an opportunity to follow the compilation in a very efficient machine code for different processor architectures.

Basic principles

Lexical conventions

Names (identifiers) in Lua can be any string of letters, digits, and underscores, not beginning with a digit. The following keywords are reserved and can not be used in names:

and break do else elseif
end false for function if
in local nil not or
repeat return then true until
while

Lua has a language-sensitive characters: and - the keyword, whereas And and AND- two different valid IDs. By convention, names starting with an underscore, and written in upper case (eg _VERSION), are reserved for use as an internal global variables used by Lua. Literal strings must be enclosed in single or double quotes and may contain a C-like escape-sequencies.

Types and variables

Lua is a dynamically typed language. There are no type definitions in the language; each value carries its own type. There are eight basic types in Lua: nil, boolean, number, string, userdata, function, thread, and table.

  1. Nil - is a type with a single value, nil, whose main property is to be different from any other value. As we have seen, a global variable has a nil value by default, before a first assignment, and you can assign nil to a global variable to delete it. Lua uses nil as a kind of non-value, to represent the absence of a useful value.
  2. The boolean type has two values, false and true, which represent the traditional boolean values. However, they do not hold a monopoly of condition values: In Lua, any value may represent a condition. Conditionals (such as the ones in control structures) consider false and nil as false and anything else as true.
  3. The number type represents real (double-precision floating-point) numbers.
  4. Strings have the usual meaning: a sequence of characters. Lua is eight-bit clean and so strings may contain characters with any numeric value, including embedded zeros. That means that you can store any binary data into a string. Strings in Lua are immutable values. You cannot change a character inside a string, as you may in C; instead, you create a new string with the desired modifications
  5. Functions are first-class values in Lua. That means that functions can be stored in variables, passed as arguments to other functions, and returned as results.
  6. The userdata type allows arbitrary C data to be stored in Lua variables. It has no predefined operations in Lua, except assignment and equality test.
  7. The table type implements associative arrays. An associative array is an array that can be indexed not only with numbers, but also with strings or any other value of the language, except nil. Moreover, tables have no fixed size; you can add as many elements as you want to a table dynamically. Tables are the main (in fact, the only) data structuring mechanism in Lua, and a powerful one. We use tables to represent ordinary arrays, symbol tables, sets, records, queues, and other data structures, in a simple, uniform, and efficient way. Lua uses tables to represent packages as well.

The variables of type table, function, thread and userdata do not contain the actual data, they are stored only a reference to the corresponding object.

In Lua, there are three kinds of variables: global, local, and table fields. Every variable is considered to be global if it is not explicitly declared as local. Local variables exist in the lexical context: local variables are available for functions definitions in this context.

local x, y, z
local a, b, c = 1, 2, 3
local x = x

Operators

There is in Lua supporting of a general standard set of operators, almost as in Pascal or C. It consists of assignment operators, operators, which control the flow of execution, function calls, and variable declarations.

Here are the basic operations:

  -            negation
  + - * /      ariphmetics
  ^            exponentiation

  == ~=        equality

  < <= > >=    ordering

  not and or   logics

  ..           string concatenation
  #            length of an array or a string

When compared to equality Lua does not make the conversion of types. Objects of different types are always considered to be different. When calculating the value of using a short circuit - the second argument is evaluated only if necessary.

The following table describes priorities and associativity of operations:

 [right]    ^
 [left]     not   #     -(unary)
 [left]     *     /
 [left]     +     -
 [left]     <     >     <=     >=     ~=     ==
 [right]    ..
 [left]     and
 [left]     or

In Lua no dedicated function that starts the program (like main() in C). The interpreter sequentially executes the statements that it receives from a file or from a control program. Thus it compiles the program beforehand in the binary representation, which can also be stored.

Each block of code is interpreted as an anonymous function, so it is possible to define local variables inside, as well as value can be returned.

Operators can be (but not necessary) separated by ';'

Below the general operators of a language are presented:

  do ... end

  if ... then ... end
  if ... then ... else ... end
  if ... then ... elseif ... then ... end
  if ... then ... elseif ... then ... else ... end

  while ... do ... end
  repeat ... until ...

  for var = start, stop do ... end
  for var = start, stop, step do ... end

  return
  return ...
  break

Block do ... end converts a sequence of statements into one statement and opens a new scope in which a programmer can define local variables.

In statements if, while and repeat all the values of an expression different from false and nil are treated as true. Operator return may not contain the return values, or contain one or more expressions (list). Operators return and break must be the last statement in the block (i.e. must either be the last statement in a block of code, or placed immediately before the word end, else, elseif, until).

Operator for cycle for all values of the variable from a starting value to ending value inclusive. The third value, if specified, is used as a step change in the loop variable. All of these values must be numeric. They are calculated only once before executing the cycle. The loop variable is local in this cycle, and is not available outside of his body. The value of the loop variable can not be changed in the loop body. That patch of the pseudocode showing the using of a for:

  do
    local var, _limit, _step = tonumber(start), tonumber(stop), tonumber(step)
    if not (var and _limit and _step) then error() end
    while (_step>0 and var<=_limit) or (_step<=0 and var>=_limit) do
      ...
      var = var + _step
    end
  end

Functions

A function definition in Lua is an executable expression (constructor function) that is evaluated to a function object type:

  f = function( ... ) ... end

In parentheses is located list (possibly empty) of function arguments. List of function arguments can end with three dots - in this case, the function has a variable number of arguments. Between the closing bracket and the operator end is placed the body of the function.

At the time of implementation of the constructor function also constructing the closure - a table of all available functions and external local variables. If a function is passed as a return value, then it maintains access to all variables in its closure. Each performance of the constructor is building a new closure.

A function call consists of a function reference, and the enclosed in parentheses argument list (possibly empty). Any expression that evaluates to a function can play a role aof a reference to a function. Between the reference to the function and the opening parenthesis can not be a newline.

If the function takes a single argument and treats it as a table whose elements are indexed names of formal parameters of the function, in this case the call is actually implemented by a named arguments mechanism:

  function rename( arg )
    arg.new = arg.new or arg.old .. ".bak"
    return os.rename(arg.old, arg.new)
  end

  rename{ old = "asd.qwe" }

Meta-tables

Each table and an object of type userdata can have meta-table - a regular table whose fields define the behavior of the original object in the application to it of some special operations. For example, when an object is in the operand of addition, the interpreter searches for meta-table field named __add and if this field is present, then its value is used as the function that performs the addition. Indices (field names) in the meta-table called events, and the corresponding values (event handlers) - metamethods.

By default, the newly created table does not have a meta-table. Any table mt can do a meta-table table t, calling the setmetatable (t, mt). The function getmetatable (t) returns the meta-table table t or nil, if the table does not have a meta-table.

Lua defines next events:

  __add, __sub, __mul, __div      арифметические операции
  __pow                           возведение в степень
  __unm                           унарный минус
  __concat                        конкатенация
  __eq, __lt, __le                операции сравнения
  __index                         доступ по отсутствующему индексу
  __newindex                      присвоение новому элементу таблицы
  __call                          вызов функции
  __tostring                      преобразование в строку
  __metatable                     получения мета-таблицы
Examples of meta-tables

In the following example, the meta-table used to assign default values for the missing elements of the table:

  function set_def(t, v)
    local mt = { __index = function() return v end }
    setmetatable(t, mt)
  end

Here's a non-trivial solution, which does not use a separate meta-tables for each default value:

  local key = {}
  local mt = { __index = function(t) return t[key] end }

  function set_def(t, v)
    t[key] = v
    setmetatable(t, mt)
  end

A meta-method __index of this meta-table intercepts calls to the missing fields of the table and returns the value stored in the table itself on the index key.

Packets

Packages - the main way to define a set of related functions that are not polluting the global scope. Normally package is a single file that defines in the global scope a single table that contains all the features of this package:

  my_package = {}
      
  function my_package.foo()
    ...
  end

You can also do all the functions of the local and apart form the table of exported functions:

  local function foo() ... end
  local function bar() ... end

  my_package = {
    foo = foo,
    bar = bar,
  }

The package is downloading using the require(), and while loading the name passed to the function (it can not contain the extension that will be added automatically) is available via the variable _REQUIREDNAME:

  if _REQUIREDNAME == nil then
    run_some_internal_tests()
  end

Objects and classes

Construction tbl: func() (function declaration and when it is called) provides basic capabilities to work with the table as an object. The main problem is generating many objects with similar behavior from one class:

  function class()
    cl = {}
    cl.__index = cl            -- cl будет использоваться как мета-таблица
    return cl
  end

  function object( cl, obj )
    obj = obj or {}            -- возможно уже есть заполненные поля
    setmetatable(obj, cl)
    return obj
  end

Here, the function class creates an empty table, prepared for becoming a meta-object table. Class methods are made from fields of the table that is a table containing both the object and its methods of meta-techniques.

The function object() creates an object of a given class - table, which as a meta-table set given class. The second argument can be transferred to a table containing initialized object fields.

  Some_Class = class()

  function Some_Class:foo() ... end

  function Some_Class:new()
    return object(self, { xxx = 12 })
  end

  x = Some_Class:new()

  x:foo()

Standard libraries

Lua standard libraries contain commonly used functions that are performed directly in the C API. Some of these functions provide essential services of language (for example, type, and getmetatable); others provide access to "outside" services (such as I / O); partly they are realized on Lua, but frequently used and having a critical time performance, implemented in C (eg, sort).

All libraries are invoked through the official C API and are carried out as separate C modules.

Currently, Lua has the following standard libraries:

  • base library (basic library);
  • Library package (package library);
  • working with strings (string manipulation);
  • work with tables (table manipulation);
  • mathematical functions (sin, log, etc.);
  • input and output;
  • work with OS (operating system facilities);
  • debug (debug facilities).

Each library, excluding the library and basic package has all the functions as the fields of global table or as methods of an objects.

Список литературы

  1. Official site Lua
  2. Users of Lua
  3. Articles about Lua
  4. Lua version 5.3 reference