2010年5月1日土曜日

LOL SHARP-DOUBLE-QUOTE と SHARP-GREATER-THAN

実験も兼ねて。

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文の書き方だろ(笑)。
一方、ignoreCLHS見ても良く分かんなかったんで、そのまま挿入しています。ロジック考えると必ずしも必要である、とは思えないんですけどね。多分。ま、いいや、その辺はCLの流儀、と言う事で。



ってな感じで「Schemeっぽく」書いても問題なく動きますね。では次。



これも原版のコード見ても何が何だか……(苦笑)。いやあ、凹みましたよ(笑)。これもDoug Hoyte氏の手癖か何だか知らないんですが、やっぱりdefunの暗黙のprogn頼みのコードで。かつ破壊的操作をしまくりなんで、何が目的でどう操作してるのか、流れが掴み辛い。あんなにインデントが深くなる必要って全然ない、と思うんですけど。これも再帰に書き換えて、引数内処理した方がスッキリ決まるんじゃないか、って思いました。
暗黙のprogn頼みが何なのか、と言うと。要するに、データをループ回して操作して。それを置き去りにしてまた別にデータ持ってきてループ回してるわけです。それを逐次処理するってのがオリジナルのコードの狙いなわけですが。必要か、それ?とか思ってさ(笑)。
しかも脱出条件が良く分からん。何で(null pointer)が二ヶ所に渡って分散してんだか、皆目見当が付かなかった(笑)。「何じゃこりゃ?」ってのが正直なトコで。破壊的操作を無自覚に使ってるからそーなるんだとしか思えなかった(笑)。
そこで、上の関数ではローカル関数foobarを二つ作って凌いでいます。根本的に、この二つの関数って「独立」で構わないんですよ。オリジナルのコードでも最初のループって、結局一種のフラグ作りなんですよね。本当にやりたい事は後者のループが握ってるんです。だから、シンプルにfooでフラグを作って、barで本操作をする、って設計にしました。やりようによってはもっとシンプルに書けるやもしれません。

1 件のコメント:

  1. RSS にコードが含まれなくなってしまうのが残念な感じです。

    返信削除