Lua
Lua（，葡萄牙语“月亮”）是一个简洁、轻量、可扩展的脚本语言。Lua有着相对简单的C API而很容易嵌入应用中。很多应用程序使用Lua作为自己的嵌入式脚本语言，以此来实现可配置性、可扩展性。
Lua是在1993年由罗伯托·耶鲁萨林斯希、Luiz Henrique de Figueiredo和Waldemar Celes创建的，他们当时是巴西的里约热内卢天主教大学的计算机图形技术组（Tecgraf）成员。Lua的先驱是数据描述/配置语言“SOL”（简单对象语言）和“DEL”（数据录入语言）。他们于1992年–1993年在Tecgraf独立开发了需要增加灵活性的两个不同项目（都是用于工程应用的交互式图形程序）。在SOL和DEL中缺乏很多控制流结构，需要向它们增加完全的编程能力。
在《The Evolution of Lua》中，这门语言的作者写道：
Lua主要受到了下列前辈语言的影响：
Lua在版本5.0之前在类似BSD许可证之下发行。自从版本5.0以来，Lua采用了MIT许可证。
Lua是一种轻量语言，它的官方版本只包括一个精简的核心和最基本的库。这使得Lua体积小、启动速度快。它用ANSI C语言编写，并以源代码形式开放，编译后的完整参考解释器只有大约247kB，到5.4.3版本，该体积变成283kB（Linux,amd64），依然非常小巧，可以很方便的嵌入别的程式裡。和许多“大而全”的语言不一样，網路通訊、图形界面等都没有預設提供。但是Lua可以很容易地被扩展：由宿主语言（通常是C或C++）提供这些功能，Lua可以使用它们，就像是本来就内置的功能一样。事实上，现在已经有很多成熟的扩展模块可供选用。
Lua是一个动态类型语言，支援增量式垃圾收集策略。有内建的，与操作系统无关的协作式多线程支援。Lua原生支援的数据类型很少，只提供了数值（默认是双精度浮点数，可配置）、布尔量、字符串、表格、函数、线程以及用户自定义数据这几种。但是其处理表和字符串的效率非常之高，加上元表的支援，开发者可以高效的模拟出需要的复杂数据类型（比如集合、数组等）。
Lua是一种多重编程范型的程式设计语言：它只提供了很小的一个特性集合来满足不同编程范型的需要，而不是为某种特定的编程范型提供繁杂的特性支援。例如，Lua并不提供继承这个特性，但是你可以用元表格来模拟它。诸如命名空间、类这些概念都没有在语言基本特性中实现，但是我们可以用表格结构（Lua唯一提供的复杂数据结构）轻易模拟。正是提供了这些基本的元特性，我们可以任意的对语言进行自需的改造。
Lua实现了少量的高级特征比如头等函数、垃圾回收、闭包、正当尾调用、强制（于运行时间在字符串和数值之间自动转换）、协程（协作多任务）和动态模块装载。
经典的Hello World!程序可以写为如下： print("Hello World!")
或者如下：
print 'Hello World'  print Hellow World 在Lua中注释可以于双连字符并行至此行的结束，类似于Ada、Eiffel、Haskell、SQL和VHDL。多行字符串和注释用双方括号来装饰。
下例中实现了一个阶乘函数：
function factorial(n) end
Lua有四种类型的循环：codice_2循环，codice_3循环（类似于codice_7循环），数值codice_8循环，和通用codice_8循环，和条件语句codice_10。 --condition = true
while condition do end
repeat until condition
for i = first, last, delta do --delta可以是负数，允许计数增加或减少的循环 end 通用codice_8循环：
for key, value in pairs(_G) do end
将在表格codice_12上使用标准迭代器函数codice_13进行迭代，直到它返回codice_14。
可以有嵌套的循环，就是在其他循环中的循环。 local grid = {
for y, row in ipairs(grid) do end
Lua将函数处理为头等值，在下例子中用print函数的表现可以修改来展示：
do end
任何对codice_15的进一步调用都要经由新函数，并且由于Lua的词法作用域，这个旧的print函数将只能被这个新的修改了的print访问到。
Lua还支持闭包，展示如下：
function addto(x) end fourplus = addto(4) print(fourplus(3)) -- 打印7
--这也可以通过如下方式调用这个函数来完成： print(addto(4)(3)) --这是因为这直接用视件参数3调用了从addto(4)返回的函数。
每次调用的时候为变量codice_16建立新的闭包，所以返回的每个新匿名函数都访问它自己的codice_16参数。闭包由Lua的垃圾收集器来管理，如同任何其他对象一样。 function create_a_counter() end
create_a_counter()會返回一個匿名函数，這個匿名函數會把count加1後再回傳。在匿名函數中的變數count的值會一直被保存在匿名函數中。因此调用create_a_counter()时产生一个记数器函数，每次调用记数器函数，都会得到一个比上次大1的值。
Lua是一种动态类型语言，因此语言中没有类型的定义，不需要声明变量类型，每个变量自己保存了类型。
有8种基本类型：nil、布尔值（boolean）、数-{}-字型（number）、字符串型（string）、用户自定义类型（userdata）、函数（function）、线程（thread）和表（table）。 print(type(nil)) -- 输出 nil print(type(99.7+12*9)) -- 输出 number print(type(true)) -- 输出 boolean print(type("Hello Wikipedia")) -- 输出 string print(type(print)) -- 输出 function print(type({1, 2, test = "test"})) -- 输出 table
表格（table）是Lua中最重要的数据结构（并且是设计中唯一内建的复合数据类型），并且是所有用户创建类型的基础。它们是增加了自动数值键和特殊语法的关联数组。
表格是键和数据的有序对的搜集，其中的数据用键来引用；换句话说，它是散列异构关联数组。
表格使用codice_18构造器语法来创建。 a_table = {} -- 建立一个新的空表格 表格总是用引用来传递的（参见传共享调用）。
键（索引）可以是除了codice_14和NaN的任何值，包括函数。 a_table = {x = 10} -- 建立一个新表格，具有映射"x"到数10的一个表项。 print(a_table["x"]) -- 打印于这个字符串关联的值，这里是10。 b_table = a_table b_table["x"] = 20 -- 在表格中的值变更为20。 print(b_table["x"]) -- 打印20。 print(a_table["x"]) -- 还是打印20，因为a_table和b_table都引用相同的表格。 通过使用字符串作为键，表格经常用作（或记录）。由于这种用法太常见，Lua为访问这种字段提供了特殊语法。 point = { x = 10, y = 20 } -- 建立一个新表格 print(point["x"]) -- 打印10 print(point.x) -- 同上一行完全相同含义。易读的点只是语法糖。 通过使用表格来存储有关函数，它可以充当名字空间。
Point.new = function(x, y) end
Point.set_x = function(point, x) end 表格被自动的赋予了数值键，使得它们可以被用作。第一个自动索引是1而非0，因为很多其他编程语言都这样（尽管显式的索引0是允许的）。
数值键codice_20不同于字符串键codice_21。 array = { "a", "b", "c", "d" } -- 索引被自动赋予。 print(array[2]) -- 打印"b"。在Lua中自动索引开始于1。 print(#array) -- 打印4。#是表格和字符串的长度算符。 array[0] = "z" -- 0是合法索引。 print(#array) -- 仍打印4，因为Lua数组是基于1的。 表格的长度codice_22被定义为任何整数索引codice_23，使得codice_24不是codice_14而codice_26是codice_14；而且如果codice_28是codice_14， codice_23可以是0。对于一个正规表格，具有非nil值从1到给定codice_23，它的长度就精确的是codice_23，它的最后的值的索引。如果这个数组有“洞”（就是说在其他非nil值之间的nil值），则codice_33可以是直接前导于codice_14值的任何一个索引（就是说可以把任何这种nil值当作数组的结束）。 ExampleTable = print(ExampleTable[1][3]) -- 打印"3" print(ExampleTable[2][4]) -- 打印"8" 表格可以是对象的数组。 function Point(x, y) -- "Point"对象构造器 end array = { Point(10, 20), Point(30, 40), Point(50, 60) } -- 建立point的数组 print(array[2].y) -- 打印40 使用散列映射来模拟数组通常比使用真正数组要慢；但Lua表格为用作数组而做了优化来避免这个问题。
可扩展的语义是Lua的关键特征，而“元表格”概念允许以强力方式来定制Lua的表格。下列例子展示了一个“无限”表格。对于任何codice_23，codice_36会给出第codice_23个斐波那契数，使用了动态规划和记忆化。
fibs = { 1, 1 } -- 给fibs[1]和fibs[2]初始值。 setmetatable(fibs, {
尽管Lua没有内建的类的概念，可以用过两个语言特征实现面向对象编程：头等函数和表格。通过放置函数和有关数据入表格，形成一个对象。继承（单继承和多重继承二者）可以通过使用元表格机制来实现，告诉这个对象在哪些父对象中查找不存在的方法。
对于这些技术不采用“类”的概念，而是采用原型，类似于Self或JavaScript。建立新对象要么通过工厂方法（从头构造一个新对象）要么通过复制现存的对象。
建立一个基本的向量对象：
Vector.__index = Vector
function Vector:new(x, y, z) -- 构造器 end
function Vector:magnitude() -- 另一个方法 end
local vec = Vector:new(0, 1, 0) -- 建立一个向量 print(vec:magnitude()) -- 调用一个方法 (输出: 1) print(vec.x) -- 访问一个成员变量 (输出: 0) Lua为便利对象定向提供了一些语法糖。要声明在原型表格内的成员函数，可以使用，它等价于。调用类方法也使用冒号，等价于。
下面是使用语法糖的对应的类： Vector.__index = Vector
function Vector:new(x, y, z) -- 构造子 end
function Vector:magnitude() -- 另一个方法 end
local vec = Vector:new(0, 1, 0) -- 建立一个向量 print(vec:magnitude()) -- 调用方法（输出：1） print(vec.x) -- 访问成员变量（输出：0） Lua支持使用元表格来使得Lua具有类继承。在这个例子中，我们允许向量在派生的类中将它们的值乘以一个常量： Vector.__index = Vector
function Vector:new(x, y, z) -- 构造子 end
function Vector:magnitude() -- 另一个方法 end
-- 类继承的例子 VectorMult.__index = VectorMult setmetatable(VectorMult, Vector) -- 使得VectorMult成为Vector的孩子
function VectorMult:multiply(value)  end
local vec = VectorMult:new(0, 1, 0) -- 建立一个向量 print(vec:magnitude()) -- 调用一个方法（输出：1） print(vec.y) -- 访问一个成员变量（输出：1） vec:multiply(2) -- 将向量的所有分量乘以2 print(vec.y) -- 再次访问成员变量（输出：2） Lua还支持多重继承，可以要么是一个函数要么是一个表格。运算符重载也可以进行，Lua元表格拥有元素比如、，诸如此类。
Lua程序不是从文本式的Lua文件直接解释的，而是编译成字节码，接着把它运行在Lua虚拟机上。编译过程典型的对于用户是不可见并且是在运行时间进行的，但是它可以离线完成用来增加装载性能或通过排除编译器来减少对宿主环境的内存占用。Lua字节码还可以在Lua之内产生和执行，使用来自字符串库的codice_38函数和codice_39函数。Lua版本5.3.4是用大约24,000行C代码实现的。
像大多数CPU，而不像多数虚拟机（它们是基于堆栈的），Lua VM是基于寄存器的，因此更加类似真实的硬件设计。寄存器架构既避免了过多的值复制又减少了每函数的指令的总数。Lua 5的虚拟机是第一个广泛使用的基于寄存器的纯VM。Parrot和Android的Dalvik是另外两个周知的基于寄存器的VM。PCScheme的VM也是基于寄存器的。
下面的例子列出上面定义的阶乘函数的字节码（通过codice_40 5.1编译器来展示）：
Lua意图被嵌入到其他应用之中，为了这个目的而提供了C API。API被分成两部份：Lua核心库和辅助库。Lua API的设计消除了对用C代码的手动引用管理的需要，不同于Python的API。API就像语言本身一样是极简主义的。高级功能通过辅助库来提供，它们很大程度上构成自预处理器宏，用以帮助做复杂的表格操作。
Lua C API是基于堆栈的。Lua提供压入和弹出最简单C数据类型（整数、浮点数等）进入和离开堆栈的函数，还有通过堆栈操作表格的函数。Lua堆栈稍微不同于传统堆栈，例如堆栈可以直接的被索引。负数索引指示从栈顶开始往下的偏移量。例如−1是在顶部的（最新进压入的值），而整数索引指示从底部（最旧的值）往上的偏移量。在C和Lua函数之间集结数据也使用堆栈完成。要调用一个Lua函数，把实际参数压入堆栈，并接着使用codice_41来调用实际的函数。在写从Lua直接调用的C函数的时候，实际参数读取自堆栈。
下面是从C调用Lua函数的例子:
int main(void)
如下这样运行这个例子： C API还提供一些特殊表格，位于各种Lua堆栈中的“伪索引”之上。Lua 5.2之前，在codice_42之上是全局表格；codice_12来自Lua内部，它是主名字空间。还有一个注册表位于codice_44，在这里C程序可以存储Lua值用于以后检索。
还可以使用Lua API写扩展模块。扩展模块是通过向Lua脚本提供本地设施，用来扩展解释器的功能的共享对象。从Lua方面看来，这种模块出现为一个名字空间表格，它持有自己的函数和变量。Lua脚本可以使用codice_45装载扩展模块，就像用Lua自身写的模块一样。一组仍在增长中的叫做“rock”的模块可以通过叫做的软件包管理器获取到，类似于CPAN、RubyGems和。对大多数流行的编程语言包括其他脚本语言，都存在预先写好的Lua绑定。对于C++，有许多基于模板的方式和一些自动绑定生成器。
在视频游戏开发中，Lua被程序员广泛的用作脚本语言，主要由于它的可感知到的易于嵌入、快速执行，和短学习曲线。
在2003年，GameDev.net组织的一次投票，说明了Lua是游戏编程的最流行脚本语言。在2012年1月12日，Lua被《》宣布为编程工具范畴的Front Line奖2011年度获奖者。
大量非游戏应用也出于可扩展性而使用Lua，比如TeX排版设置语言实现LuaTeX、键-值数据库Redis、文本编辑器Neovim和web服务器Nginx。
通过Scribunto扩展，Lua可获得为MediaWiki软件中的服务器端脚本语言，Wikipedia和其他wiki都基于了它。它的应用包括允许从Wikidata集成数据到文章中，和助力于。
Lua可以用於嵌入式硬體，不僅可以嵌入其他編程語言，而且可以嵌入微處理器中，例如NodeMCU開源硬體項目將Lua嵌入到Wi-Fi SoC中，另外，遊戲平台Roblox所有遊戲都是利用Lua進行編程的。另外, 还有中国大陸发起的开源 LuatOS 项目, 也是将Lua应用到嵌入式领域, 但不仅限于Wifi, 它包含2G/4G/NBIOT等通信模块,也包含stm32/w800等嵌入式mcu,同时也支持在windows/linux平台上执行的模拟器.