バリケンのRuby日記 RSSフィード

2009-03-06

[] RubyistLispを学ぶ理由  RubyistがLispを学ぶ理由 - バリケンのRuby日記 を含むブックマーク はてなブックマーク -  RubyistがLispを学ぶ理由 - バリケンのRuby日記  RubyistがLispを学ぶ理由 - バリケンのRuby日記 のブックマークコメント

Rubyの作者、まつもとさんも次のように言っているよ。

エリック・レイモンド(Eric Raymond)のエッセイ「ハッカーになろう*」では、Lispのことが以下のように紹介されています。

LISPは、それをモノにしたときの素晴らしい悟り体験のために勉強しましょう。この体験は、その後の人生でよりよいプログラマーとなる手助けとなるはずです。例え、実際にはLISPそのものをあまり使わなくても。

それに対してLispハッカーであるポール・グレアム(Paul Graham)は以下のように反応*しています。

彼がLispについて言っていることはよくある意見だ。つまり、Lispを学べばよいプログラマーになれる、でもそれを実際に使うことはない、と。何故だい? プログラミング言語なんてただの道具じゃないか。Lispでよいプログラムが書けるなら、使うべきなんだ。

そのとおり。あまり使われていませんが、Lispには優れたところがたくさんあります。

まつもとゆきひろのハッカーズライフ:第11回 Let’s Talk Lisp (1/2) - ITmedia エンタープライズ

Rubyist Magazineの第16回のインタビューで、essaさんは次のように言っているよ。

ささだ 若手へ一言、あります?

essa 関数型プログラミング言語を勉強した方がいい。

一同 (笑)

essa 自分の実体験から、「関数型プログラミング言語の勉強はわかんなくても役に立つ」ということを言いたいです。私の場合は On LispSICP を読んで、どちらも半分から分んなくなってんですけど、それでもかなり、結構効果あったような気がしてるんで。

Rubyist Magazine - Rubyist Hotlinks 【第 16 回】 essa さん

Googleの高林哲さんも次のように言っているよ。

今年の4月に『計算機プログラムの構造と解釈』(SICP)を知った。これはすごい本である。MITの入門コース用の教科書らしいのだが、僕にとっては難しい(一応は情報科学が専門の大学院生なんだが)。が、難しい以上に楽しい。本物の計算機科学を感じる。perlだとかCGIだとか、くだらんことをやっていないで、もっと早く読むべきだった。

この本では、プログラミング言語としてLispの1つの方言であるSchemeを採用している。僕はLispを長い間、敬遠してきた。あんな括弧の多い言語、IQの高い人間じゃないと理解できないに違いない、そもそも実用性がないんじゃないか、と思っていた。が、やり始めてみると、すぐに病みつきになった。リスト構造の単純さ、lambda式の考え方、そして、リストとlambda式の組み合わせによる表現力。限りなく高い自由度。なんでこんなにすごいんだ? 何より楽しい。

括弧については bit 2000 年 5月号 に竹内郁雄氏の 言葉がある。

弟子が尋ねた。「先生、私は先生がカッコをまるで魔術師の ように扱っているのを常々敬服しています。どうすれば先生のようになれ るのでしょうか?」

師「えっ? カッコ? あ、そうか。そんなものもあったな。いやあ、 すっかり忘れておったわ」

でも実用性がないじゃないか? ビジネスの世界で使えないじゃないか? との疑問が残るかもしれない。僕は実用性がないとは思わないし、ビジネスで使えなくても気にしない。実用性やビジネスより楽しさの方が大きな動機づけとなるのだ。

『計算機プログラムの構造と解釈』について

Googleでは実際に関数型言語の知見が生かされているみたいだよ。

関数型プログラミングを会得しない限り, Google に強大なスケーラビリティをもたらしたアルゴリズム ― MapReduce を発明することはできないだろう。 -- Joel Spolsky [Joel]

たしかに MapReduce は面白い。これほどまでに単純なプログラミングモデルによって,あの巨大なクラスターが駆動しているというのだから,面白くないはずは無い。

Radium Software Development - MapReduce

今すぐ役に立つ知識じゃないかもしれないけど、Lispを学ぶことで得られた知見はきっといつか役に立つよ。

繰り返しますが、先を読んで点と点をつなぐことはできません。後からふり返って初めてできるわけです。したがってあなた方は、点と点が将来どこかでつながると信じなければなりません。自分の勇気、運命、人生、カルマ、何でもいいから、信じなくてはなりません。点がやがてつながると信じることで、たとえそれが皆の通る道からはずれても、自分の心に従う自信が生まれます。これが大きなちがいをもたらしてくれるのです。

