Lua

1. 개요
2. 언어적 특징
2.1. 가벼움
2.2. 문법적 특징
2.3. 테이블
2.5. 파편화
2.6. Python과의 비교
2.7. JavaScript와의 비교
3. 용도
3.1. 실제 사용 예

#!syntax javascript
print("Hello, world!")

Lua (루아)

http://www.lua.org/

1. 개요

1993년에 개발된 프로그래밍 언어. 브라질 리우데자네이루의 교황청대학교에서 호베르투 예루잘링스키[1] 및 2명이 공동제작했으며 이름도 달을 의미하는 포르투갈어 단어에서 따왔다. 스크립트 언어를 하나의 목적으로 가지고 있기 때문에 굉장히 작고 가벼운 인터프리터형 언어이다. 현재 안정버전은 5.3이고 5.4 버전을 테스트 중이다.[2]

태생 자체가 C/C++ 프로그램 내부에 포함(embed)시키기 매우 쉬운 깔끔한 문법의 가벼운 스크립트 언어를 목표로 개발되었다. 교황청대학교 컴퓨터 그래픽 기술 연구소(Tecgraf)에서 내부적으로 개발해서 사용하던 기존의 데이터 처리용 스크립팅 언어 SOL과 DEL의 한계를 극복할 더 강력한 언어가 요구되었다고 한다.[3]

2. 언어적 특징

2.1. 가벼움

인터프리터(또는 후술한 JIT 컴파일러)의 용량이 일백 수십KB[4] 정도로 작고 굉장히 빠르다. 그 흔한 정수도 없을 정도로[5] 굉장히 적은 수의 데이터형만을 지원하긴 하지만 그만큼 가볍다. 다양한 프로그램에 쉽게 붙일 수 있는 이유도 용량과 속도의 부담이 적기 때문. 그러면서도 다양한 패러다임을 가지고 있는데, 절차적으로도, 객체지향적으로도, 함수형으로도 이용할 수 있다.

2.2. 문법적 특징

언어의 문법이 굉장히 단순한 편이다. 다만, C 스타일의 언어들과 비교했을 때 다른 점이 많다는 것이 특징이다.

  • Lua에서는 null이 아닌 nil
  • 진리값은 boolean type 이 있어서 true 는 참, false 는 거짓이다. boolean 이 아닐 경우 nil이 거짓이고 나머지는 모두 true 이다. 그래서 C 와는 달리 0 도 true이다.
  • 기본적인 자료형은 nil, boolean, number, string, function, table, userdata, thread
  • ==의 반대 연산자로 보통은 !=, <>등을 많이 사용하는데, Lua에서는 ~=
  • 논리연산자도 타 언어에서 !, &&, ||등을 사용하는데 lua에서는 단어 그대로 not, and, or로 쓴다.
  • bitwise 연산자는 Lua 5.3에서 추가되었다. &, |, ~(binary: bitwise xor), >>, <<, ~(unary: bitwise not)
  • ^xor 관련이 아닌 pow, 즉 거듭제곱
  • A+=B 같은 꼴은 지원하지 않으며 무조건 A = A + B 처럼 작성해야한다.
  • 문자열 합치기는 ..
  • self라는 예약어 아닌 예약어가 존재.[6]
  • 반복제어문에 continue가 없다.
  • goto가 있다.
  • 1 based index다.
  • 함수를 정의하는게 아니라 함수를 만들어 변수에 대입하는 방식으로 작성이 가능(이는 JavaScript도 동일하다).
  • 기본 자료형에 thread 타입이 있으나, 실제로는 coroutine이다.
  • 문자열 패턴 매칭이라는 정규표현식과 유사한 기능을 지원한다. 다만, 정규식과 많이 다르고 기능도 부족하긴하다.

2.3. 테이블

다른 언어의 배열과는 다르게 다양한 자료형을 키로 사용가능한데, 이것을 가지고 단순한 구조체, 배열 뿐만 아니라 객체, 클래스, 인터페이스 등을 다 구현해 낼 수 있다. 사실 Lua의 테이블은 단순히 저장하는 것이 아니라 메타테이블과 같이 써서 테이블에 기능을 붙일 수 있기 때문이다. 그래서 Lua를 잘 다루려면 테이블과 메타테이블을 잘 다룰 수 있어야 한다.

