$ と cut
Gauche には $ というマクロがこっそり入っている。 まだ改良の余地があると考えているらしく、ドキュメントにはまだ記載されていない。
Haskell の $ をヒントにしたそうで、具体的には以下の例のとおりに展開される。
($ f a b c) => (f a b c) ($ f $ g a b c) => (f (g a b c)) ($ f $ g $ h a b c) => (f (g (h a b c))) ($ f a $ g b $ h c) => (f a (g b (h c)))
インデントが深くならないというのはあるにしても、記述が短くなるわけでもなく、便利な場面があるか私は疑問に感じていた。
ところが、「どう書く?org」で出題されていた「文字列に含まれる単語の最初の文字を大文字にする」という問題を解こうとして $ を使う機会があり、考えが変わった。
まず、私が書いたコードを示そう。
(use srfi-13) (display(regexp-replace-all #/\w+/(port->string(standard-input-port))(cut $ string-titlecase $ <>)))
string-titlecase は単語の最初以外は小文字にしてしまうので問題に対して正解になってないかもしれないが、とりあえずそのへんは無視して $ を使っている箇所に注目して欲しい。
(cut $ string-titlecase $ <>)
これを $ を使わずに書くとどうなるだろう。
(lambda(x)(string-titlecase (x)))
そう。 cut も使えないのだ。
cut に慣れてくるとネストした内側の方に <> を入れたいと誰しも思うようで、以前に Lingr の Gauche 部屋で話題になっていた覚えがある。 $ を使えば逆にネストをなくすことで cut を使えるようになるというわけだ。
cut は頻出するマクロであるし、 $ との組合せはなかなか使い出があるのではないかと思った次第である。
Document ID: f9d9067fc9f042dd7f6e0871682e5eed