H-Yamaguchi.net: Steve Jobsのスピーチ、山口訳

まったく別のものを学ぶことで、違った視点で物事を考えることができるようになるよ。

関数型言語の難しさは、既に手続き型言語を使いこなしている人と、関数型言語で初めてプログラミングに触れる人とで違うのではないかと思われます。既に手続き型言語を知っている場合、その知識が関数型言語を使うにあたって邪魔になる可能性があります。そこで、どんな材料で勉強するにしても、まず一度、手続き型言語でマスターした概念をわきに置いてみることをお薦めします。具体的には…

1. 「こう書くと余分なメモリを食うのでは」とか「ここでコピーするともったいないな」とか「同じ計算を何度もしてるんじゃ?」みたいな、貧民的発想をいったん捨てましょう。無限の速度と無限のメモリを手にしているのだと思い込み (あるいは、処理系がものすごく賢くてうまいことやってくれるんだと信じて) **最初は** ナイーブなコードでいいと開きなおります

2. 手続き型言語でループを書くとき、アセンブラででもなければ条件分岐とgotoは使いませんよね。forやwhileなどを使うと思います。定型的な処理にはイディオムがあるわけです。関数型言語にもイディオムがあり、それは手続き型言語のものとかなり異なります。手続き型言語の知識をあてはめようとするのではなく、例を読んだり課題を解いたりする過程で関数型言語のイディオムを意識的に覚えるようにします。

3. 変数は値を入れる箱ではありません。値、あるいは式そのものに便宜的に名前をつけているだけです。

4. 計算は、つねに関数に値を渡し、その戻り値を使うことで進行します。戻り値は複数あるかもしれません。

5. 構造を持つデータの各要素に対して処理をしたい場合には、(a)その構造全体を一気に処理できる関数(例:map, fold等)を使うか、(b)その構造を「頭」と「残り」に分解し、「頭」を処理して、「残り」は自分自身を再帰で呼んで処理させ、最後に結果を合成します。

関数型言語(プログラミング言語Scheme, Haskellなど)を勉強しようと思っています。 初心者にも関数型言語のメリットや考えかたがスラスラ分かる勉強の材料を教えてくださ.. - 人力検索はてな
トラックバック - http://rubyist.g.hatena.ne.jp/muscovyduck/20090306

2008-03-31

[] consセル、ドット対、リスト  consセル、ドット対、リスト - バリケンのRuby日記 を含むブックマーク はてなブックマーク -  consセル、ドット対、リスト - バリケンのRuby日記  consセル、ドット対、リスト - バリケンのRuby日記 のブックマークコメント

今日はconsセル、ドット対、リストについて勉強するよ。

consセルとドット対

consセルとは、「値」と「その次のconsセル」という二つの参照を持ったものだよ。そして、consセルをLispで表現するには「ドット対」を使うよ。

「ドット対」は、二つの要素を参照できる表現で、たとえば

(123 . 456)

のように書くよ。最初の要素を取り出すにはcarを、2番目の要素を取り出すにはcdrを使うよ。

