実験も兼ねて。
valvallowさんを真似て、
github使ってみようかな、と。
まあ、単に今のままでは、ブログにコード貼り付けると、<pre>タグ使っててもインデントがズレて嫌なわけですよ。どうにかなんねえのかな、とか思ってて。
んで、valvallowさんが
gist使ってうまい具合にやってるんで、それを真似してみよう、って思ったわけです。で、まあ、gitそのものは要らなかったよね(笑)。gistとgitって違うみてえ(笑)。レポジトリ、なんて作らんで良かった、って話なんですが(笑)。単にアカウント取れば良かっただけの話、と言うオチ(笑)。
それはさておき。LOLをvalvallowさんに続いて読んでるわけですが。他の人の意見はともかくとして
読みづれえ。
いや、地の文体がどーの、って話じゃないです。単に
コードが読みづらいって話なんだよな(苦笑)。精読試みると引っかかっていけねえや。
第3章、リードマクロからもうこれが破壊的操作の嵐でさ(苦笑)。こんなんここまでやる必要あんのか?とかぶっちゃけ思ってしまいました。もちろん、効率性考えれば必要になるケースってのがあるんですが、僕が思うトコ、この著者って
美的観点ってのが全くねえんじゃねえの、とか思ってるのです(笑)。不遜ですけどね。
いやね、実際問題。無頓着にコード書いてるようにしか見えないし、心情的にはSchemerの筈のポール・グレアムも「こりゃあねえだろ」と思うんじゃねえのかな、と(笑)。そこまでいかんでも、ここに列挙されてるコードを他の言語のユーザーが見たら
「不必要に括弧が多すぎ!これだからLisperはよお。」
とか思うんじゃねえのか、と(笑)。ケンケンガクガクですよ(笑)。マジな話でさ。
リードマクロって考え方自体は単純ですよね。単に関数書いてやって、それを
set-dispatch-macro-characterで文字指定してやってその関数と関連付けちゃえばおしまい、です。普通にマクロ書くよりラクかもしれませんね。
set-dispatch-macro-characterって長ったらしい名前もEmacs + SLIMEだったらEsc-Tabで補完しちゃえばラクラク記述可能です。Viva! Emacs!
問題はその
関数の書き方だ。個人的には川合史朗さんが
何でも再帰で記述してたような「ローカル関数を設計」してやった方が見た目スッキリすんじゃねえの?とか思うんですけどねえ。生粋のCLerだと違うのかな。
doは副作用使う時は確かに便利なんですけど、このケースじゃそんなの多用する必然性がそんなねえんじゃねえの、って思いました。
まず最初。LOLのSHARP-DOUBLE-QUOTEを書き直したものです。多分Schemeやってる人はこっちの方が見やすいのでは、と思います。オリジナルのコードは破壊的操作しまくりですが、そのテの操作は一切止めています(笑)。
そもそも、Doug Hoyteって人は
defunの「暗黙の
progn」アテにし過ぎだろ、って気もしますしね。これは本読むと、結局欲しいのは
(coerce (nreverse chars) 'string)なんですけど、これは単に
doの返り値にした方がいいんじゃねえの、って謎がまずあって。要するにオリジナルのコードは
charを破壊的に
doで弄くっていって、それはそれでほっといて、最後に
(coerce (nreverse chars) 'string)なわけですよ。何じゃそりゃ、とか思って(笑)。Lispがどうの、って以前にそれじゃあ手続き型言語の
for文の書き方だろ(笑)。
一方、
ignoreは
CLHS見ても良く分かんなかったんで、そのまま挿入しています。ロジック考えると必ずしも必要である、とは思えないんですけどね。多分。ま、いいや、その辺はCLの流儀、と言う事で。
ってな感じで「Schemeっぽく」書いても問題なく動きますね。では次。
これも原版のコード見ても何が何だか……(苦笑)。いやあ、凹みましたよ(笑)。これもDoug Hoyte氏の手癖か何だか知らないんですが、やっぱり
defunの暗黙の
progn頼みのコードで。かつ破壊的操作をしまくりなんで、何が目的でどう操作してるのか、流れが掴み辛い。あんなにインデントが深くなる必要って全然ない、と思うんですけど。これも再帰に書き換えて、引数内処理した方がスッキリ決まるんじゃないか、って思いました。
暗黙の
progn頼みが何なのか、と言うと。要するに、データをループ回して操作して。それを置き去りにしてまた別にデータ持ってきてループ回してるわけです。それを
逐次処理するってのがオリジナルのコードの狙いなわけですが。必要か、それ?とか思ってさ(笑)。
しかも脱出条件が良く分からん。何で
(null pointer)が二ヶ所に渡って分散してんだか、皆目見当が付かなかった(笑)。「何じゃこりゃ?」ってのが正直なトコで。
破壊的操作を無自覚に使ってるからそーなるんだとしか思えなかった(笑)。
そこで、上の関数ではローカル関数
fooと
barを二つ作って凌いでいます。根本的に、この二つの関数って「独立」で構わないんですよ。オリジナルのコードでも最初のループって、結局一種の
フラグ作りなんですよね。本当にやりたい事は後者のループが握ってるんです。だから、シンプルに
fooでフラグを作って、
barで本操作をする、って設計にしました。やりようによってはもっとシンプルに書けるやもしれません。