読者です 読者をやめる 読者になる 読者になる

第一回 関数型言語勉強会 大阪に行ってきた

44人の枠に一時期80人以上が申し込むという人気ぶりの勉強会、第一回 関数型言語勉強会 大阪に行ってきました。
とても面白い内容の発表ばかりで、行ってよかったです。

勉強会自体について

大阪は関数型言語に関する勉強会を開く土壌はある*1と思うのですが、今まであまり聞かなかったので、今後も続いてくれるとうれしいです。
もともとの主催者が多忙により勉強会に来れなかったのもありますが、運営面ではちょっとこなれてないな、という印象を受けたました。
今後続いていってほしい、という思いも込めて、気になった点を列挙します。

  • 発表タイトルが半数程度「未定」になっていた*2
  • ATND の地図が別の地点を指しており、騙された
  • 勉強会自体の概要の説明あったっけ?
  • 初心者に対するフォローがないに等しい*3
  • にも関わらず、前提知識が参加するまで不明*4
  • 電源や無線 LAN といった設備に関する説明が最初なかった*5
  • 最後時間が余ったのに、有効活用できていない*6

用語があばばばば

誤用すんな!とか言うつもりはないですが、曖昧に使ってると初心者をより混乱させることになるのではないのかなぁ、とか思うのです。

関数

「手続型言語での関数と関数型言語での関数は別物で、関数型言語の関数は数学的な関数だよ」的なアレ。
まぁより近くはあるだろうけど、それはそれでどうなんだ、という話もあります。
その関数って部分関数を言っているのか全域関数を言っているのか、そもそも停止性は・・・とかそういう。
数学「的」だからそのものじゃないよって意見はあるかもしれません。数学「の」関数だよと言ってしまうとどうなんだろ。
言葉尻をとらえすぎてますかね。

カリー化

その「カリー化」って何を指して言っていますか?というのがあります。

  • 複数引数の関数を、一引数関数のみで表す「カリー化」(currying)
  • 「カリー化」された関数(curried function)
  • タプル形式の関数を「カリー化」すること(curry)
  • タプル形式の関数を「カリー化」するための curry 関数(let curry f = fun a b -> f (a, b)とかそんな)

とりあえず、カリー化って言葉には色々と意味がある、ってことは頭の片隅にでも置いておくといいでしょう。
詳しい意味や、カリー化の利点については各自調べるということで。

末尾再帰

「末尾再帰に対応」とかって表現をされるとこう・・・
末尾再帰自体は何かの機能を指すわけではなく、単に再帰関数の形式の一つにすぎません。
乱暴に説明すると、「再帰呼び出しから戻ってきた後にすることが何も無いような再帰」のことです。
例えば Java で、

// 末尾再帰ではないfact
static int fact(int n) {
    if (n == 0) return 1;
    else return n * fact(n - 1); // 再帰部
}

は、再帰から戻ってきた後に、その結果と n を乗算する、という処理が残っています。
それに対して、

static int fact(int n) {
    return factImpl(n, 1);
}
// 末尾再帰なfactImpl
static int factImpl(int n, int acc) {
    if (n == 0) return acc;
    else return factImpl(n - 1, acc * n); // 再帰部
}

では、再帰から戻ってきた後はその結果を返すだけになっており、処理は残っていません。
で、この「末尾再帰」になっている再帰はループに変換することができ、それを「末尾最適化」と言います。
「末尾再帰に対応」という表現があった場合、まず間違いなく「末尾最適化に対応」のことを言っていると思っていいでしょう。


末尾最適化されると何が嬉しいか、というとそれはスタックオーバーフローが起きなくなるという一点に尽きます。
再帰呼び出しによるスタック消費がループになることでなくなるわけですから当然ですね。
なんで末尾再帰をループに変換できるのか、という話は各自調べるということで。

証明

証明って言葉を安易に使うとこわい人たちがこわいので、気を付けましょう。
同様に、検証とかもこわい人たちがこわいので、気を付けましょう。

いけがみさんの発表

初心者へのフォローという意味では、唯一といってもいい発表でした。
が、これは初心者向けどうこうを抜きにして素敵な発表でした。
Haskell が好きであるにもかかわらず、「Haskell に影響されすぎだ。自重しろ」とたしなめ*7、いけがみさんの思う関数型言語につて熱く語ってくれました。
発表資料は公開されており、これなかった人向けに書いた記事も用意するという素晴らしさ。
これ ust とか録画とかなかったのは本当に残念・・・

uskz さんの発表

おそらく一番置いてけぼりの人を出した発表であることは間違いないでしょう*8
あれをもって「関数型無理だわー」となってしまうのは色々と残念なので、とりあえずは「突っ走っていくとああいう世界もある」という程度の認識でお願いしたいところです。
「関数型こわい」ではなく、「uskz さんこわい」あたりでどうでしょうか。


このセッションでの発表資料は後でじっくり読み解きたいですね。

しゃみのさんの発表

まだ高専 5 年生って、俺の弟と同い年だー!
にもかかわらず何とも言い難いこの・・・えっと、その。弟にもっとがんばれと言いたい。いやマジで。
このセッションも uskz さんの発表に次いで、置いてけぼりの人を出した発表であるように思います。
これは前提条件色々とすっ飛ばしているためですので、まぁこの発表もとりあえず置いておいてもいいです。