[1]> (car '(123 . 456))
123
[2]> (cdr '(123 . 456))
456
[3]>

リスト

さっきの例だとドット対ひとつで二つの要素しか参照できないけど、ドット対をconsセルとして使うことでたくさんの要素を一元的に扱うことができるよ。ドット対でconsセルを表現するには、「値」と「その次のconsセル(つまり次のドット対)」という表現を続けていけばいいよね。だから、

(1 . (2 . (3 . (4 . (5 . ())))))

と書くことで複数の要素を一括して扱えるようになったね。このデータ構造のことを「リスト」って言うみたいだよ。

そして実はこの表現は、Lispでは

(1 2 3 4 5)

と書いたのと同じことになるんだって。実際に評価して試してみよう!

[3]> '(1 . (2 . (3 . (4 . (5 . ())))))
(1 2 3 4 5)
[4]>

ということで、Lispでカッコでくくって複数の要素を列挙していたのは、実はリストだったんだね。だからLispのS式(の関数や特殊形式)は、リストでできているんだねえ。

トラックバック - http://rubyist.g.hatena.ne.jp/muscovyduck/20080331

2008-03-30

[] 評価(evaluation)  評価(evaluation) - バリケンのRuby日記 を含むブックマーク はてなブックマーク -  評価(evaluation) - バリケンのRuby日記  評価(evaluation) - バリケンのRuby日記 のブックマークコメント

今日は評価(evaluation)について勉強するよ。

評価(evaluation)

評価(evaluation)とは、「式を値にすること」だよ。Lispの場合は、「S式を値にすること」だね。

じゃあ、具体的に見てみるよ。

昨日もちょっと出てきたけど、Lispの式(S式)は一つには

(+ 1 2 3 4 5)

という感じで「一番最初に関数名(または特殊形式名)を表すシンボル、それ以降に値(または式)が列挙されたもの」をカッコでくくったもの、もうひとつには

1

のように単に値を書いたものもS式だったよね。そしてさらに

hoge

のように変数名だけを書いたものもS式だったよね。

それぞれについて見てみるよ。

関数(または特殊形式)を評価する

関数(または特殊形式)を評価すると、一番最初の関数名(または特殊形式名)を表すシンボルに関連付けられた関数(または特殊形式)が呼び出され、計算が行われて、その計算結果が戻り値になるよ。

関数を呼び出したときは、関数名の後に列挙された値(または式)がそれぞれすべて1回ずつ評価されて、それぞれの戻り値を関数の引数とするみたいだよ。

そして関数ではなくて特殊形式の場合は、すべての引数が評価されるとは限らないみたい。まったく評価されない引数があったり、1回だけ評価されたり、2回以上評価されたりもするみたいだよ。

値を評価する

値(のように見えるもの)を評価すると、その値が返ってくるよ。ちょっとややこしいけど、たとえば『「1」という表記』を評価すると『整数の1』が返ってくる、ということみたい。

変数名を評価する

変数名を評価すると、変数に代入されている値が返ってくるよ。

だから変数名そのもの(シンボル)が欲しいときは、「引数を評価せずに返す」quote特殊形式を使って

(quote hoge)

またはその構文糖衣の

'hoge

って書く必要があるんだったよね。

トラックバック - http://rubyist.g.hatena.ne.jp/muscovyduck/20080330

2008-03-29

[] S式  S式 - バリケンのRuby日記 を含むブックマーク はてなブックマーク -  S式 - バリケンのRuby日記  S式 - バリケンのRuby日記 のブックマークコメント

今まで何気なく「Lispの式」って言っていたけど、Lispの式のことを「S式(S-expression)」って言うみたい。

S式は、

(+ 1 2 3 4 5)

のような感じで、最初の要素が関数を表すシンボル、それ以降が値(または式)を列挙したもの、という構成になっているよ。

あ、あと値そのものもS式なんだって。だから

1

と書いただけでもS式だし、

hoge

という変数名だけでももちろんS式だよ。

[] On Lispがネットで読める!  On Lispがネットで読める! - バリケンのRuby日記 を含むブックマーク はてなブックマーク -  On Lispがネットで読める! - バリケンのRuby日記  On Lispがネットで読める! - バリケンのRuby日記 のブックマークコメント

http://b.hatena.ne.jp/entry/1097999

On Lispの日本語PDFが!

トラックバック - http://rubyist.g.hatena.ne.jp/muscovyduck/20080329

2008-03-28

[] 値の型を調べる  値の型を調べる - バリケンのRuby日記 を含むブックマーク はてなブックマーク -  値の型を調べる - バリケンのRuby日記  値の型を調べる - バリケンのRuby日記 のブックマークコメント

Rubyなら、「そのオブジェクトはどのクラスのインスタンスなの?」ということを調べるにはclassメソッドを使えばよかったよね。

irb(main):001:0> 123.class
=> Fixnum
irb(main):002:0> "hoge".class
=> String
irb(main):003:0> [1, 2, 3].class
=> Array
irb(main):004:0> 3.14.class
=> Float
irb(main):005:0> 100000000000000000.class
=> Bignum
irb(main):006:0>

Common Lispの場合は、「その値の型は何?」ということを調べるにはtype-ofを使えばいいみたいだよ。

[1]> (type-of 123)
(INTEGER 0 16777215)
[2]> (type-of 3.14)
SINGLE-FLOAT
[3]> (type-of "hoge")
(SIMPLE-BASE-STRING 4)
[4]> (type-of '(1 2 3))
CONS
[5]> (type-of 100000000000000)
(INTEGER (16777215))
[6]> (type-of 2/3)
RATIO
[7]>

うーん、「(INTEGER 0 16777215)」とか「(INTEGER (16777215))」という型の意味がよく分からないや。あとで調べなくっちゃ。

トラックバック - http://rubyist.g.hatena.ne.jp/muscovyduck/20080328