LisperはなぜLispが読みやすいし書きやすいと思うのか?
まぁ、なんというか、Lispネタです。はい。
括弧のせいで挫折した!
なんかこういう話をよく聞く。ぶっちゃけ、あなたがちゃんと真面目に読んでないからでは?とか思ったりするのだが、まぁそれは置いておこう。
要は、括弧が多過ぎて、カッコとコッカの対応が取れないというあたりかな?挫折する理由としては。何となく思うのが
エディタが良くない
多くの場合コレだと思う。あと
書き方が良くない
まぁコレもあるよね。地味に全然インデントしてなかったりする。そりゃあ読みにくいですよ。
大学のセンセの教え方が良くない!
知るか!
Lispが読みやすい理由、書きやすい理由
そもそもなんでみんなキモイと言うのか?
だいたい、Lispに疎い人に、Lispがキモイ理由を聞けば以下の2つの理由を挙げてくるんだ。
- 「括弧が多い」から
- 前置記法だから
しかし、これには僕は反論する。むしろ、「括弧が多い」「前置記法」はむしろ、Lispの利点なのだ!
中値記法はよみにくい!
僕は、「中置記法」は読みにくいと思う。なぜか?中置記法こそが曖昧にする原因だからだ!
そもそも、「中置記法」が実装されたのは数学の加減乗除によるところが多い。普段数学では中置記法で演算する。だからプログラムでも同様に表現したい欲求があって、中置記法を用いたと思う。
1 + 2 * 3 + 4 - 5 / 6
しかし、どうだろう?数学的に表現したいから、という目的のためだけに中置記法を用意するのか?と思う。ぶっちゃけ、加減乗除の表現だけが読みやすくなっただけのように思う。
一方、中置記法は構文木からは遠い表現である。前置記法と比べて、計算式を見て、構文木を構築するのは大変だと思う。
以下のコードを見てほしい。rubyで実行すると3が返ってくる
1 + 2 * 3 + 4 == 1 + 2 / 5 && 10 <= 10 + 20 || 1 + 2
これは非常に読みにくいと思う。なぜ読みにくいのだろうか?
構文木の根が分かり辛いからだ。
前置記法的に書き換えてみよう
|| && == + + 1 * 2 3 4 + 1 / 2 5 <= 10 + 10 20 + 1 2
これも、大分キモイが、少なくとも、一番左の演算が構文木の根の演算と言うことは理解できる。
これにはもう一つ重要な点がある。前置記法は演算の優先順位なんて必要がないのだ!逆にいえば、中置記法は演算の優先順位を考えなければならない。これは、実装する側にとっても、利用する側にとっても大きな負担になる。実装する側は自然な優先順位を考えないといけないし、利用者は優先順位を覚えないといけないからだ!
括弧はより読みやすくするために存在する
これは中値記法であっても、前置記法であっても同様だと思う。
((1 + 2 * 3 + 4) == (1 + 2 / 5) && (10 <= 10 + 20)) || (1 + 2)
一瞬で木が見えるようになったのではないだろうか?
さっきの、前置記法に括弧を付けてみよう
(|| (&& (== (+ (+ 1 (* 2 3)) 4) (+ 1 (/ 2 5)) (<= 10 (+ 10 20) ) (+ 1 2))
キモイ。だが、これに前置記法にインデントを付けたらどうだろうか?
(|| (&& (== (+ (+ 1 (* 2 3)) 4) (+ 1 (/ 2 5)) (<= 10 (+ 10 20)) (+ 1 2))
見やすくなったのではなかろうか?
Pythonまたはそれに類する言語以外で、Lispほどインデントが重要な言語は無い。もし、LIsperがLispコードが読みにくいときは、ほとんどの場合、インデントされてない時だ!
中置記法の括弧は書き辛い!
以下の例を考えよう。これは、実際に書いてもらいたい。
((((1 + 2) * ((2 + 3) / (3 - 4))) + (5 / 6))
これは非常に書き辛い。なぜ書き辛いのだろうか?
それは、
式を書く時、構文木の深さが分からないため、最初にどのぐらい括弧を書けばいいか分からないからである。
この式を書く時、どれだけの人が最初に(((が書けるのだろうか?
では、前置記法はどうだろうか?
(+ (* (/ (+ 2 3) (- 3 4)) (+ 1 2)) (/ 5 6))
すごく書きやすい。なぜなら、構文木の根から書くため、構文木の深さが分からなくても、式が書けるからである。最後に括弧の帳尻合わせをすればいい。
つまり、Lispは自然と括弧が書きやすいように出来ているのだ。
まとめ
Lispは読みやすくて書きやすい。なぜなら、それは、「前置記法と括弧」が構文木を根から明確にし、また、自然と括弧が書きやすい様になっているからである。
中置記法は、構文を曖昧にし、演算子の優先順位、右結合性、左結合性などを考えなければならず、より自然になるどころか、より言語として複雑になる可能性を秘めている。
少なくとも、「Lispが読みやすくて書きやすい」と言うのは、ただのLispキチガイではなく、むしろ自然なことなのだ! <- ココ大事。
追記 : 中置記法を糞みたいに言ったが、もちろん、中置記法の方が数学的な記述は自然だ。コレだけは言っておく。しかし、それを実現するために、言語をより複雑にするのはどうだろうか?
追記2: 言われると思ったがやっぱり指摘されたので、補足しておくと、Smalltalkとかの中置記法は、演算(というか全部メッセージなので)の優先順位はなく、すべて等しいですが、数学的な演算の順番とは異なるので、あえて言いませんでした。(このことについては後のブログに書き散らかします)