このセッションの理解のためには、前提知識として

  • 代数的データ型 (一応 Bool と Either という説明はあったので、そのあたりから調べていくといいでしょう)
  • ラムダ計算 (ラムダ式ではなく)

の理解 (なんでそういうものが必要なの?という問いに答えられるだけの理解) が最低限必要でしょう。
代数的データ型はまだしも、ラムダ計算Wikipedia とかで真面目にやっても、そういう理解を得るのは難しいような気がします。
なのでこれも、とりあえずは「そんな世界もある」程度でいいのではないでしょうか。

関数型の利点?

マルチコア時代には状態を考えなくていい関数型が有利!的な話が一部あったのですが、正直これに関してはかなり懐疑的です。
タダ飯を食える時代は終わった、これからはマルチコア時代だからアプリケーションでの対応が必須!とか言われ始めてかなり経ちますが、実際どうですかね?
未だにタダ飯食ってる人多んじゃないですか?
確かにタダ飯食えなくなった人もいるでしょう。ですが、大多数の業務系プログラマはいまだにタダ飯を食らい続けているのです。


なんでか。
結局、当初の想定ほどマルチコアが普及していない、というのと、PC のユーザは現状の性能に満足しつつある、というのが大きいのではないでしょうか?
まわりを見てみると、ようやっとデュアルコアが普通になったかな、程度の普及率です。メインストリームはたぶんもうすぐクアッドコアが普通になっていくでしょうが、でも当初の想定よりかなり遅い速度ですよこれは。
これは CPU 性能向上の停滞を意味しているわけではありません。CPU の性能は年々向上しています。どこが? (もう伸びない、と言われて久しい)シングルスレッド性能が、です。
そしてほとんどのユーザ現状の性能に満足しつつあります。正しくは、マルチコア CPU を使わなければならないような用途に PC を使ってはいない、かもしれませんがまぁ同じことです。
CPU の性能は上がり続けているし、ユーザは満足しつつあるし、正直 IO 周りを何とかした方がよっぽど性能の向上を体感できる(HDDをSSDにするとか)。
こうして我々はタダ飯を食らい続けているのです。


ただ、マルチスレッドのプログラムをより安全に簡潔に間違いも少なく組める、というのは大きな利点ではないものの、確かな利点です。
今後、業務プログラムでも徐々にマルチスレッド対応が必要になる部分というのは徐々に増えていくかもしれません。
もしそうなったときには、このあたりはメリットとして見ることができるようになるでしょう。
でも、これはすぐにどうこう、という話ではないですよ、とだけ。

まとめ

いいこと言いますね。
別に、最初から今回の発表全部を理解しなきゃ関数型言語使っちゃいけない、とかって規則はないわけですし、そんなこと言ったら誰も関数型言語使えなくなっちゃう。
もっとこう、軽い気持ちで始めてみてもいいと思うんです。
そのためにはいけがみさんの発表で出てきたような本を読んでみるのがいいでしょう。
分からなかったら、人に聞いてみればいいでしょう。
聞く人がいなければ、勉強会でも開催してみればいいでしょう。


最後に、関数型プログラミングやってみたい人に向けて (主に静的型付きの) 関数型の利点を伝えている Web 上の資料を紹介しておこうと思います。

[http
//www.itpl.co.jp/tech/func/essense_of_fp(sea0305).pdf:title=函数プログラミングのエッセンスと考え方]:いけがみさんの記事で参考にされていた資料で、名古屋の小笠原さん作の資料です。
[http
//www.slideshare.net/osiire/3-8660480:title=Start F#!]:これも小笠原さんの資料で、非関数型プログラマ向けに丁寧に「F# は何が嬉しいか」を解説しています。
[http
//www.slideshare.net/bleistift/cvbf:title=C#/VBプログラマのためのF#入門]:拙作の資料で、F#の紹介になっています。
[http
//www.atmarkit.co.jp/fdotnet/special/introfs_01/introfs_01_01.html:title=F#で初めての関数型プログラミング]:ちょっと前に書いた記事で、関数型プログラミングで割と勘違いされがちな部分を重点的に解説しました。

F# に偏ってる?いや、名古屋に偏ってるんだ!(何

*1:某大学とか某大学とか某大学とかあるので

*2:概要くらいは開催前までに埋めてほしいかも

*3:この勉強会をどのような位置づけに考えているかでやり方は変わるだろうけど、入門レベルの人をどうするか、というのは考えた方がいいとは思う

*4:このあたりはわんくま勉強会の発表毎のレベル表記はそれなりにいいと思う。3段階くらいでいいと思うけど

*5:使っていいのであれば、開催前にホワイトボードなどに書いておいてくれた方がありがたい

*6:他の勉強会の宣伝など、関西のコミュニティをかき混ぜるための時間にするなどすればよかったのでは

*7:確かに、「関数型言語」と言いつつ Haskell のことを言っている発表は多かった

*8:あれをあの発表の中だけで理解できた人はいないのでは