GN⁺: Lua는 과소평가된 언어임
(nflatrea.bearblog.dev)- Lua의 설계와 구현을 배우면 배울수록 감명받음. 적은 코드로 많은 일을 수행하는 소프트웨어는 드물음
- 그러나 Lua는 다른 언어들만큼의 마케팅과 주목을 받지 못함. 이로 인해 Lua의 기능과 장점을 아는 개발자가 적음
- 주로 게임과 임베디드 시스템에서 사용되는 틈새 언어로 인식됨
[Lua의 특징과 장점]
이해하기 쉬운 언어
- Lua는 무료, 반사적, 명령형 스크립트 언어임. 1993년에 만들어졌으며, 다른 애플리케이션에 내장되어 확장 가능하도록 설계됨.
- 설계가 깔끔하고 코드가 빠름. C API는 사용하기 쉬우며, 성능이 좋음.
- 문법이 간결하고 미니멀리즘적이어서 초보자도 접근하기 쉬움.
뛰어난 임베딩 가능성
- Lua는 다른 언어, 특히 C와 C++로 작성된 애플리케이션에 쉽게 내장되도록 설계됨.
- 게임과 임베디드 애플리케이션의 스크립팅과 확장에 탁월한 선택임.
- 예: Lua를 C 프로그램에 임베드
#include <lua.h> #include <lauxlib.h> #include <lualib.h> int main() { lua_State *L = luaL_newstate(); luaL_openlibs(L); luaL_dofile(L, "./myscript.lua"); lua_close(L); return 0; }
다중 프로그래밍 패러다임 지원
- Lua는 독립적으로 또는 적절한 라이브러리와 함께 명령형, 함수형, 객체 지향 프로그래밍을 지원함.
- 사용자의 필요에 맞는 프로그래밍 스타일을 선택할 수 있는 유연성 제공
[Lua의 잠재적 단점]
인덱싱 관례
- Lua에서 인덱싱은 일반적으로 1부터 시작하지만, 이는 관례임. 배열은 0, 음수 또는 다른 값으로 인덱싱 가능함.
- Lua에는 실제로 배열이 없고, 항상 키-값 해시인 테이블만 존재하여 0 또는 음수 등 다양한 값으로 인덱싱
- 표준 라이브러리와 내장 함수는 인덱스가 1부터 시작하는 배열 같은 테이블을 가정함.
오류 처리
- Lua의 오류 처리는 다른 언어에서 온 개발자에게 직관적이지 않을 수 있음.
- Lua에서는 오류를 값으로 처리할 수 있음.
pcall
을 사용하여 오류를 잡을 수 있음.function risky_function() error("Something went wrong!") end local status, err = pcall(risky_function) if not status then print("Error: " .. err) end
Nil로 종료되는 배열
- Lua의 배열(배열로 사용되는 테이블)은 nil 값을 만나면 종료되며, 이는 예상치 못한 동작을 유발할 수 있음
local arr = {10, 20, 30, nil, 50} for i, v in ipairs(arr) do print(v) -- 출력: 10, 20, 30 (nil에서 중단) end
-
ipairs
함수는 nil 값을 만나면 반복을 중지함 - 배열에 빈 공간이 있을 경우
ipairs
대신pairs
를 사용하는 것이 좋음. nil 값을 포함한 모든 항목을 탐색 가능
[요약]
- Lua는 강력하고 효율적이며 다재다능한 프로그래밍 언어로, 더 많은 인정을 받을 자격이 있음.
- 단순함, 내장 가능성, 성능 덕분에 게임과 임베디드 시스템 같은 다양한 애플리케이션에 적합함.
- 저평가되었지만, 단순함과 성능 덕분에 시도해 볼 가치가 있음
- nvim의 플러그인 시스템에서 사용되며, 효율적임.
Lua에는 실제로 배열이 없고, 항상 키-값 해시인 테이블만 존재하여 0 또는 음수 등 다양한 값으로 인덱싱
와우 애드온 때문에 루아를 잠깐 써본 적 있는데 이 부분이 제일 인상 깊었던 기억이 납니다. 거의 모든 자료구조에 항상 테이블을 쓰더라구요.
개인적으로는 Ruby.. 보다는 '일단 옛날 코드가 켜지는가??' 라는 질문에는 좀 더 나은 편이지만, 특히 5.3에서 이전 버전과 number를 취급하는 방식이 달라져 5.1에서 5.3으로 올리면 내부적으로 트랙킹하기 어려운 버그가 잔뜩 생깁니다...
그리고 LuaJIT을 쓰는 곳도 많고 이건 또 인터페이스가 미묘하게 달라서 미묘하게 달라 생기는 문제가 가장 심각한 것 같아요. 내부 동작이 달라진 파트가 꽤 있어서 어떻게 할 수도 없고.. =ㅁ =.
루아로 스마트싱스의 엣지 드라이버를 작성한 경험이 있습니다.
그럭저럭 쓸 만은 했는데, 제 취향의 언어는 아니었습니다.
저는 개발 환경이나 DE도 언어의 일부라고 생각하는데요,
우선 커뮤니티의 분열이 좀 있는 것 같고
language server도 여러 가지가 있는데 기능이 하나씩 빠져있거나 코드 인덱싱이 늦고 수정이 발생하면 처음부터 다시 하더라고요.
1-base 인덱싱이나 주석으로 타입 힌트 작성하는 것도 별론데
타입 힌트도 표준이 있는 것이 아니라 language server마다 다른 듯했습니다.
코루틴도 구닥다리 파이썬의 그것을 떠올리게 합니다...
임베딩이나 FFI는 확실히 간편한 것 같긴 합니다.
요즘 sumneko 분이 만든 루아 랭귀지 서버가 죽입니다 'ㅁ '... (22년인가 23년에 만드셨어요) 요게 인덱싱이 꽤 센스가 좋더라고요
루아의 장점(이자 단점)은 아무래도 이상한 짓을 할 때 생긴다고 생각하는데, 터무니 없을 정도로 다른 오브젝트의 메서드를 overwrite 하기 쉽고. 그로 인해 마구잡이로, 생각나는데로 쓰기에 참 좋은 언어라고 생각해요.
타입 힌팅은... 말씀하신대로 나온 솔루션은 정말 많은데 제대로 정착한 솔루션은 거의 없어서 로블록스팀이 만든 luau에 기대를 걸고 있습니다..
Hacker News 의견
-
Lua는 임베딩하기에 좋지만, Redis에서 스크립팅 언어로 선택한 것은 후회가 많았음. 언어 자체가 마음에 들지 않음. 추상화 수준에서 기대하는 것과 비교해 마찰이 있는 것처럼 보임. 작은 설계 결정들이 누적되어 언어가 다소 적대적임. 그러나 빠르고, 통합이 쉽고, 작은 메모리 사용량과 신뢰성 때문에 여전히 선택할 가치가 있음. C-API 수준에서도 스택 접근 방식으로 인해 적대감이 존재함. FORTH와 같은 스택 언어에 노출된 적이 있지만 바인딩을 작성할 때 여전히 정신적 운동이 필요했음.
-
Lua를 좋아한다면 Terra를 보길 권장함. Terra는 Lua에 임베딩되고 메타 프로그래밍되는 저수준 시스템 프로그래밍 언어임. C/C++처럼 정적 타입, 컴파일 언어이며 수동 메모리 관리가 가능함. 그러나 C/C++과 달리 처음부터 Lua로 메타 프로그래밍되도록 설계됨. Terra 프로그램은 Apple의 C 컴파일러에 사용되는 동일한 LLVM 백엔드를 사용함. 이는 Terra 코드가 동등한 C 코드와 유사한 성능을 발휘함을 의미함.
-
Lua를 커스텀 게임 엔진과 통합하는 작업을 최근에 했으며, 다른 언어와의 통합이 얼마나 깔끔한지 공감함. 인터페이스가 깔끔하여 자동으로 바인딩을 생성하기 쉬움. Roslyn Incremental Source Generators를 사용하여 C#과 Lua 간의 바인딩을 자동으로 생성했으며, 인터페이스 설계 덕분에 전혀 어렵지 않았음. Lua 스택과 동적 타이핑, "테이블" 덕분에 C#과 Lua 간의 임의 데이터 클래스에 대한 마샬러를 생성하기 쉬웠음. 그러나 언어 자체에 대한 유효한 비판이 많음. 특히 1 기반 인덱싱을 좋아하지 않음. 이러한 문제를 해결하면서 유사한 인터페이스를 가진 임베디드 스크립팅 언어를 설계하는 것을 고려 중임.
-
Lua에 대한 애정이 더 생기지는 않았음. 오히려 불만이 강화되었음. Lua를 작성한 지 오래되었지만 직관적이지 않다고 생각했음. 왜 배열이 테이블인지, 왜 nil로 종료되며 1에서 시작하는지 이해할 수 없음. Lua가 과소평가되었다고 생각하지 않음. (구형) 게임 엔진에서 스크립트를 작성하는 데 매우 인기가 있음.
-
Lua 플러그인 명령어로 챗봇을 만들었지만 C++ 프로그램에 통합하는 데 끔찍한 경험을 했음. 사람들이 임베딩이 쉽다고 말하는 이유를 이해할 수 없음. 스택 조작을 많이 해야 함. 언어 자체가 번거롭고 실수를 했을 때 전혀 도움을 주지 않음. 다시는 Lua를 사용하지 않을 것이며 Lua를 사용하는 프로젝트를 피할 것임.
-
Lua는 약한 타이핑, 타입 힌트 및 오류 처리의 부재로 인해 상당한 양의 코드를 작성하기 어려움. 과소평가되지 않음. 시간이 지나면서 정적 타입 언어와 타입 힌트(Python, TypeScript)를 점점 더 좋아하게 되었음. 커뮤니티에 힌트 없는 Python이나 JS 코드를 작성하는 것은 해로움. 최근에 1.5k cloc의 JS를 TypeScript로 다시 작성했음. 항상 누락된 null, null 속성 접근 또는 의미적으로 의심스러운 null이 수십 건 있었음.
-
대부분의 스크립팅이 필요한 애플리케이션은 JavaScript를 임베딩해야 한다고 생각함. 기존 생태계에서 큰 이점이 있음. 사람들이 항상 좋아하지는 않지만 수백만 명이 이미 알고 있음. 배열 인덱싱과 nil 종료의 특이점과 Lua가 런타임에 알게 되는 수십 가지 다른 점을 다시 배울 필요가 없음. 모든 크기의 JS 엔진이 있으며, 대부분의 운영 체제는 설치 없이 접근 가능한 고품질 엔진과 임베딩 프레임워크를 제공함. 사용자에게 새로운 언어를 배우게 하는 대신 표준 언어를 사용하는 것이 좋음. 사용자와 자신 모두에게 시간을 절약할 수 있음.
-
Lua와 함께 작업하는 것을 즐겼으며 매우 좋은 언어라고 생각함. 특히 C/C++에 임베딩하는 인터페이스가 깔끔하고 유연함. 성능 문제는 있지만 고성능 비디오 게임에서 게임 로직에 Lua가 널리 사용되는 것을 고려할 때 이러한 문제는 해결 가능함. 그러나 혼란스럽고 언어를 어렵게 만드는 다른 문제들이 있음. Lua와 C 인터페이스를 배우는 것이 Lua를 배우는 것만큼이나 많기 때문에 배포 간 전환이 다른 언어보다 혼란스러움. 그럼에도 불구하고 언어가 과소평가되었다고 생각함.
-
Lua를 임베딩하는 것이 재미있었지만, wasm과 마찬가지로 전체 바이너리를 다시 컴파일하지 않고 새 코드를 실행해야 하는 경우가 거의 없었음. 가장 재미있었던 것은 C++로 게임 엔진을 만들고 모든 게임 로직에 Lua를 사용한 것이었음. 빠른 디버그 사이클이 매우 유용했음. 두 번째로 재미있었던 것은 Lua 로직을 다시 로드할 수 있는 IRC 봇을 만든 것이었음. 세 번째로 재미있었던 것은 Lua를 튜링 완전한 구성 언어로 사용하는 것이었음. 배열이 필요할 때 Lua로 배열을 만들었음. 가장 재미없었던 것은 3D 모델을 생성된 Lua로 내보내는 Blender 플러그인이었음.
-
Lua는 과대평가되었다고 생각함. 게임 산업에서 널리 사용되기 때문임. Lua의 유일한 장점은 C++에 쉽게 임베딩할 수 있다는 것임. 그 외에는 악몽임.