Hatena::Groupcadr

わだばLisperになる このページをアンテナに追加 RSSフィード

2004 | 12 |
2005 | 01 | 02 | 07 | 10 | 11 |
2006 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2007 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2008 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2009 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2010 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2011 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 11 |

2008-05-03

gensymのリスト

| 11:58 | gensymのリスト - わだばLisperになる を含むブックマーク はてなブックマーク - gensymのリスト - わだばLisperになる

当初、気の効いたイディオムを探索するという趣旨でしたが、見付けようと思ってもなかなか見付からないので、適当にイディオムを探してエントリを書くことにしました(^^;

さて、CLのマクロを書いていると、変数のリストと同じ長さのgensymのリストが欲しくなることがあると思います。

'(a b c)
;=>
(#:g000001 #:g000002 #:g000003)

そこに焦点を当てて人間模様を観察してみたいと思います。

とりあえず、

(defparameter *lst* '(foo bar baz))

としておきます。

(1)Paul Graham氏

(mapcar (lambda (x) (gensym)) *lst*)

;; コンパイラに警告されるので、ignoreする場合。
(mapcar (lambda (x) 
	  (declare (ignore x))
	  (gensym))
	*lst*)

アンチloopの人なので、mapcarで。

declareあり、45文字。なしは、31文字

(2)適当に変種。declareが長いので、valuesで2値目を捨てるぞ、という場合。

(mapcar (lambda (x) (values (gensym) x))
	*lst*)

でも、分かりにくい。42文字

(3)やっぱりloopが定番だろう

(loop :for g :in *lst* :collect (gensym))

loopがぴったり嵌まる状況な気がする。36文字。

アンチloopじゃない人は、普通にこちらかも。

(4)dolistはどうか。

(let (res)
  (dolist (g *lst* res)
    (push (gensym) res)))

見たことない。49文字

(4)Brian Mastenbrook氏(common-idiomsより)

わざわざ、fconstantlyというconstantlyに似た関数を定義して使う。

(mapcar (fconstantly #'gensym) *lst*)

fconstantlyに汎用性はあるんだろうか。基本的にこのシチュエーション専用な気が…。

fconstantlyをインポートすれば、32文字。しなければ、46文字。

まとめ

以上、色々(といっても基本的に3バージョン)纏めてみましたが、最短は、31文字で、declareなしのPG方式。警告回避の場合32文字でfconstantly

しかし、やっぱりloopが定番なのではないでしょうか。

もっと良い方法があったら教えて下さい!