Archive for May, 2007

これってようするにローカル関数定義できるかどうかと変数のスコープをどう解決するかってことだよね

Posted by 向井 淳 on Thursday, 31 May, 2007

http://d.hatena.ne.jp/lethevert/20070528/p2

「ボクも知ってるあのマイナー言語でいろいろ書いてネタにしてみよー」と漠然と思っていたけれど、そんなにマイナーな言語など特に知らないのでした。ざんねん。

というわけで特にマイナーでもない言語を2つほど。ひとつめは Lua。

function f(x) local function g(y) return x + y end local function h(x) return g(10) end return h end

JavaScript によく似てますね……って思ったけどそれって function っていうキーワードだけ?な気もしてきた。特に注目するポイントは local かな。 local 宣言のされていない変数に何かの値を代入したりすると、グローバル環境への操作とみなされるため、ここで local を省くと g と h は(fを最初に実行したときに)グローバル環境で定義されてしまいます(Ruby の「defのなかのdef」みたいな感じね)。

もうひとつは Erlang。 Erlang には関数内で関数を定義するという方法がありませんが、関数リテラルを変数に束縛するという方法で強引に解決できないこともありません。

f(X) -> G = fun(Y) -> X + Y end, H = fun(X) -> G(10) end, H.

対応づけのために H への束縛を作ってから H を返していますが、もちろん fun (X) -> ... で終了にしてしまっても構いません。

さて、この関数を呼ぶと、

1> c(test). ./test.erl:6: Warning: variable 'X' is unused ./test.erl:6: Warning: variable 'X' shadowed in 'fun' 2> test:f(10)(1). ** 1: syntax error before: '(' **

警告を出してくれるのは嬉しいのですが、それはさておき関数を呼べません。どうも何やら不思議な優先順位に従って構文が解析されているようですね。

2> (test:f(10))(1). 20

こうしないといけません。

というわけで、個人的にけっこう気に入っているんですがいまいちちゃんと使ってみたことがない Lua と、なんだかんだいってもいろんな構文に萎え要素が満載な Erlang でした。

 

あーあとそういえばマイナーでもなんでもないけど挙がってないやつだと Common Lisp ならこんな感じ?

