小説家になろう

第1話: 手続き型しか知らない俺が美少女の女子高生に関数型プログラミングを学ばされることになったんだが

More than 3 years have passed since last update.


序文: 著者(?)より

 多くの人々に、このような拙い文章が目に触れられ、本当に恐縮しています。

 自分の構成のまずさから、ちょっとした誤解が生まれているようなので、カッコ悪いですけれど、序文を。

この小説はある程度連続していて、この第一話においては、現状として「関数型プログラミング」の導入くらいの位置付けにして頂ければと思っています(例えば、本来ならば参照透明高階関数の話などが必要になるかとは思われるのですが、そこは順に追って書ければ、と思っています)

 もちろん、本文中について問題があるところ、また「関数型プログラミングってこうじゃなかったっけ?」というご意見に関しては、教えて頂ければ、検討し、改善していきたいと思っています。よろしくお願いします。


始まり

 新しい門出には必ず希望と可能性に心を踊らせると思う。

この僕も、この高校に入ってから、今後の学校生活についてわくわくしていた。手元にある部活パンフレットをちらちらと眺めながら、華やかな高校生活に想いを寄せていた。マンモス校と言われるだけあって、たくさんの部活がそこには掲載され、中には「触手研究会」とか「マシマズ部」など、何が楽しいのかさっぱりわからないものまで含まれていた。

 まず目に引いたのはパソコン部だった。

 「これからの時代は情報社会を制するものは世界を制する」という、訳の分からぬ意識の高さを持っていた僕は、その部活の説明会に出ようと思った。まかりなりにも、PHPくらいなら、簡単なプログラムが書ける。そう思って、パソコン部への道を急ぐと、途中でツインテールの金髪の少女に行く手を阻まれた。

「あなた、コンピューターに興味があるの」

「そうだよ、僕は今からパソコン部に……」

「ダメ、あなたはプログラムが書けるのでしょ、そういう目つきをしている。あんな部活入っちゃだめ。Lispを括弧が多いからという理由で気持ち悪がるようなレベルの低い人間達の集まりよ」

面倒臭い人間に捕まってしまった。

「まあいいわ。私たちは『副作用部』と呼ばれる部員の一人、蓮家藻等(はすいえ もなど)。さっそくだけど、あなたをテストしたいわ、ついてらっしゃい」

 そう手を引っ張ると、小汚い一室まで連れて行かれてしまった。やれやれ、希望に満ちた高校生活が、一気に灰色にしまったようで、すこしため息をついた。


命令型言語

「部長! 新入生候補連れてきました! こいつ、プログラミングができるようですよ」

 奥の机で、大量の本に囲まれた女性?がこちらを振り向いた。長髪で、髪の毛がぼさぼさで、しかも眼鏡は油まみれだ。一瞬、男性だと言われても、気がつかないだろう。

「あー、貴方が……ちょっと今から入会案内をするから、待っててね」

 そう言って読んでいた本を机に置く。タイトルは『型システム入門』。いまさら入門書なんだから、そんな人の部活を批判するほどレベルなんて高くないんじゃ……。

「はい、これは、『たのしい開発 Ruby』。これでRubyの文法をざっと覚えて。あとPHPは……正直わからないの。別にPHPでもいいけど、ちょっと説明が面倒くさいし。チュートリアルは1時間後。それまでに目を通して」

 言われるままに、僕は黙ってその本を読み始めた。周りが読んでいる本も、『データ構造とアルゴリズム入門』とか『関数型プログラミング入門』とか、そういう本ばっかりだ。こんな入門書ばっかり読んでいる部活で、本当にいいのだろうか。

「はいーーーーー!タイム切れですよーーーーー!」

 そういって、ドラを叩く小柄の少女。この子も、この部活の部員だろうか? その衝撃に僕はびっくりして、読んだ本の半分を忘れるところだった。

「いまから問題をやりまーす!さらっと仕様をこのホワイトボードに書くので、それに合わせてRubyで実装してくださいー!」

 ボワイトボードは、元のインクが染み付いていて汚かった。そういうのをあまり気にしないタイプなのだろうか。


問題

以下のような関数を実装しなさい。

* この関数は第一引数に数値だけで構成されている配列を取ります
* 返却する値は、"Result"という文字列と、第一引数に渡された配列(例としては:[3, 9 ,6])の最初の要素(この場合は3)の二倍で組み合わされた配列です
* 具体的には第一引数が[1, 2, 3]だと、期待される返却値は["Result", 2]となります

この問題を見たとき、正直バカにされていると思った。Rubyのことはなんとなくわかった。つまり、こう書けばいい。

def imp(x)

a = []
a.push("Result")

y = x[0]
z = y * 2
a.push(z)

return a
end

先ほどの蓮家が覗き込んで、「0点」と呟いた。

「なんでだよ、仕様通りじゃないか、何がおかしいのか」

そういうと、部長と呼ばしき少女が、奥から古めかしい本を取り出してきた。タイトルは『On Lisp』。そこからある一節を朗読しはじめた。


「命令型プログラムを関数型プログラムに変換するうまい方法がある。この方法は完成した他コードに適用することから始めるといい。すぐに勘が働くようになり、コードを書きながら変換できるようになるだろう。そうすればあっという間に、初めから関数型プログラミング用語でプログラムを考えるようになるだろう。この方法は、命令型プログラミングは関数型プログラムを裏返しにしたものと思うことだ。関数型プログラムが命令型プログラムの中に隠されているのを見つけるには、ただ裏返しにすればいい。」