2.4. 함수형 프로그래밍

Lua도 일단은 함수형 프로그래밍이 어느정도 된다. 함수를 익명함수로 생성할 수도 있고 전달할 수도 있다(JavaScript에서 지원하는 정도와 비슷하다). 그리고 사실 파일로 저장해서 불러오는 스크립트 자체가 함수다. 대신 성능을 위해서 스택의 크기가 고정되어 있기 때문에 어떤 함수든지 지역변수를 200개 이상 만들 수가 없다. 대신 전역범위에 저장하는 _G라는 테이블이 존재한다.

클로저와 익명함수를 지원한다.[7]

2.5. 파편화

중요한 Lua 커뮤니티 파편화가 시작되었다. Lua 5.3버전이 64비트 부동소수점 타입[8]을 명확히 지원하기 위해서 정수형 타입을 도입한 것이 기존의 Lua코드와 호환성 문제를 일으키게 된 것이다.[9] 게다가 LuaJIT을 개발하고 사실상 혼자 유지보수하던 Mike Pall이 앞의 정수형 문제와 기타 몇 가지 이유를 더 들어 5.3 버전을 공개적으로 크게 비판하고 LuaJIT은 Lua 5.1까지만 지원하고 자신은 더이상 개발에 관여하지 않겠다고 선언해서 문제가 매우 복잡해졌다.[10] 때문에 LuaJIT에 의존해 성능 향상을 꾀하던 대다수의 Lua 라이브러리가 Lua 5.1까지만 지원하고 후속 개발이 진행되지 않는 사태에 이르렀다. 현재 Lua 커뮤니티는 순정 5.3 인터프리터로도 충분한 상황의 개발자와, LuaJIT과 기타 라이브러리가 꼭 필요한 개발자들로 양분되어버렸다. 파이썬이 파이썬2와 파이썬3로 나뉘어 파편화가 진행되어 10년이 지난 지금까지 해결이 되지 않은 것과 비견된다.

2.5.1. JIT

LuaJIT는 Lua의 Just-In-Time Compiler인데, 엄청난 장점으로 타 JIT와 비교해도 더 우수한 성능을 보여준다. 주 비교 대상은 V8인데, 자료구조 성능을 제외하면 전반적으로 Lua 쪽이 성능이 더 좋다. 파이썬, 루비와 비교하면 수십배 정도가 더 빠르다.

JavaScript와 Lua는 문법과 패러다임이 90% 이상 비슷한 사촌언어격이지만 JIT 성능의 구현 측면에 있어서는 JavaScript가 가진 문법 일부가 성능 향상에 약점으로 작용한다고 한다. 참조 또한 메모리 사용량에 있어서 LuaJIT이 더 나은 최적화를 보여주고 있다. 따라서 Node.js를 LuaJIT 기반으로 다시 작성한 Luvit이라는 프로젝트가 활성화되었다.

홈페이지에 따르면 인터프리터를 손수 어셈블리어로 작성했으며, 이미 상당한 수준의 최적화가 되어있다고 한다. 파이썬의 JIT 컴파일러인 PyPy가 자기 자신으로 JIT을 구현하는 것과 대조되는 부분. Lua가 그나마 단순한 언어라 이런 일이 되는 듯하다.

이 때문인지 업데이트가 자주 되는 편은 아닌데, Lua 5.3이 나오고 있는 동안에도 LuaJIT은 Lua 5.1 문법이 최신이다[11]

또한, 안 그래도 손쉬운 C와의 인터페이스 작업은 LuaJIT의 FFI(Foreign Function Interface)를 이용하면 Low-Level C 함수들을 별다른 작업 없이 직접적으로 사용할 수 있다. 이 FFI 방식으로 인해 스크립트 - 네이티브 코드 간 호출규약을 맞추기 위한 별도의 작업이 사실상 필요가 없어지고, C 자료형을 직접 사용할 수 있게 되며 호출 성능은 네이티브에 견줄만큼 빨라지기 때문에, 일단 JIT을 사용하게 되면 기존 Lua 바인딩 코드를 사용할 일이 극히 적어진다. 이 FFI 방식은 이후 파이썬의 CFFI 라이브러리에 많은 영감을 주었다(Node.js의 node-ffi도 상당한 영향을 받은 것으로 추정된다).

