言葉の式というのを小学生の時に習った。算数の文章題を解くために、式を立てる前に言葉で表現してから数式を作る。そのための言葉でできた式を言葉の式と呼んでいた。
例: りんご5個とみかん10個買った。代金の合計は1500円だった。りんご1個の値段はみかん1個より30円高い。みかんは1個いくらか。
(りんご1つの値段) * (りんごを買った個数) + (みかん1つの値段) * (みかんを買った個数) = (代金)
(りんご1つの値段)- (みかん1つの値段) = (りんごがみかんよりもいくら高いか)
これが言葉の式である。そのあとの数字で置き換える。
(りんご1つの値段) * 5個 + (みかん1つの値段) * 10個 = 1500円
(りんご1つの値段)- (みかん1つの値段) = 30円
方程式という概念を学んでしまうとともすればこういうステップを飛ばしてしまいがちではある。例えば言葉の式の世界においては、以下のようにしてはいけない。
(りんご) * 5 + (みかん) * 10 = 1500
(りんご)- (みかん) = 30
それが何を示しているのか、ということを少しサボって理解せずにいると、気がつけば何をやっているのかわからなくなってしまうということもある。そういう時には言葉の式に立ち戻ってちゃんと自分の言葉で問題を表現する。小学生の頃だったので言われたものをそのまま黙々とやっていただけなのであるが、今思えばこれは問題に対する抽象を考えるというためのトレーニングだったのだと言える。
言葉の式の考え方は私が様々な規則のある物事を考えるために役立っている。プログラムもその一環である。ファイルを読み込んで1行ずつscanする。これをプログラムに落とし込む。
f, err := os.Open(path) // ファイルを開いて
if err != nil {
return err
}
defer f.Close()
scanner := bufio.NewScanner(f) // スキャナにセットする
プログラムを書いたことがある人にはパッと見てわかるかもしれない。しかしプログラムを書いたことのない人にはわかりづらいかもしれない。こうした怪しい文字列を見ただけで拒絶反応を出してしまう人もいるだろう。僕のようなプログラマだって、直接この文字列を使って会話をしているわけではない(もちろんそういう風に見えることだってあることは否定しないけれど)。ここに書かれていることが何をしているのかを母国語ないし英語として理解してから、プログラムを理解している。ある程度プログラムを書いたことのある人ならば、他の言語で書かれているものもなんとなく理解できることが多い。もちろん「なぜプログラムが動くのか」「ファイルとはどのように扱うものか」という前提知識があるとさらに理解しやすくなる。とはいえ細かい振る舞いまでは知らなくとも、どういうことをしているかというのはおおよその見当がつくものである。
プログラムの字面自体も言葉の式に落とし込むことができる。しかし普段はもう少しプログラムから離れたものでも言葉の式に落とし込んでいる。新しい機能を作るときに、「なぜこの機能を作る必要があるか」ということを考えるとしよう。もちろん「作りたいから作る」という熱い気持ちでガッと作ってしまうこともなくはないが、多くの場合は優先順位を立てて、「それを本当に作るべきかどうか」という議論であったり判断をすることになる。この時に私は説明的な文章で考えを整理し、同僚やマネージャーに共有するということを日常的にしている。「事業およびシステムの背景と現状」「現状の課題と問題点」「それに対する解決法とアプローチ」「期待される成果」というあたりのトピックをまとめて書くようにしている。いわゆるデザインドキュメントと言われているものに近いのかもしれない。
プログラムそれ自体にとってはデザインドキュメントというのは少し遠い場所にあるように思われるかもしれない。私としては「なぜそれを作るか」というのは、コードの質やその表現以上に大事なことがあると考えている。プロダクトにフェーズや事業の状況にもよるかもしれないが、私の関わっている環境ではどちらかというと「何を作るのか」の判断の積み重ねが事業に影響を与えやすいことがほとんどだった。結果として「なぜ」に対する「どのように」の実現がプログラムとして現れるのである。デザインドキュメントというのは機能に対する理由付けを抽象を使って文章で表現する手段である。「なぜ」という抽象を言葉に落とし込んで、そしてそれをまた「どのように」やるかを設計する。「どのように」をさらに言葉に落とし込んで、プログラムを書いている。
ということをlexerを書いていてふと思ったので、文章に起こしてみた次第である。