そう言い終わると、部長はまた、古書が山積みになった机に戻り、「ラムダ、ラムダ」とつぶやきはじめた。僕はただ、この言葉を聞いても、何を意味するかわからなかった。


変数をわざわざ使わなくても良い???

 先ほどのドラを鳴らしたショートカットの女の子が、こちらをパタパタと叩いてきた。

「じゃー、研修を始めるぞ!私は数奇六イリス(すうきむ いりす)。さあ始めましょ」

 うーむ、展開が早くてついていけない……。

「えーと、部長は裏返しにすればいいっていう話をしたんだよね。そもそもこれは何が必要なんだっけ?」

「配列かな?」

「あー、じゃあまずこういう風に定義するといいかもね」

def fun(x)

[]
end

「あれ、最後のreturnは?」

「まー、途中で値を返すときはreturnがあったほうがいいけど、できるだけ使わないほうがいいかもね。現実はそう甘くいかないけど、基本はreturnなしでなんとかやっていくとベターだね、Rubyでは」

そういうものか、と思いながら話を聞く。

「で、この要素に必要だったのは、"Result"と、引数に渡された配列の一番目だったよね。まあ二つの要素が必要だってわかってるんだから、こう書ける」

def fun(x)

["Result", 4]
end

「いや、これどこでx使うのよ」

「慌てない慌てない。この4っていうのが、本来はxの配列の最初のものだったでしょ?それをそのまま式にするといいんだよ」

def fun(x)

["Result", x[0] * 2]
end

「はい、完成。100点とはいわないけれど、これが合格かな。別にayzもいらないでしょ?」

 僕はこれをみて、ふーんと思うけれど、でもこれが実際に何が意味があるのかわからなかった。

「まあ、わかるんだけどさ……でも、これ別にどっちでもよさそうな気がするんだけど」

「まだわからないかなー、じゃあ次この問題やってみて」

関数に数値のみで構成されている配列が渡されたとき、これらの要素を二倍にして返す関数を定義しなさい

うーん、この問題の意味が、未だにわからない。こんなもの、プログラミングの初歩の初歩だし……

とりあえず、Rubyにもforがあったから、それを使ってみよう。

def imp(x_array)

a = []
for x in x_array
y = x * 2
a.push(y)
end
return a
end

少女は首をひねり、ちょっとため息をついた。

「うーん、確かにこういうコードはよく見るけど……」

僕は何が悪いのかさっぱりわからなかった。これでもちゃんと動くものだし。

「えーとね、まずこの問題を細かく分解してみようよ。まず一つには要素を二倍にするということと、それを配列に適用するという二つの問題に区分けできるよね」

「うん、まあ上のコードはそういう風に書いたつもりだよ」

「でもね、この二つはそのものズバリの方法があるんだよ。ちょっと見てみてね」

というと、少女はホワイトボードに一行で書き下し始めた。ただ背が低いのか、下のホワイトボードを使うので必死だけど。

def fun(x)

x.map { |x| x * 2 }
end

そこに現れたのは、簡潔なコードだった。

「つまりさ、要素を二倍にする配列に適用するという二つのパーツがあればいいの。片方はmapと言われるもので、後ろのやつはRubyだとblockとかになるのかな。でも呼び名は正直どうでもよくて、要するに配列に何かの操作を加えることと、二倍にするってことは別々にわけられるということが確認できればいいの」

なんだか抽象的でわかりにくい。わかるようでわからない絶妙な……。

「前のコードが余計なのは、私たちは配列の要素を二倍にするということだけ考えたかったのに、配列に要素を追加するとか、あるいはブロックを繰り返すということを考えないといけなかったわけ。そこは、私たちのやりたいことの本質ではない。そうでしょ?」

「つまり……僕がやっていることは、それらのやりたいことに対して本質的ではないものがあまりにも入っていて、それを自明に考えすぎてしまっている。それに直結するような表現があれば、それを利用したほうがいい、と」

「ご名答! そして、関数型プログラミングを学べば、そのあたりのことがだんだんクリアになってくるってわけさ!」

最初は、変な部活に連れてこまれたと思ったけれど、だんだんと興味を持ち始めてきた。もちろん、まだ意味がわからないところが多いけれど、ちゃんと勉強すれば、もっと面白いことができるかもしれない……。でもこの人たち面倒臭そうで……。

「じゃあ、後日改めて入部するかどうか考えてみます、今日はこのへんで」

部長は顔を上げると、壁を指差した。入部者の名前がぶら下げられている板の最後に「服紗陽(ふくさよう……僕の名前だ!)」がぶら下がっている。

「えっ、ちょ、なんでもう入部に」

「じゃあ、明日は授業が終わったら部室に来るように。今日の活動はこれで解散」

「途中においしいドーナッツ屋ができたから食べに行こう」

「あーいいねいいね」

どやどやと彼女たちが退出すると、僕は一人取り残されてしまった。僕は一体どうなるんだろう。ただ、ウェブサービスとか、ゲームとか、スマートフォンアプリとか、そういうのを作りたかっただけなのに……


第2話へ続く

第2話へ