네이티브에 견줄만큼 속도가 빠르고, 메모리 사용량이 매우 적기 때문에 최근 NGINX에 LuaJIT을 포함시켜서 커스터마이징을 한 OpenResty 웹 서버가 인기를 끌고 있다. CDN 서비스로 유명한 Cloudflare와 알렉사 Top 13 규모의 세계에서 가장 큰 C2C 상거래 서비스(지마켓/옥션을 생각하면 된다)인 타오바오에서 주-웹서버로 사용하고 있으며 두 회사의 개발자들이 OpenResty 개발을 주도하고 있다(단 Cloudflare의 CDN 서비스는 사실 NGINX에 LuaJIT으로 코드를 올려 커스터마이징한 서비스들이다. 그래서 타사와 달리 진정한 CDN 서비스가 아니라는 비평도 있다).

알파고로 유명한 DeepMind 사가 알파고의 기반인 Q-Learning을 구현할 때 사용된 Torch 머신러닝 미들웨어도 LuaJIT으로 작성되어 있다(DeepMind 사의 구인공고는 그래서 C/C++와 Lua 스크립트가 필수역량으로 적혀있다).

2.6. Python과의 비교

파이썬과 자주 비교가 되는데, 두 언어의 초기 개발 목표의 차이가 현재의 두 언어가 갖는 거의 모든 차이의 원인이라고 볼 수 있다. 파이썬은 깨끗한 문법의 고급(high-level) 범용(general) 프로그래밍언어가 개발 목표였고 부수적으로 다른 언어와의 쉬운 접착(glue) 기능이 제공되는 반면에, Lua는 C/C++ 프로그램에 내포(embed)되는 것을 기본 사용례로 가정하고 개발되었고 부수적으로 고급(high-level) 범용(general) 프로그래밍 언어로도 사용할 수 있는 것이다. 즉, 인터프리트형 스크립트 언어라는 공통점을 제외하면 강조하고 있는 점이 거의 정반대이다. 그리고 파이썬이 접착(gluing)이 쉬운 언어이지 내포(embedding)가 쉬운 언어는 아니라는 점도 주목할 만하다.

따라서 파이썬 커뮤니티에서 잘 쓰이는 표현대로 '배터리가 포함된'[12] 파이썬은 어느정도 단독으로 프로그램을 만들 수 있는 환경인 반면, Lua는 기본중의 기본 기능만을 포함하고 있어 단독으로 응용프로그램을 만들려면 손에 꼽히는 외부 라이브러리[13]를 포함하고도 이것저것 직접 구현해야 하는 어려움이 있다. 너무 없으면 불편하다보니 배터리가 포함된 LuaDist나 Lua for Windows같은 프로젝트도 배포되고있다.

물론 관점을 바꾸어서 C/C++ 프로그램에 내포할 때를 가정하면, 파이썬은 기본으로 import되는 라이브러리[14]가 많아 메모리 사용량이 큰데 비해 사실상 아무것도 없어 극도로 가볍고 빠른 것이 Lua의 장점이라고 하겠다.[15]

그리고 파이썬 커뮤니티에서도 Lua와 비교해서 embedding 기능쪽으로 부족함을 인지하고, 최근 영역 확장을 시도하고 있다. 파이썬이 스크립트용으로 내포된 유명한 프로그램으로는 3dx Max, Blender가 있다. 둘 다 그 자체로 덩치 큰 프로그램[16]

2.7. JavaScript와의 비교

굉장히 유사한 면이 많은 두 언어다. 둘 다 JIT도 있다는 것도 유사한 점이다. 그래서 JavaScript에 있는 것을 Lua로 옮기는 경우도 있는데 예로 Node.js를 Lua로 옮긴 Luvit이라든가...

3. 용도

  • Lua를 내포할 경우에 C/C++ 프로그램 개발 과정에서 재컴파일이나 리로딩없이 바로 설정 변화를 적용할 수 있게 되는 점 때문에 특히 게임업계에서 많이 쓰인다.
  • 개발의 편의를 위해서 Lua를 내부적으로 활용하는 일 이외에도, 아예 게임 코드를 Lua로 작성하는 경우도 있다. 예를 들면 RPG 게임 등에서 개별 NPC의 AI나 기타 행동 정의를 위한 스크립트로도 쓰이고 있다.
  • API를 유저들에게 공개하여 MOD 제작이나 게임의 커스텀 UI 설정 스크립트 언어로 쓰이기도 한다.

