Luaは過小評価されている言語
(nflatrea.bearblog.dev)- Luaの設計と実装について学べば学ぶほど感銘を受ける。少ないコードで多くのことを実現するソフトウェアはまれ
- しかし Lua は他の言語ほどマーケティングや注目を集めていない。このため、Lua の機能や利点を知る開発者は少ない
- 主にゲームや組み込みシステムで使われるニッチな言語として認識されている
[Luaの特徴と利点]
理解しやすい言語
- Luaは無料で、リフレクティブな命令型スクリプト言語。1993年に作られ、他のアプリケーションに組み込んで拡張できるよう設計されている。
- 設計はクリーンで、コードは高速。C API は使いやすく、性能も高い。
- 文法が簡潔でミニマルなため、初心者でも取り組みやすい。
優れた埋め込み適性
- Luaは他の言語、特に C や C++ で書かれたアプリケーションに簡単に組み込めるよう設計されている。
- ゲームや組み込みアプリケーションのスクリプティングと拡張にとって優れた選択肢。
- 例: CプログラムにLuaを埋め込む
#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) -- output: 10, 20, 30 (stops at nil) end ipairs関数は nil 値に出会うと反復を停止する- 配列に空きがある場合は
ipairsの代わりにpairsを使うのがよい。nil 値を含めたすべての項目を走査できる
[要約]
- Luaは強力で効率的、かつ多用途なプログラミング言語であり、もっと高く評価されるに値する。
- シンプルさ、埋め込みやすさ、性能のおかげで、ゲームや組み込みシステムのようなさまざまなアプリケーションに適している。
- 過小評価されているが、シンプルさと性能のおかげで試してみる価値がある
- nvimのプラグインシステムで使われており、効率的。
7件のコメント
> Luaには実際には配列がなく、常にキー・バリューのハッシュであるテーブルだけが存在し、0や負数などさまざまな値でインデックスできる
WoWアドオンのためにLuaを少し触ったことがあるのですが、この部分がいちばん印象的だった記憶があります。ほとんどすべてのデータ構造に常にテーブルを使っていたんですよね。
Luaという名前だけは知っていましたが、この記事を見て、あまり良くないと思うようになりました(笑)..
詳しくは分かりませんが、バージョンの下位互換性がひどいという話を聞きました..
個人的には、Ruby.. よりは「とりあえず古いコードが動くか??」という問いに対してはもう少しマシなのですが、特に5.3では以前のバージョンと
numberの扱い方が変わっていて、5.1から5.3に上げると内部的にトラッキングしにくいバグが大量に発生します...それにLuaJITを使っているところも多いですし、これはまたインターフェースが微妙に違うので、その微妙な違いから生じる問題がいちばん深刻な気がします。内部動作が変わった部分もかなりあるので、どうしようもなくて.. =m =.
LuaでSmartThingsのEdgeドライバーを書いた経験があります。
そこそこ実用にはなりましたが、自分の好みの言語ではありませんでした。
私は開発環境やDEも言語の一部だと考えているのですが、
まずコミュニティにやや分裂があるように感じますし、
language serverもいくつかありますが、機能が一つずつ欠けていたり、コードのインデックス作成が遅く、修正が入ると最初からやり直したりします。
1始まりのインデックスやコメントで型ヒントを書くのもいまひとつですし、
型ヒントにも標準があるわけではなく、language serverごとに違うようでした。
コルーチンも、古いPythonのそれを思い出させます……
埋め込みやFFIは、たしかに手軽だとは思います。
最近、sumneko さんが作った Lua の言語サーバーがすごいです
'ㅁ '...(22年か23年に作られたはずです)これのインデックス機能がかなり気が利いているんですよね。Lua の長所(であり短所) は、やはり変なことをするときに出ると思っていて、とんでもないレベルで他のオブジェクトのメソッドを上書きしやすいんです。だからこそ、かなり雑に、思いつくままに書くのにとても向いている言語だと思います。
型ヒンティングは……おっしゃる通り出てきたソリューションは本当に多いのですが、きちんと定着したものはほとんどないので、Roblox チームが作った luau に期待しています……
Hacker Newsの意見
Lua は埋め込みに適しているが、Redis がスクリプト言語として選んだことにはかなり後悔があった。言語自体が好きになれない。抽象化レベルで期待するものと比べて摩擦があるように見える。小さな設計上の判断が積み重なって、言語がやや敵対的になっている。それでも、高速で、統合しやすく、メモリ使用量が小さく、信頼性があるため、なお選ぶ価値はある。C-API レベルでも、スタックアクセス方式のせいで扱いづらさがある。FORTH のようなスタック言語に触れたことはあるが、バインディングを書くときには依然として頭の体操が必要だった.
Lua が好きなら Terra を見ることを勧める。Terra は Lua に埋め込まれ、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 エンジンがあり、ほとんどの OS はインストール不要で使える高品質なエンジンや埋め込みフレームワークを提供している。ユーザーに新しい言語を学ばせるより、標準的な言語を使うほうがよい。ユーザーにも自分にも時間の節約になる.Lua と一緒に作業するのは楽しかったし、とても良い言語だと思う。特に C/C++ へ埋め込むためのインターフェースが整理されていて柔軟だ。性能上の問題はあるが、高性能なビデオゲームでゲームロジックに Lua が広く使われていることを考えれば、そうした問題は対処可能だ。しかし、混乱を招き、言語を難しくしている別の問題もある。Lua と C のインターフェースを学ぶ必要性が Lua 自体を学ぶのと同じくらい大きいため、配布間の切り替えが他の言語よりも混乱しやすい。それでも、この言語は過小評価されていると思う.
Lua を埋め込むのは楽しかったが、wasm と同様に、バイナリ全体を再コンパイルせずに新しいコードを実行する必要がある場面はほとんどなかった。いちばん楽しかったのは、C++ でゲームエンジンを作り、すべてのゲームロジックに Lua を使ったことだった。高速なデバッグサイクルが非常に役立った。次に楽しかったのは、Lua ロジックを再読み込みできる IRC ボットを作ったことだった。三番目に楽しかったのは、Lua をチューリング完全な設定言語として使ったことだった。配列が必要なときは Lua で配列を作った。いちばん楽しくなかったのは、3D モデルを生成された Lua としてエクスポートする Blender プラグインだった.
Lua は過大評価されていると思う。ゲーム業界で広く使われているからだ。Lua の唯一の利点は C++ に簡単に埋め込めることだ。それ以外は悪夢だ.