Scheme:マクロ:anaphoric ifの代替

Scheme:マクロ:anaphoric ifの代替

OnLispに出てくるanaphoric ifの代わりになる一般的な技、ありませんか? non-hygienicなマクロが気持ち悪い(勝手に"it"が束縛されているのはよくな い)というのは分かるんですが、じゃあどうするかというと、aifを使うのに比 べて冗長な書き方をするしかないような気がします。

場合によっては、condの"=>"構文が、aifの代わりに使えます。典型的には、 連想リストに値があればその値を返し、なければ#fを返すというような場合。 ローカル変数を省くことができます。

 (cond ((assoc "foo" alist) => cdr)
       (else #f))

しかし、condを使えばいつでも簡潔に書けるというわけではありません。上の 例では、cdrの代わりにそこに複雑な手続きを置こうとすると、lambdaを書か なければならず、束縛フォームが現れて、見た目に複雑になってしまいます。 うまくいけばcutが使えますが、一般にそうとは限りません。

たとえば、ハッシュテーブルに値があれば、その値とそれを大文字にした値の リストを返し、ハッシュテーブルに値がなければ'()を返す手続きは、次のよ うに書くことになるでしょう。

 ;;; 書き方(1)
 (cond ((hash-table-get ht "key" #f)
        => (lambda (val)
             (list val (string-upcase val))))
       (else '()))
 
 ;;; 書き方(2)
 (let1 val (hash-table-get ht "key" #f)
   (if val
     (list val (string-upcase val))
     '()))

上記の書き方に比べると、下記のanaphoric ifを使った書き方のほうが明解で 簡単です。

 (aif (hash-table-get ht "key" #f)
   (list it (string-upcase it))
   '())

aifと同じくらい簡潔に書けて、なおかつ暗黙のitを使わなくて良いような方 法、ありませんか?


Last modified : 2005/09/17 12:11:28 UTC