(defun f (x) (labels ((g (y) (+ x y)) (h (x) (g 10))) #'h))

CL-USER> (funcall (f 10) 1)
20

局所定義に defun は使えないので labels を使う。敢えて labels ではなく let を使うなら、

(defun f (x) (let* ((g (lambda (y) (+ x y))) (h (lambda (x) (funcall g 10)))) h))

ってところか?(正しくは #'(lambda ...) なのかな)

ところで「世の中でもっとも普及した Common Lisp 処理系は xyzzy だ」というのはどうだろう(たぶん嘘)。


rubyでリングベンチマーク

Posted by 向井 淳 on Wednesday, 30 May, 2007

ふと Fiber をさわってみたくなって、前に別のところで試したリングベンチマークというのをやっていることにしました。

リングベンチマークというのはどういうのかというと、 N 個のノード(プロセス)を用意して、1番のノードは2番に、2番のノードは3番に……というようにメッセージを送信する。で、 N 番のノードはまた1番に戻る。で、 M 回ほどメッセージの送信を終えたらおもむろに終了する。これのパフォーマンスを調べなさいっていう話。

まあ、あからさまに Erlang に有利なベンチマークなんですが(笑)。

Fiber を使うとこんな感じでしょうか。

require ‘benchmark’ class Node attr_accessor :oth def initialize(count, oth=nil) @oth = oth @node = Fiber.new do count.times do |i| # puts "sending message [#{i}]" v = @oth.pass(:message) end end end def pass(v=nil) @node.pass(v) end end class RingNodes def initialize(nodes, count) @nodes = Array.new(nodes) @nodes[nodes-1] = Node.new(count) (nodes-1).downto(0) do |i| @nodes[i] = Node.new(count, @nodes[i+1]) end @nodes[nodes-1].oth = @nodes[0] end def start @nodes[0].pass end end def main(nodes, count) Benchmark.bm(15) do |x| ring = nil x.report("initialize") { ring = RingNodes.new(nodes, count) } x.report("passing") { ring.start } end end nodes = (ARGV[0] || 10).to_i count = (ARGV[1] || 10).to_i main(nodes, count)

実行結果はこんな感じでした。

% /usr/local/ruby-1.9/bin/ruby19 ~/ring.rb 10 100 user system total real initialize 0.000000 0.000000 0.000000 ( 0.000319) passing 0.000000 0.000000 0.000000 ( 0.003591) % /usr/local/ruby-1.9/bin/ruby19 ~/ring.rb 100 100 user system total real initialize 0.000000 0.000000 0.000000 ( 0.002868) passing 0.030000 0.000000 0.030000 ( 0.038393) % /usr/local/ruby-1.9/bin/ruby19 ~/ring.rb 1000 100 user system total real initialize 0.040000 0.020000 0.060000 ( 0.060228) passing 0.610000 0.010000 0.620000 ( 0.639878) % /usr/local/ruby-1.9/bin/ruby19 ~/ring.rb 5000 100 user system total real initialize 0.970000 0.160000 1.130000 ( 1.142228) passing 3.690000 0.060000 3.750000 ( 3.836600) % /usr/local/ruby-1.9/bin/ruby19 ~/ring.rb 10000 100 user system total real initialize 4.520000 0.450000 4.970000 ( 5.042758) passing 8.600000 0.140000 8.740000 ( 8.966811) % /usr/local/ruby-1.9/bin/ruby19 ~/ring.rb 20000 100 user system total real initialize 33.880000 1.470000 35.350000 ( 35.640199) passing 28.600000 0.310000 28.910000 ( 29.607706)

だんだんキツくなっていくとはいえ、1万fiberくらいは余裕みたいですね。 Fiber かっこいい(←これ言ってみたかっただけ)。


ウィキペディアをウィキって略すのが嫌なのは

Posted by 向井 淳 on Wednesday, 30 May, 2007

「ペディア」の方にこそアイデンティティが潜んでいる(ように思える)からだな、とふと思った。

携帯電話を(「携帯」じゃなく)「電話」と略したりはしないようなもので(少なくとも今は)。


ロックマンMAD

Posted by 向井 淳 on Wednesday, 30 May, 2007

もってけ!エネルギー缶

ロックマン映像で『らき☆すた』OPというアイディアに脱帽。ついでに音がまるでロックマンでほんとうによくできている。けっこうキモチ良く動いてるけど、動きがかなりソレっぽくて「オリジナルにはこんな動きないよねえ」ってわざわざ思うくらい。

で、同じ作者の「ハレ晴れユカイ」もあるのね。こっちの方が先に作ったものらしい。こっちの方が気持ち良く動くけど、その分「ああ自分で描いたんだなあ」というのがすぐわかるのがちょっと悲しいし、音もちょっと日和っている感じ。「習作」というか……でもボスキャラ総出演な感じとかはオチとかは好きです。

検索したら、作者のサイトに「公開までの流れ」がありますね。

>

2007年3月上旬、友人スパナから例のアニメを借りる。 >

そして思いのほかハマル。 そしてちょっと現実がイヤになる。 >

その後YOUTUBEで例の踊りのパロディーを色々と発見。 >

モトネタのアニメーションも発見。動きすぎでびびる。 >

3月中旬、ロックマンで作ってみようと思いつく。 >

3月下旬、動画完成。

……いやーその、なんでまたロックマンで作ってみようと思いついたかが知りたいんですが……まあ、ほんとうに「ふと思いついた」としか言えないような何かなんでしょうが。

あと上で文句をつけてるけど同じようなことを思う人はほかにもいるらしく、作者ページには、もっとちゃんとロックマン風サウンドなものがあった。素晴しい。

 

 

とかエラソーなこと抜かしとりますがらきすたもハルヒもぜんぜん観たことありません。


ディーノ・ブッツァーティ『神を見た犬』

Posted by 向井 淳 on Tuesday, 29 May, 2007

神を見た犬

ブッツァーティはイタリアの幻想作家。本書はそのブッツァーティの短編集で、ほとんどショートショートと呼んでいいような掌編を多く含む22編が収録されている。

短いものについては、さすがにすぐ結末までわかってしまうようなものも多いのだけど、全体としてはなかなか面白かった。個人的には、妙に人間くさい聖人たちを描いた作品(「聖人たち」とか)が意外に良かった。解説で指摘されていてなるほど、と思ったが、妙にアニミズム的な雰囲気がある。

こうした作品では、わりと世界中のその辺の人も聖別されていたりするし、奇跡もホイホイ起こる。クリスマスには神の存在はその辺に感じられ、この世の終わりには神は「ある朝の十時ごろ、とてつもなく大きな握りこぶし」として登場する。

「聖人たち」はこんな話だ。あるところにガンチッロという名前の男がいて、死後、彼が聖人に叙される。こんな理由で。

>

聖人といっても、ガンチッロは、世間を驚かせるようなことをしたわけではない。農夫として慎ましい一生を終えたが、死後になってようやく、よく考えてみれば彼のまわりには恩恵が満ちあふれ、少なくとも三、四メートル四方が明るく照らされていたことに気づいた者がいた。

というわけだが、ガンチッロはあまりにもささやかだったので、聖人だということを認識してもらえない。誰からも祈りは捧げられず、誰からも懇願をされない。そこで奇跡を起こしてみるが、隣の礼拝堂で祀られる聖マルコリーニの奇跡だと勘違いされてしまう。そんな、他愛もない話。これがふつうの話だと、ガンチッロがあの手この手で注意を引こうとしては失敗するのがコミカルに描かれるところだろうけれど、いかに人間くさいといってもガンチッロは聖人なので、そんな下世話なことはしない。

>

ここに至り、ガンチッロは独りごちた。どうやら、あきらめたほうがよさそうだ。私のことなど誰も思い出してくれやしない。彼はバルコニーに座り、大海原を眺めていた。それはまた、たいへん心の安らぐ光景でもあった。

てな感じで静かに終わる。

あと面白かったのは「七階」「一九八〇年の教訓」「戦艦『死』」。「七階」は、七階建ての病院に入院することになった男を描くごく他愛もない話で、読みはじめたら結末まですぐにわかるし実際そのまま予想通り展開するけど、なぜか面白く読めた。「戦艦『死』」は、第二次大戦の失なわれた極秘プロジェクトの顛末を追うという体裁の話だが、最後の不条理な展開と幻想的な光景がいい。「一九八〇年の教訓」は今読むとなんだか『デスノート』みたいな話だが(ただし死ぬのは犯罪者ではなく権力者)、皮肉が効いている掌編。


Lua のテーブルと配列のしくみ

Posted by 向井 淳 on Monday, 28 May, 2007

PHPの配列のキーについて調べてみるという話をみました。 PHP のこの話は前にもどこかで読んだことがないわけではなく、そのたびに「キモいねえ」と思うわけですが、幸いにして PHP で組むはめになったことがないので(正確には二度ほどあったが、どちらも自分にコントロール権があったので、ぜんぶ Ruby で書きなおした)、個人的にはさほどの興味はないのでした。

さて、ハッシュと配列が同一視されているプログラミング言語というと、わたしは Lua を思い出します。

Lua は「テーブル指向」の言語で、とにかくありとあらゆるデータ構造を「テーブル」(ようするにハッシュだ)で表現します。 t['key'] を t.key と表記できたり、 function というキーワードで無名関数も作れたりとちょっと JavaScript に似ている気がします。……ってそれくらいか。わたしはわりと好きですね。あんまり使っていませんが。

さて、 Lua はテーブル指向でありまして、配列も「テーブル」というデータを使っています。ちなみにテーブルのキーには nil を除く任意のデータが使えますが、物理的な同等性で比較されるので注意が必要です。実用上は文字列と数値以外には使われないと思います。

まず、 Lua ではキーに数値と文字列を使っても混同が起きません。まあ、当然だと思いますが。

面白いのは、 Lua は配列としては順序を記憶しているがハッシュとしては順序を記憶していないことです。 Lua ではテーブルの各要素をなめるための for ループ構文がありますが、まず整数のキーをその順番に処理し、残りの要素があればそれをよくわからない順序で処理する、という流れになります(数値パートだけを処理するようなこともできる)。

そのようになっているのはなぜかというと、ようするにテーブルというのは実態としては、配列とハッシュの組み合わせになっているのだね。十分小さな整数がキーのときは配列パートに組み入れられ、そうでない場合にはハッシュに放り込まれるようになっていると。で for ループではまず配列パートをなめてからハッシュパートに取りかかるため、そのような処理になるというわけです。したがって、キーが整数でも巨大である場合にはハッシュになることがあります(リハッシュが発生した段階で配列パートに戻ることもある)。

そこまで頑張るくらいなら配列とハッシュくらいは分けてもよかったんじゃない?という気もするんですが(じっさい類似の組み込み言語と言われている Squirrel は配列とハッシュが分かれているらしい)、面白いことをやっているなということで紹介してみました。

ところで Lua プログラミングの名高い落とし穴として「配列のインデックスは1から始まる」というのがあります。キーに0は指定できるんですが、これはハッシュテーブルに放り込まれるのですね。むかしは0とnilが同一視されていたとかそういう系なのですかね。理由はよくわかりません。

そういうわけで、次のように書くと、

a = {} a[1] = 1 a[2] = 2 a[0] = 0 a['0'] = ‘zero’ for k, v in pairs(a) do io.write(k..""..v.."\n") end

結果はこんな感じで、

1 1 2 2 0 0 0 zero

0が三番目(わかりづらいですが最後のが '0' のペア) 。うーむ。配列パートだけを使う ipairs を使うと、

> for k, v in ipairs(a) do io.write(k..""..v.."\n") end 1 1 2 2

0がありません。

というわけで Lua でした。


まんが感想3つ

Posted by 向井 淳 on Sunday, 27 May, 2007

SABE『世界の孫 (2)

「お孫」顔の少女、甘栗甘水。あまりのお孫顔のため、道行くじーさんばーさんはもれなく声をかけ、かわいがってくれるという少女のためにいろいろ大変なことになったりならなかったりするまんがの2巻。あと時代劇ネタとか、カンフー映画ネタとかでこのまんがは構成されております。

今回は「世界のイカ」と改題した方がいいんじゃないかと思うくらいイカ子先生が大活躍しまくり。読んでいる人間を置いてけぼりにしてなんだかすごいところにまで行ってしまった気がするのだが感動の渦が巻き起こったりは決してしない、なんだか知らんがとにかく良し。

読み手を選ぶけど一部のボンクラにはマスト買い。

長谷川裕一『機動戦士クロスボーン・ガンダム鋼鉄の7人 (2)

『クロスボーン・ガンダム』シリーズの「完結編」なのだそーだ。知らなかった(まあ既にVガンダムのキャラも出はじめているので、確かにそろそろこの世界も続けられないだろうけれど)。悪くはないけど長谷川裕一だなあというか、うーん、よくよく考えたら長谷川裕一まんがの中ではクロスボーンは好きな方ではないのかもしらん。マップスのweb連載の方が気になっている今日このごろ。

ところで、この2巻でボスの一方は倒してしまった。意外に展開は速いのかな?

唐沢なをき『まんが極道 (1)

まんが業界の非道い話を、ミもフタもなく、しかもありのままにではなく非道い方向にエスカレートさせた話ばっかり集まったまんが。非道すぎるがゆえに爆笑につぐ爆笑だった。うーん非道い。非道すぎる。

個人的に心にキたのは、マイナーまんがを愛好して、それを愛好する自分に酔っているだめなファンを描いた「貧富論」と、SF大好きで設定に凝りすぎてだめな方向になんだか突っ走っちゃってる「センス・オブ・ワンダーくん」でした。ううっ。

わかりやすいあたりでは、休載につぐ休載でついに鉛筆のラフ画みたいなのを載せちゃう少年漫画家の「へのへの」と、新興宗教にハマっちゃってる少女漫画家を描いた「信じれば…」とかでしょーか。


sun tea というのを作ってみた

Posted by 向井 淳 on Saturday, 26 May, 2007

写真1(淹れはじめ)、
写真2(完成後)

mixiの紅茶コミュニティにそういう話題があったのであった。水出し紅茶と何か違いはあるのか? 少しだけ加熱されるぶん、味が変わったりするのだろうか……?

まあ、ものは試しである。どうせだめだったとしても、水出しができるだけだし、今日はそのつもりだったのだし。というわけで作ってみたわけだが、やっぱりというかなんというか、水出し紅茶との差異はさっぱりわからないのであった。

まあ、いいけどね。茶の化学はよくわからないのだが、日中に放置するくらいの熱量で何か変わるのだろうか?(太陽熱でお湯をつくる、とかいうほどではなく、その辺に放置するんだしなあ) その辺に詳しい人がいたら教えていただければさいわい。

でも、一点だけよーくわかったことがある。

つまりさ、水出し紅茶なんて、冷蔵庫がなくても作れるんですよ。当たり前だけども。そりゃー冷えてた方が美味しいと思いますが ;-)


Haskellが使えるホスティングサービス

Posted by 向井 淳 on Saturday, 26 May, 2007

http://example.nfshost.com/versions.php これも Wadler のブログより。 Haskell (GHC 6.6) だけじゃなくて、ほかにも、

>
  • GNU CLISP >
  • Lua >
  • OCaml >
  • Scheme (MIT scheme, Guile, Chiken, MzScheme) >
  • Tcl
  • なんかが使えるらしい。むろん、 Perl/Ruby/Python は当然のように使えます。あと Gauche があれば。

    ホスティングの初期費用が$0.25、利用料は従量制で転送量(帯域)が$1.00/ギガバイト、ディスク使用料が$0.01/メガバイト。なんか MySQL はオプショナルな別料金て書いてあるんですが、そこはどうもよくわからんな。

    ただまあ、 CGI サービスっつうことだし、シェルとかは貰えないのかねえ。 Haskell はどうやってるんだろう。


    関数プログラミング

    Posted by 向井 淳 on Friday, 25 May, 2007

    artonさんの日記経由で
    http://cappuccino.jp/keisuken/logbook/20070525.html#p02を見たけど、それ関数的じゃないです。

    というのは、 set っていう名前が気になったので試してみたんですけど、

    import java.util.*; public class Func { interface Fn<T> { T $(T arg); } static <T> List<T> map(List<T> list, Fn<T> fn) { for(int i = 0; i < list.size(); i++) { list.set(i, fn.$(list.get(i))); } return list; } static <T> List<T> list(T… values) { List<T> list = new ArrayList(values.length); for(T value : values) { list.add(value); } return list; } public static void main(String[] args) { List<Integer> l1 = list(1, 2, 3); List<Integer> l2 = map(l1, new Fn<Integer>() { public Integer $(Integer n) { return n * n;}}); for(Integer n : l1) { System.out.println(n); } for(Integer n : l2) { System.out.println(n); } } }

    これを実行すると、

    % java Func 1 4 9 1 4 9

    てことで、このコードに相当するのは Ruby では map ではなくて map! です。べつに map! でも実用上はいい場合が大半だと思いますが、しかしそれは少なくとも関数プログラミングではない。関数的と名乗るなら、 clone するんだか new するんだかわかんないですけど、そのようにしてコピーするべきです。

    そういえば $ という関数名は、わたしは prototype.js を見て JavaScript で使えるのをはじめて見たときに「おおっ」って思ったんですけど、ほかの言語だとどれくらい使えるもんなんでしょうね(ってなんだ、Cでも使えるのか……)。