トップページtech
582コメント172KB

プログラミング言語 Lua

■ このスレッドは過去ログ倉庫に格納されています
0001デフォルトの名無しさんNGNG
Lua について語ろう。

http://www.lua.org/
0151デフォルトの名無しさんNGNG
>>150
どういうこと?
マニュアルなら日本語の奴もある、
単に用途がみつからんということ???
0152デフォルトの名無しさんNGNG
なんかこれといって、特徴とか、売りとかがない気がする。
luaだからこんなことができる、とかあるのかな。

感想。
0)全ての文(?)の終端がendなのは萎える。
 rubyもそうだけど、これ、実はすごく読みにくい。
 結局、文の対応がインデントでしかわからない。
1)式の終端記号がない。危険な香りがする。
2)テーブル{}に関係する構文と操作全般がわかりにくい。
3スクリプト用途にしては、)returnとかfunctionとか長い名前が気になる。
 return不用、function → fn or lambda、 local → letとか。まあ修正すりゃいいけど。
4)elseifかよ。
5)local変数群への多重代入がややわかりにくい。
6)でも多値を返せるのは便利。
7)レジストリって何?
8)タグの有効な使い方ってなんだろう?
9)テーブルは慣れれば使いやすいかも。
0153デフォルトの名無しさんNGNG
>>152
> 7)レジストリって何?

組み込み/拡張用でわ

> 8)タグの有効な使い方ってなんだろう?

タグメソッドでわ

VectorTag=newtag()
function Vector(a,...) do v={}; settag(v,VectorTag); v[1]=a; for i=1,getn(arg) do v[i+1]=arg[i] end; return v; end; end
function dot_product(v, u) do s=0; for i=1,min(getn(v),getn(u)) do s=s + v[i]*u[i] end; return s; end; end
settagmethod(VectorTag, "mul", dot_product)

print(dot_product({1,2}, {3,4}))
print(Vector(1,2)*Vector(3,4))
0154デフォルトの名無しさんNGNG
>>152

確かにendって使いにくいね。
読みやすさが有ると言う意見もあるが、ちょっこりif文なんかいれて
end忘れたひにゃ。。。(以下略)

あと、キーワードが長過ぎるのも同感

多値リターンはすぐれものか?
0155デフォルトの名無しさんNGNG
ライセンスがMITなんだけどこれって本当にgpl互換なんだろうか?
0156デフォルトの名無しさんNGNG
>>155
MIT は修正 BSD 相当だから互換じゃないのか?
0157ヽ(´ー`)ノNGNG
>>154
end 使いにくいよね。Lua も Python もかじってみたいんだけど、俺的にネック。
0158デフォルトの名無しさんNGNG
>157
Python?
0159デフォルトの名無しさんNGNG
Pythonはendじゃないよね
0160デフォルトの名無しさんNGNG
rubyの間違い?
0161ヽ(´ー`)ノNGNG
あ、ゴメン、Ruby と間違えた。Python はインデントだっけ?
始めに触ったのが C だからブレースが無い言語は苦手…。
0162デフォルトの名無しさんNGNG
でも、そんなこと気にしてたらもったいないと思う
すぐに慣れるし、慣れたらそんなことどうでも良くなるよ
0163デフォルトの名無しさんNGNG
end を使うのはブロックの開始を省略できるかどうかによるんじゃないかな。
まあそれはいい。しかし
function f(x)
a = x+1
return a
end
print(f(1))
これのワンライナが
lua -e 'function f(x) do a = x+1; return a end end; print(f(1))'
になるのには少々驚いた。
0164デフォルトの名無しさんNGNG
おお、こういう書き方ができるのか。upvalue はなかなか画期的な文法かも。

plus = function(a) return function(b) return %a+b end end
print(plus(2)(3)) -- 5
0165デフォルトの名無しさんNGNG
>>164
それ高階関数だね。
ML風に書くと
val plus=fn a=>fn b=>a+b; print(plus 2 3);
テーブルの役割からすると意味的にはLISPと似てる。
(((lambda(a)(lambda(b)(+ a b)))2)3) ;;5
0166デフォルトの名無しさんNGNG
>165
むしろ upvalue を使ったスコープの制御が面白いかなと。

それと plus(x)(y) と書けるのは直観的だなと。
ruby だと変数名の後にカッコでは引数を渡せないから [] を使う必要がある:
plus = lambda{|a|lambda{|b|a+b}}
p plus[2][3] # 5
python ではどう書くのだろう。
plus = lambda a: lambda b: a+b
では駄目だし。
この点S式は比べにくい。
0167デフォルトの名無しさんNGNG
漏れ的に一番驚いたのは、複数戻り値が返せるという点