3.1. 실제 사용 예

Lua가 쓰인 게임 목록

  • 고전 게임인 원숭이 섬의 비밀 시리즈의 개발 언어가 SCUMM에서 Lua로 변경되면서, 게임 내에 자주 등장하는 술집인 SCUMM bar가 Lua bar로 개명된 것은 유명한 개그다. Lua가 프로그래머들(특히 게임 프로그래머들) 사이에서 인기를 끌게된 시작점이다.
  • 월드 오브 워크래프트에서 유저들이 UI를 직접 제작할 수 있게 되면서 일반 게이머들에게도 인지도를 얻었다. Lua가 국내외의 일반 게이머들에게 널리 알려지게된 시작점이다. 월드 오브 워크래프트의 커다란 성공 덕분에, Lua를 월드 오브 워크래프트 전용 스크립트 언어로 착각한 국내외의 게이머가 매우 많다.
  • 라그나로크 온라인에서 NPC의 AI와 호문클루스의 AI, 용병의 AI에 Lua가 쓰였으며, 이 가운데 호문클루스와 용병은 유저가 직접 변경이 가능했다(아직도 되는지 확인 바람). 3차 직업군이 등장할 즈음에 용병의 AI를 변경하여 거의 0프레임 수준의 스킬이 가능하다는게 여기저기 알려져 너도 나도 창용병 무명섬 3층 고고싱을 외친 적이 있다.
  • 게리 모드에서도 Lua를 지원하고, 일부 소스 엔진 기반 게임(또는 모드)들도 Lua를 사용한다.
  • GTA 4에도 Lua 스크립트 모드가 있다. GTA 산 안드레아스의 멀티플레이어의 하나인 MTA: San Andreas의 서버를 작성한 언어다. TAS 영상을 만드는 데에도 일부 사용한다.
  • 한게임에서 제공중인 오픈 마켓형 게임 툴인 아이두게임의 기본 언어. 초보 프로그래머들을 위해서 배려를 해준 것이라고.
  • 마인크래프트의 모드 컴퓨터크래프트의 프로그램을 작성한 언어.
  • 로블록스(Roblox)의 모든 게임이 이 루아 기반으로 돌아간다. 여담으로 로블록스의 핵(스크립트)은 게임 내 시스템을 변형시켜야 하기 때문에 이도 루아로 작성된다.
  • 2015년에는 Corona sdk라는 게 나온 덕분에 Lua만 배워서 게임 하나 뚝딱 만들어 내는 게 가능해졌다. 2015년 12월 기준으로 iOS, 안드로이드 모두 지원된다.
  • Love2d라는 C++(SDL)에 접착시켜 만든 게임 개발 프레임워크가 Lua를 사용해 코딩한다. Not Tetris 2, Not Pacman, 포탈 마리오 등 꽤나 흥행한 게임들을 탄생시켰지만 인지도가 그닥 높지 않다. 한국에는 커뮤니티조차 없다
  • 피니엔진이 cocos 2d-x의 Lua 모듈을 통해 개발되었다. 자체 스크립트인 LNX 스크립트 또한 컴파일 과정을 통해 Lua 코드로 변환한 뒤 사용된다.
  • 스텝매니아에서도 Lua를 사용하여 기믹패턴을 만들 수 있다. 기존의 XML방식의 스크립트에서 간소화가 된것 영문 설명 링크
  • 게임 크루세이더 킹즈에도 쓰였다.
  • 스타크래프트1 유즈맵 편집기인 SCM draft 2의 플러그인 TEP의 기반언어다.
  • 네코랜드 스튜디오의 스크립트로 Lua를 사용한다.
  • 자막 제작용 소프트웨어인 Aegisub에서도 Lua 스크립트를 응용해 자동화 기능을 사용할 수 있다.
  • Lua를 Java로 만든 Luaj를 이용해 자바에서 직접 Lua 5.1 스크립트를 실행시킬 수 있다! 단점은 관련 정보가 적다는 것. Lua 5.3을 Java에 심기 위해 만든 Rembulan도 있다.
  • Ti-nSpire 계산기의 프로그래밍 언어다. 공학용 계산기는 복수 프로그래밍 언어를 지원하는 경우가 많은데, Ti사 제품의 경우 Lua, C언어, Ti-BASIC 등의 언어를 지원한다. Lua의 경우 컴퓨터로 프로그래밍해서 nSpire으로 보내는 방법으로 프로그래밍한다.
  • 아이패드로 코딩해서 만든 Lua 개발 툴도 있다. 이름은 공개 당시 Codify, 현재 Codea이다. 정확히는 Lua를 기반으로 사용하지만 앱내에서 개별적으로 함수나 API 등을 제공한다.
  • 파우더 토이의 스크립트와 MOD는 Lua로 작성된다.
  • 심시티 4의 일부 특수 건물 기능이나 운전 미션은 Lua 스크립트로 작성되어 있다. 그러나 플러그인 dat 파일 안에 저장되어 있어 열거나 편집하려면 별도의 에디터가 필요하다.
  • Command: Modern Air / Naval Operations에서 시나리오를 제작할 때 여러 방면으로 사용한다. 예를 들면 헬기나 수송기에서 병력을 내리는 것도 수송작전이 정식으로 패치되기 전까지는 정상적인 방법으로 불가능했기 때문에 시나리오 제작자가 Lua 스크립트를 이용해야 했다.
  • 스타크래프트 리마스터 맵 에디터에서 유즈맵 제작시 SCM Draft로 작업할때 트리거의 노가다를 획기적으로 줄여주는 플러그인을 사용할 수 있는데 이것이 Lua언어로 작성된다.
  • Wireshark 플러그인 제작에 사용된다.
  • Cheat Engine 스크립트 제작에 사용된다.

  1. [1] Roberto Ierusalimschy. 1960년생으로 컴퓨터과학자이며 상단의 리우 교황청 대학과 스탠포드 대학에서 부교수로 역임한 적이 있다. 위키백과에선 성씨를 이에루잘림스시(...)라고 표기하고 있다
  2. [2] 2018.06.18. Lua 5.4 work 2
  3. [3] The evolution of Lua
  4. [4] 상대적으로 덩치가 큰 LuaJIT조차 300KB 정도 된다.
  5. [5] 5.3버전에 정수가 추가되었다. 이때문에 Lua 커뮤니티 파편화가 진행중이다. 아래 참고.
  6. [6] 예약어(reserved keywords)로 분류되지는 않지만, 콜론을 사용한 함수 호출시에 self 변수를 다른 OOP 언어에서 제공하는 this나 self 변수처럼 함수 안에서 사용이 가능하다
  7. [7] 엄밀히 말하면 Lua에는 클로저만 존재하고, 나머지는 syntactic sugar.
  8. [8] 요즘 C/C++의 double은 대개 IEEE754표준 64비트 부동소수점 타입
  9. [9] 기본 숫자 타입은 여전히 number 뿐이다. math.type()을 통해서 서브 타입을 확인해야만 64비트 부동소수점 타입인 경우에는 double이라고 할 것이지 헷갈리게 float, 정수형인 경우에는 integer라고 구분되어 표시된다.
  10. [10] 이후에 사람들이 대체 maintainer를 공개모집했으나 적당한 사람을 찾는데 실패했다.
  11. [11] 전술한 대로 주요 개발자 Mike Pall이 개발 포기를 선언했다.
  12. [12] 기본으로 포함된 라이브러리가 기능이 풍부해 다른 외부 모듈이 필요없다는 뜻.
  13. [13] 주로 LuaRocks에서 구할 수 있다.
  14. [14] embedding 상황에서는 잘 쓰이지 않는 것들도 기본 라이브러리에 많이 들어있다.
  15. [15] 파이썬 개발자가 작성한 다음의 논의를 참고. embedding이라는 분야만 한정했을 때 Lua가 더 직관적임을 설명하고 embedding 목적으로 파이썬을 꼭 써야 한다면 생각해볼 수 있는 대안을 제안하고 있다.
  16. [16] Lua를 직접 언급하며 파이썬도 이쪽으로 좀 더 잘 할 수 있지 않을까 논의하는 영상: The Future of Python

최종 확인 버전:

cc by-nc-sa 2.0 kr

Contents from Namu Wiki

Contact - 미러 (Namu)는 나무 위키의 표가 깨지는게 안타까워 만들어진 사이트입니다. (94.33ms)