関数型言語(プログラミング言語Scheme, Haskellなど)を勉強しようと思っています。

初心者にも関数型言語のメリットや考えかたがスラスラ分かる勉強の材料を教えてください。
言語の習得よりも、関数型言語の考え方の習得に重きを置いています。

例えば
- この本を読め
- このサイトを読め
のように、入門から実用レベルまできちんと筋の通ったものをお願いします。

ちなみに
以前Schemeを勉強しましたが末尾再起辺りでなんとなくうやむやになってしまいました。
あと「計算機プログラムの構造と解釈」は僕には難しすぎでした。

回答の条件
  • 1人5回まで
  • 登録:2006/03/30 19:23:59
  • 終了:2006/04/01 13:04:49

ベストアンサー

id:practicalscheme No.3

practicalscheme回答回数157ベストアンサー獲得回数422006/03/31 12:11:54

ポイント300pt

なかなか難しい質問です。一冊あるいは一サイト、決定版と言えるようなものは思い当たりません。しかし関数型言語やそのアプローチについては最近関心が高まりつつあるようで、ギャップを埋める入門書が徐々に出てくると思われます (例えば青木さんの「ふつうのHaskellプログラミング」 http://i.loveruby.net/d/20060323.html#p02 。5月末出版だそうです)。というわけで、「これ!」という一冊の本で勉強したいのならもう少し待ってみるというのも手です。

さて、現在ある材料で勉強するとして、higeponさんのリクエストを考えてみます。

[とっかかり]

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

  1. 「こう書くと余分なメモリを食うのでは」とか「ここでコピーするともったいないな」とか「同じ計算を何度もしてるんじゃ?」みたいな、貧民的発想をいったん捨てましょう。無限の速度と無限のメモリを手にしているのだと思い込み (あるいは、処理系がものすごく賢くてうまいことやってくれるんだと信じて) **最初は** ナイーブなコードでいいと開きなおります
  2. 手続き型言語でループを書くとき、アセンブラででもなければ条件分岐とgotoは使いませんよね。forやwhileなどを使うと思います。定型的な処理にはイディオムがあるわけです。関数型言語にもイディオムがあり、それは手続き型言語のものとかなり異なります。手続き型言語の知識をあてはめようとするのではなく、例を読んだり課題を解いたりする過程で関数型言語のイディオムを意識的に覚えるようにします。
  3. 変数は値を入れる箱ではありません。値、あるいは式そのものに便宜的に名前をつけているだけです。
  4. 計算は、つねに関数に値を渡し、その戻り値を使うことで進行します。戻り値は複数あるかもしれません。
  5. 構造を持つデータの各要素に対して処理をしたい場合には、(a)その構造全体を一気に処理できる関数(例:map, fold等)を使うか、(b)その構造を「頭」と「残り」に分解し、「頭」を処理して、「残り」は自分自身を再帰で呼んで処理させ、最後に結果を合成します。

まあこんな感じのことを頭において、

などに練習問題も含めてトライしてみたらいかがでしょうか (Schemeの例ばかりですが、他の関数型言語にも似たようなものがあると思います)。確かにこれらは言語の習得 (HtDPはもっと一般的ですが) に重点を置いていますが、上に挙げたような「違う見方を得る」ことに注意していると、得られるものが違ってくると思います。

[舞台裏]

富豪的とは言われても、裏でプログラムがどう動いているかは気になるもの。特に手続き型言語でがりがりプログラムを書いていた人にとっては、関数型言語のプログラムが実際にどのような手順で実行されているかを知ることによって、関数型言語への理解が深まることもあります。

それには処理系を読んでみるのが一番なのですが、フルセットの処理系はコードベースも大きくなりがちなうえ、色々なおまけがついていて本質的なところが見えにくいかもしれません。サブセットのMLコンパイラの実装を解説したこれなんかは参考になるかもしれません。

コンパイラを読むことで、関数型言語であってもある程度どのような機械語に落ちているかを意識することができるようになります (関数型言語のイディオムを習得した後でこの段階に進んで下さい)。


[実用へ]

最後に関数型のメリットですが、これは中規模以上の実用的なプログラムを書いてメンテナンスしてみないと肌で感じるのが難しい領域だと思います。大規模プログラミングで最も重要な要素はモジュラリティであり、それが関数型プログラミングの最大の利点のひとつでもあるからです。この論文はその点を簡潔に述べています:

ですが、この論文を「そうだよな〜」と納得しながら読める人は、既に関数型言語をよく知っている人だけなのではないか、という気がします。ですので、関数型言語についてのメリットを本当に知りたいと思うなら、それによってプログラムを書いてみるしかないのではないかと思います。

id:higepon

大変ご丁寧な回答ありがとうございます。

特に取っ掛かりの部分はとても分かりやすく感激しました。

2006/04/01 13:02:29

その他の回答(4件)

id:takkan_m No.1

takkanm回答回数3ベストアンサー獲得回数02006/03/30 21:34:47

ポイント50pt

Haskellプログラミング

「情報処理」で連載されているHaskellプログラミングの連載を読むことができます。最初の方で関数型について説明されています。

プログラム工学VI 授業関連資料

大学での講義資料です。

id:higepon

ありがとうございます!

2006/04/01 13:03:19
id:jmk No.2

jmk回答回数3ベストアンサー獲得回数12006/03/31 11:05:06

ポイント50pt

OCaml でよければ

Objective Caml 入門

は非常に優れた入門です。

関数型言語的な考え方はよく理解できると思います。

id:higepon

ありがとうございます!

2006/04/01 13:03:29
id:practicalscheme No.3

practicalscheme回答回数157ベストアンサー獲得回数422006/03/31 12:11:54ここでベストアンサー

ポイント300pt

なかなか難しい質問です。一冊あるいは一サイト、決定版と言えるようなものは思い当たりません。しかし関数型言語やそのアプローチについては最近関心が高まりつつあるようで、ギャップを埋める入門書が徐々に出てくると思われます (例えば青木さんの「ふつうのHaskellプログラミング」 http://i.loveruby.net/d/20060323.html#p02 。5月末出版だそうです)。というわけで、「これ!」という一冊の本で勉強したいのならもう少し待ってみるというのも手です。

さて、現在ある材料で勉強するとして、higeponさんのリクエストを考えてみます。

[とっかかり]

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

  1. 「こう書くと余分なメモリを食うのでは」とか「ここでコピーするともったいないな」とか「同じ計算を何度もしてるんじゃ?」みたいな、貧民的発想をいったん捨てましょう。無限の速度と無限のメモリを手にしているのだと思い込み (あるいは、処理系がものすごく賢くてうまいことやってくれるんだと信じて) **最初は** ナイーブなコードでいいと開きなおります
  2. 手続き型言語でループを書くとき、アセンブラででもなければ条件分岐とgotoは使いませんよね。forやwhileなどを使うと思います。定型的な処理にはイディオムがあるわけです。関数型言語にもイディオムがあり、それは手続き型言語のものとかなり異なります。手続き型言語の知識をあてはめようとするのではなく、例を読んだり課題を解いたりする過程で関数型言語のイディオムを意識的に覚えるようにします。
  3. 変数は値を入れる箱ではありません。値、あるいは式そのものに便宜的に名前をつけているだけです。
  4. 計算は、つねに関数に値を渡し、その戻り値を使うことで進行します。戻り値は複数あるかもしれません。
  5. 構造を持つデータの各要素に対して処理をしたい場合には、(a)その構造全体を一気に処理できる関数(例:map, fold等)を使うか、(b)その構造を「頭」と「残り」に分解し、「頭」を処理して、「残り」は自分自身を再帰で呼んで処理させ、最後に結果を合成します。

まあこんな感じのことを頭において、

などに練習問題も含めてトライしてみたらいかがでしょうか (Schemeの例ばかりですが、他の関数型言語にも似たようなものがあると思います)。確かにこれらは言語の習得 (HtDPはもっと一般的ですが) に重点を置いていますが、上に挙げたような「違う見方を得る」ことに注意していると、得られるものが違ってくると思います。

[舞台裏]

富豪的とは言われても、裏でプログラムがどう動いているかは気になるもの。特に手続き型言語でがりがりプログラムを書いていた人にとっては、関数型言語のプログラムが実際にどのような手順で実行されているかを知ることによって、関数型言語への理解が深まることもあります。

それには処理系を読んでみるのが一番なのですが、フルセットの処理系はコードベースも大きくなりがちなうえ、色々なおまけがついていて本質的なところが見えにくいかもしれません。サブセットのMLコンパイラの実装を解説したこれなんかは参考になるかもしれません。

コンパイラを読むことで、関数型言語であってもある程度どのような機械語に落ちているかを意識することができるようになります (関数型言語のイディオムを習得した後でこの段階に進んで下さい)。


[実用へ]

最後に関数型のメリットですが、これは中規模以上の実用的なプログラムを書いてメンテナンスしてみないと肌で感じるのが難しい領域だと思います。大規模プログラミングで最も重要な要素はモジュラリティであり、それが関数型プログラミングの最大の利点のひとつでもあるからです。この論文はその点を簡潔に述べています:

ですが、この論文を「そうだよな〜」と納得しながら読める人は、既に関数型言語をよく知っている人だけなのではないか、という気がします。ですので、関数型言語についてのメリットを本当に知りたいと思うなら、それによってプログラムを書いてみるしかないのではないかと思います。

id:higepon

大変ご丁寧な回答ありがとうございます。

特に取っ掛かりの部分はとても分かりやすく感激しました。

2006/04/01 13:02:29
id:hiroyuki_t No.4

hiroyuki_t回答回数7ベストアンサー獲得回数02006/03/31 12:17:00

ポイント50pt

http://www.hyuki.com/haskell/200412

Haskellのコードが載っています。

考え方の参考になるのではないでしょうか?

id:higepon

ありがとうございます

2006/04/01 13:03:40
id:hengsu No.5

hengsu回答回数185ベストアンサー獲得回数102006/03/31 12:54:50

ポイント50pt

http://www.sampou.org/haskell/tutorial-j/goodies.html

入門書として読んでますが、他にも読みたいです。

id:higepon

ありがとうございます。

2006/04/01 13:03:50
  • id:nashitenano
    初めての人のためのLISP ソフトウェアライブラリ (3)
    竹内 郁雄 (著)
    LISPですので、Schemeの文法を覚えたいとかには向きませんが、
    関数型言語の入門としては、よい本だと思います。
    古書でないと見つからないと思いますが。
  • id:cutsea
    > あと「計算機プログラムの構造と解釈」は僕には難しすぎでした。

    あの本は決して難しくはないと思うのですが、日本語訳が変なところがあるのも
    有名な話なので、???と思うような場合は自分の理解力を疑う前に
    原書の対応する場所を読むのが良いかもしれません。
    原書はWebでも公開されてますので購入する必要ありませんし。

    回答になってませんが、やっぱり私の知る限りではSICPが一番オススメですよ。

この質問への反応(ブックマークコメント)

トラックバック

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

絞り込み :
はてなココの「ともだち」を表示します。
回答リクエストを送信したユーザーはいません