2番目は、そのソースとバイナリの大きさかな?
0168デフォルトの名無しさんNGNG
小さいのは builtin が少ないからだろね。おかげで速いのは良きかな良きかな。

多値や多重代入は python でも ruby でもできるよね。
% lua -e 'function f(x) return x*2,x*3 end; a,b = f(3); print(b,a)'
9 6
% python -c '
def f(x): return x*2,x*3
a,b = f(3)
print b,a'
9 6
% ruby -e 'def f(x) return x*2,x*3 end; a,b = f(3); p b,a'
9
6
0169ヽ(´ー`)ノNGNG
>>162
そうだね。とりあえず、Lua と Ruby を勉強してみるよ。ありがとう。

>>168
む〜、便利だな。Perl の list($a,$b) = f(3) とは違って、配列と同じ扱いじゃないの?

// 今ちょっとコンパイラが(゚Д゚)マズ-な事になってて Lua を入れれないのです。
0170デフォルトの名無しさんNGNG
>>169
lua の場合は一つの何かを返すわけではないので common lisp の values に近いみたい
しかしこう↓書けるのでさらにイカす
% lua -e '
function f(x,y) return x+1,y+10 end
print(f(f(0,0)))'
2 20

python と ruby は値を引数リストに展開するために f(*f(1,2)) と書く必要がある
多値といっても ruby は Array を、python は tuple を返すから
0171デフォルトの名無しさんNGNG
perl -e "sub f{(1+shift,10+shift)} $,=' '; print f(f(0,0))"
2 20
0172デフォルトの名無しさんNGNG
ルアってユーザいたんだ(w
0173デフォルトの名無しさんNGNG
luaってオブジェクト指向ですか?
0174デフォルトの名無しさんNGNG
ユーザっていうか、試用してる。
しかしendがウザイね。
return省いて多値返すときだけvaluesにしたらいいのに。
fun f(x,y) x+1,y+10; //カンマは演算子。y+10が関数の値
fun f(x,y) values x+1,y+10; //カンマはvaluesの区切り
0175デフォルトの名無しさんNGNG
>>173
どっちかっていうと、LISPみたいな関数型だな。
テーブルのタグ付けでそれっぽい事はできそうだが。
0176デフォルトの名無しさんNGNG
>>175
Lispみたいなというのはちょとちがうのでは?
0177デフォルトの名無しさんNGNG
>>176
簡単に言えば、
リストをテーブル(配列)にして、括弧無くしたLISPモドキ→Lua
でしょ
0178デフォルトの名無しさんNGNG
lispっぽいのは
・関数と変数に型がない
・call by value
・lambda 相当の function
・無名関数
くらいでは。eval がない点は大きく違う。
0179デフォルトの名無しさんNGNG
lispといえど、関数のeval使うことなんてほとんどない。
repl改造する時ぐらいじゃないか。
それに、lua自身もeval入れようと思えば出来るだろうし。
0180デフォルトの名無しさんNGNG
むしろlispとの大きな違いは演算子と、区間を限定する構文が
使える事だろう。
lispは括弧を閉じ忘れるだけで、エラー個所の特定が難しくなる。
0181デフォルトの名無しさんNGNG
eval に代表させたけど反射性は言語の大きな特徴だと思うよ
0182173NGNG
いろいろ情報ありがとう>>all

私も触ってみようと思いました。
ところで、最近endで区切るのが流行ってる(?)ような感じですが、
これってメリットあるのでしょうか?

(好みは別として)

なんか、素人丸出しで恐縮ですが、{}の方が閉じ忘れをすぐに見付
けることができるっぽいので(例:vi の % キー)良いような気もし
ています。
0183デフォルトの名無しさんNGNG
そうね。なんちゃら〜endだと非対称だから、
ちゃんとparseしない限り機械的な対応付けも辛い。
既にlua-mode.elなんてのもあるけど。
0184デフォルトの名無しさんNGNG
>>182
Pascal派への挑戦と受け取る。
























爆撃
0185デフォルトの名無しさんNGNG
>>182
好みの問題でしょう。
ブロックの開始を省略できるのがメリット
と思える人にはメリット。
0186デフォルトの名無しさんNGNG
いきなりendは、心臓に悪い。
0187デフォルトの名無しさんNGNG
>>185
それなら}のみにすれば更に吉かも?
0188デフォルトの名無しさんNGNG
vimでは対応してますか?
0189デフォルトの名無しさんNGNG
>>187
いっそ.とかの方が気持ちよくないか?
0190デフォルトの名無しさんNGNG
end に慣れたから正直些細なこととしか思わない。
Pascal の後で C をやったときは == にも抵抗があったがそれも今では些細なこと。
0191デフォルトの名無しさんNGNG
>>190
いや、そうではなくて(つまり、好き嫌いとかなれとかでなくて)
editorが対応してない香具師があるというのが問題なんだ

下手すればemacs専用になるよ(w
0192デフォルトの名無しさんNGNG
>>191
何を訳のわからんことを・・・
0193デフォルトの名無しさんNGNG
漏れは、c/awk/ruby/...と見て来たが、正直luaもハマリそうだ
しかし、言語が変わるたびに書き方変わるのが正直つらい。

いつになったら、--になれることやら。。。

だれか?マジデluaを改造してくれんか?
0194デフォルトの名無しさんNGNG
>>190
重度の不感症ですね。
0195デフォルトの名無しさんNGNG
>191
ttp://lua-users.org/wiki/LuaEditorSupport
Vim, Emacsen, Jed, MED, NEdit, TextPad, Scintilla/SciTE, EditPlus, EditPadPro, MC-Cooledit
0196デフォルトの名無しさんNGNG
>>195
おお〜、ありがとう!!
0197デフォルトの名無しさんNGNG
ついでといっちゃあなんだけど、if〜then のthen
ってなんで必要なんだろう?

改行じゃまずいのでしょうか?
0198デフォルトの名無しさんNGNG
>>195
これって単にハイライト表示するだけじゃないの?
{}のマッチと比較するには非力か?(ちがってたら、スマソ)
0199MLerNGNG
>>197
演算子の区分を決めるために必要。
ただし、別にthenじゃなくてもいいんだけど。
例えば、C言語の条件演算子'?' と ':' の間の式中には
優先度の低いカンマ演算子が置ける。これと同じ原理。
仮に改行を区切り子にすると、BASICの様な行指向言語に
なってしまう。
0200デフォルトの名無しさんNGNG
>>199
でも、どうでしょう?
実際のところifの条件箇所をマルチラインでサクッと書ける言語
なんてほとんどないと思うけど。。。
0201デフォルトの名無しさんNGNG
話が噛み合ってない。
0202200NGNG
えっと、うまく伝わらなかったみたいでスマソ、

例えば、すっごくなが〜い条件文があったとしても、
backslash で結べば十分だとおもうのですが。。。どこか欠けてますか?

if x>3 and \
y<3
a=4
end

来んな風には書けないとおもったが。。。

if x>3 and
y<3 then
a=4
end

0203200NGNG
いま手もとでやってみたら書けた(動いた)!
スマン>ALL
0204デフォルトの名無しさんNGNG
>>198
indent/lua.vim は適切にインデントしてくれる
0205デフォルトの名無しさんNGNG
だれかコンパイル済みのluaください。
0206デフォルトの名無しさんNGNG
http://angband.oook.cz/distrib/Angband-303.exe
0207デフォルトの名無しさんNGNG
>>205
luaのオフィサイトにおいてあるけど
0208デフォルトの名無しさんNGNG
>>195
最新のvimには両方ついてくるね
0209デフォルトの名無しさんNGNG
>>204

勘違いしてる香具師が多いので言っとくけど、インデントなんて
ど〜でもいいんよ!
0210デフォルトの名無しさんNGNG
言語仕様的にはどうでもいいけど、変なインデントは人が読むにはつらいので、適切にインデントしてくれることは重要だと思う。
0211デフォルトの名無しさんNGNG
pretty-printぐらい欲しいだろう
0212デフォルトの名無しさんNGNG
>>209

{ } じゃなくて end だと数があってるかがエディタで確認しにくい
  ↓
エディタが end を認識すればいいんだけど
  ↓
emacs ならできるよ
  ↓
じゃあ emacs 以外は?
  ↓
vim には標準で indent/lua.vim がついてくる
0213デフォルトの名無しさんNGNG
    ↓
vim なんか使ってネエ
    ↓
たかがindentがeditorに依存するのは馬鹿げてる
    ↓
luaは一応program作る言語
    ↓
pretty-printぐらい欲しいだろう
    ↓
pretty-print誰か作れ
0214デフォルトの名無しさんNGNG
>>213
知るか、死ね。
0215デフォルトの名無しさんNGNG
>>212,213

サンクス、流れがよくワカッた。
つまり、vimならインデントと言っても%によるマッチが(標準で)つかえるのね?

0216デフォルトの名無しさんNGNG
LUAって結局はCから呼ばれるライブラリみたいなもんでしょう?
これをスクリプト言語として使うのは、無理でないにしてもやや
目的外って感じになるのでしょうか???
0217デフォルトの名無しさんNGNG
>>216
んなこたないと思うよ。5.0ではtagまわりがさらに強化されてるし。>>108のリンク嫁
0218デフォルトの名無しさんNGNG
>>215
試してみたが、indentはインデントであって % によるマッチは行なわない。
改行した瞬間やendと打った瞬間にインデントされる。
また gg=G でバッファ全体のインデントが修正される。
詳しくはvim使いに聞いて。
0219デフォルトの名無しさんNGNG
>>218
やはり、というか%マッチの威力を知らん香具師のあおりの検証サンクス!
有る意味、自動でインデント(綺麗に)されてると、変なかたわれブロック
が出来たときにかえってバグ取りが難しくなる。

よって、endは糞決定!

>>217
結局TAGっていっても素直にADDのFUNCTIONと(この例読むかぎりでは)なん
の違いもない。(こちらは、99%もれの理かい不足!)
0220デフォルトの名無しさんNGNG
>>219
> 有る意味、自動でインデント(綺麗に)されてると、変なかたわれブロック
> が出来たときにかえってバグ取りが難しくなる。

そのためにも >> と << があるのでは。
0221デフォルトの名無しさんNGNG
>>220
なにそれ?
0222デフォルトの名無しさんNGNG
>>221
To increase the amount of indent in a line, use the ">" operator. Often this
is used as ">>", which adds indent to the current line.
そういうことじゃなくて?

まあ % 好きに非難されるのは理解できなくはない
0223デフォルトの名無しさんNGNG
もう分かってると思うが
普通のif文の中で、endのないifをいれてしまったら
と思うとぞっとする。
0224デフォルトの名無しさんNGNG
ほんと、構文については書き直して欲しいな、これ。
センスなさすぎ。
0225デフォルトの名無しさんNGNG
とはいえ、以外に伸びるなぁこの擦れ
こんなにマイナーな言語なのに。。。(w
0226デフォルトの名無しさんNGNG
sage
0227デフォルトの名無しさんNGNG
Lua5.0のcoroutine(Schemeの継続みたいなやつ)って結構おもろいな。
0228デフォルトの名無しさんNGNG
>>227
subroutineと違うのか?
0229デフォルトの名無しさんNGNG
おもろいけど独特過ぎないか
0230デフォルトの名無しさんNGNG
それは言いすぎでないか
0231デフォルトの名無しさんNGNG
coroutineって普通にCソースから使えないのかな?軽く実装してみたが
どうもうまくいかん。

lua_dostring(l, ... );
while( lua_resume(l) != 0 ){
;
}

というような感じの事をしたいのだけど、5.0Βはまだ謎がいっぱいだ。
0232デフォルトの名無しさんNGNG
あぁ、あと、構文だけど、ソースをちょっと弄ればCライクなスコープが
記述できるようになるんだけど、Luaって改変して配布するのってOKなの
かな?

まぁ、そこまでして使うのはどうかと思うけど、どーせ使うならあのダサ
いコメント「--」だけは//辺りに変更する事をお勧めするよ。
0233デフォルトの名無しさんNGNG
>>232
>ダサいコメント「--」だけは//辺りに変更する事をお勧めするよ。

正直、//に比べて--のどこがダサいのかわからん。

単にお前の好き嫌いだろ?

0234デフォルトの名無しさんNGNG
触ったことある言語だと Ada Occam Haskell Eiffel Sather は -- だったよ
あ SQL もそうだよ
珍しくもないな
0235デフォルトの名無しさんNGNG
begin endがダサいと言ってるのと変わらんわな
0236デフォルトの名無しさんNGNG
coroutine って resume で引数渡せるから油断すると goto なみに危険
0237デフォルトの名無しさんNGNG
>>233
理由は簡単。Cへの組み込みスクリプトだからコメントがCと同じほうが
いいに決まってる。それに--はCではデクリメント演算子なので意味合い
が違う。だから--コメントはダサい。と、個人的に思う。
まぁちょっとパッチ当てるだけで変更出来るんだからいいんだけどね。
0238デフォルトの名無しさんNGNG
コメントが // で出来るCの処理系ってそんなに多い?
0239デフォルトの名無しさんNGNG
gccでも-pedanticつけると//はエラーになるな
0240デフォルトの名無しさんNGNG
いつの話だ‥‥
今じゃ // コメントは ISO C の標準になってるよ。
0241デフォルトの名無しさんNGNG
gcc でも -std:c99 -pedantic とやればエラーにならない。
0242デフォルトの名無しさんNGNG
endやめて;にしてくれ>だれか
0243デフォルトの名無しさんNGNG
>>241
Invalid option `-std:c99'だってよ。ちなみにgcc 2.95.3
0244241NGNG
>>243
ごめん。-std=c99 のまちがい。
ていうかもはやぜんぜん Lua の話じゃないね。
0245デフォルトの名無しさんNGNG
>>232
Lua(5.0beta)はMITライセンス(修正BSDライセンス相当)だから、
自由に改変、再配布できるよ。

俺もコメントは//か#がいいのでパッチ作成キボン。
ついでにdo ... endを{ ... }にしてくれると最高。
0246デフォルトの名無しさんNGNG
>>231
test.c:
#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>
int main(int argc, char **argv) {
  int index, i;
  lua_State *L, *co;
  L = lua_open();
  lua_baselibopen(L);
  index = lua_gettop(L);
  lua_dofile(L, "test.lua");
  lua_settop(L, index);
  lua_getglobal(L, "coroutine");
  lua_pushstring(L, "create");
  lua_gettable(L, -2);
  lua_getglobal(L, "co_func");
  lua_call(L, 1, 1);
  co = lua_tothread(L, -1);
  lua_setglobal(L, "co");
  index = lua_gettop(L);
  for (i = 0; i < 4; i++) {
  lua_pushnumber(co, i);
  printf("c: resume=%d\n", lua_resume(co, 1));
  printf("c: co top=%d, L top=%d\n", lua_gettop(co), lua_gettop(L));
  printf("c: co result1=%lf\n", lua_tonumber(co, -2));
  printf("c: co result2=%lf\n", lua_tonumber(co, -1));
  }
  lua_close(L);
  return 0;
}
0247続きNGNG
test.lua:
function co_func(arg)
  i = 100
  print("co_func: start")
  while 1 do
    print("co_func: arg=", arg, " i=", i)
    i = i + arg
    arg = coroutine.yield(i, arg)
  end
end
0248デフォルトの名無しさんNGNG
>>246
こんな感じでもOK

#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>
int main(int argc, char **argv) {
  int i;
  lua_State *L, *co;
  L = lua_open();
  lua_baselibopen(L);
  lua_dofile(L, "test.lua");
  co = lua_newthread(L);
  lua_getglobal(co, "co_func");
  for (i = 0; i < 4; i++) {
lua_pushnumber(co, i);
    printf("c: resume=%d\n", lua_resume(co, 1));
    printf("c: co result1=%lf\n", lua_tonumber(co, -2));
    printf("c: co result2=%lf\n", lua_tonumber(co, -1));
  }
  lua_close(L);
  return 0;
}
0249デフォルトの名無しさんNGNG
>>246
うお神降臨!さっそく試してみます。ところでlua_closethreadって実装されて
なさげなのですが、任意のスレッドを開放するにはどうすればいいんでしょうね?
lua_close使うとエラー 出るし。マニュアルにはちゃんとあるんだけどなー。

>>245
Lua5.0b file:llex.c line:317に次レスを追加。//と/**/が普通に使えるようになります。
きちんとデバッグしてないので自己責任でどーぞ。#も似たような感じで。
ちなみに漏れはlua_commentblock( "//" , "/*" , "*/" )で自由にカスタムできるよう
にしてます。あと、--コメントを消し去りたいのならその次のブロックをコメントアウト。
 Cスコープ{}にあわせる方法はLuaを弄る訳ではなくプリプロセスを通してLua
コードに変換するだけなので汎用性はあるけど、ちょっと微妙。スマヌ。
0250デフォルトの名無しさんNGNG
case '/': {
next(LS);
if (LS->current != '/' && LS->current != '*' ) return '/';
/* else is a comment */
//long comment
if (LS->current == '*'){
while (1){
if( LS->current == '*' ){
next(LS);
if( LS->current == '/' ){
next(LS);
break;
}
continue;
}
if ( LS->current == EOZ) break;
next(LS);
}
continue;
}

//short comment
next(LS);
while (LS->current != '\n' && LS->current != EOZ){
next(LS);
}
continue;
}
■ このスレッドは過去ログ倉庫に格納されています