Archive for 7月, 2008

ゆの in ニコスクリプト

金曜日, 7月 11th, 2008

世界中で数人しか知らなさそうですが、
ニコスクリプトは演算子オーバーロードが出来るんですよ!

0::/t=drawText(text:"",size:20,color:0xffffff)
1::/echo=dt
1::/echo.setSlot('lessThan',def_kari('#:g3',t.text+=$1))
2::/trg=dt
2::/trg.setSlot('divide',def_kari('#:g2',t.text+="365";echo))
3::/X=dt
3::/X.setSlot('divide',def_kari('#:g1',t.text="ひだまり"+$1;trg))
4::/_="スケッチ"
5::/X / _ / X < '来週も見てくださいね!'

実行すると動画内時間5秒で「ひだまりスケッチ365来週も見てくださいね!」と画面に表示されます。
dtというのは本来画面に文字を表示する手続き(drawTextの略)ですが、
この手続きは新しい(少し特殊な?)オブジェクトを返します。
で、そのオブジェクトのスロットに'divide'とか'lessThan'といった名前で手続きを格納すると、
'/' や '<' といった演算子が使われたときに任意の手続きが呼べるという仕組みです。
ちなみに、手続きを作るdef_kariは第一引数に名前を要求するので、適当な名前をつけています。
「こうやったら出来るんじゃないか?」と思いつきでやってみたら案外出来るものですね。
ちなみに、ひだまりスケッチはマンガは読んでますがアニメは見てません。
そもそもスケッチブックの方が好きだし。
そんなことよりも問題なのはゆのさまですよ。ゆのさま。
ひだまりスケッチが流行って以来、「ゆのは」でググっても
「'ゆの' は」で引っかかってゆのさまばっかし出てくるんですよ。
もうやってられないんだぜ!
……と書いてから気づいたけど、今はそうでもなくなってるみたいです。
(まあ、やっぱり上位にひだまりスケッチ関連がきてますけど。)
前に検索したときに丁度ひだまりスケッチが流行ってたから上位にきやすかったんでしょうかね。

第7回 慢性的CL勉強会[予習]

火曜日, 7月 8th, 2008

気が付けばかれこれ2週間もエントリーを投稿していませんでしたが、生きています。
サイクロンゆのはな一号機(自転車)の後輪が壊れて修理に1万円取られたり、
戦国ランスにはまりすぎて廃人になったり色々ありましたが、一応生きています。


「The Common Lisp Cookbook」の「The Loop Macro
を読み終わったので適当にまとめておきます。
*全体として*
説明よりもソースコード嫁!
という感じでした。
冒頭で「最も文書化されていない(least documented)」と書きながら、
ここでも説明が少ないというのには笑いました。
*内容のまとめ*
Loopマクロとは:
- Common Lispの中で最も価値があり、もっとも文書化されていない。
Loopマクロの価値:
(mapや再帰と比べて)
- 強力
- コンパクト
- 読みやすい
Loopマクロを成す4つの部分:
- 変数の設定(これは繰り返される)の式
- 繰り返しを終了させる条件の式
- 繰り返しごとに何かをする式
- 繰り返しを抜ける前に何かをする式
*試してみた*

[21]> (loop for x in '(a b c 1 2 3) thereis (numberp x) do (print x)) A B C T [22]> (loop for x in '(a b c) thereis (numberp x) do (print x)) A B C NIL

thereisは直後に書いた式がnil以外になるとループを抜け、tを返すようです。
全ての繰り返しでnilになれば最終的にnilを返すようです。

[23]> (loop for x in '(a b c 1 2 3) never (numberp x) do (print x)) A B C NIL [24]> (loop for x in '(a b c) never (numberp x) do (print x)) A B C T

neverは直後に書いた式がnil以外になるとループを抜け、nilを返すようです。
全ての繰り返しでnilになれば最終的にtを返すようです。

[19]> (loop for x in '(1 2 3 a b c) always (numberp x) do (print x)) 1 2 3 NIL [20]> (loop for x in '(1 2 3) always (numberp x) do (print x)) 1 2 3 T

alwaysは直後に書いた式がnilになるとループを抜け、nilを返すようです。
全ての繰り返しでnilにならなければ最終的にtを返すようです。
これら3つがwhenとreturnを組み合わせたものというのは大体納得できるのですが、
最終的に返す値を決めるには、これら3つを使わない場合、どうやって指定するんでしょうか。

[31]> (loop for x in '(a b c) never (numberp x) collect x) *** - (LOOP FOR X IN '(A B C) NEVER (NUMBERP X) COLLECT X): ambiguous result: (SYSTEM::LIST-NREVERSE #:ACCULIST-VAR-4350) from COLLECT X T from NEVER (NUMBERP X)

上記の最終的に返す値の話が絡んでいるかは分かりませんが、
never等とcollectを組み合わせるのはまずそうです。

[32]> (loop for x in '(a b c 1) when (numberp x) return x collect x) 1 [33]> (loop for x in '(a b c) when (numberp x) return x collect x) (A B C)

こういう書き方なら問題ないようです。