#:g1: common-idiomsの紹介

Posted 2014-11-27 15:00:00 GMT

(LISP Library 365参加エントリ)

 LISP Library 365 の332日目です。

common-idiomsとはなにか

 common-idiomsは、Brian Mastenbrook氏作のCommon Lispのユーティリティ集です。

パッケージ情報

パッケージ名common-idioms
Quicklisp×
CLiKiCLiki: common-idioms

インストール方法

 CLiKiのリンクも死んでいますが、archive.orgでファイルを探すか、common-idioms-3.tar.gzでググって適当にソースを探します。ASDFで読み込めるので、Quicklispのlocal-projectsに置けばQuicklispでロード可能です。

(ql:quickload :common-idioms)

試してみる

 定義されているユーティリティは下記の通りです。

 適当につらつらと紹介していきたいと思いますが、else節でsetf-itというのが使えるのが面白いaif

(let ((xs (list nil 2)))
  (aif2 (car xs)
      it
      (setf-it 42))
  xs)
;=>  (42 2)

(let ((tab (*:alist-hash-table '((a . 0) (b . 1))))) (aif2 (gethash 'c tab) it (setf-it 42)) (*:hash-table-alist tab)) ;=> ((C . 42) (B . 1) (A . 0))

ここまで複雑だとパタンマッチマクロの方が使いやすそうなdestructuring-case

(destructuring-case next (1)
  (((1 (y (z))) (list 1 y z))
   ((x (y (z))) (list z y x)))
  '(1 (2 (3)))
  :else)
;=>  (1 2 3)

(destructuring-case next (1) (((1 (y (z))) (list 1 y z)) ((x (y (z))) (list x y z))) '(1 (2 (3 8))) :else) ;=> :ELSE

展開するフォームを指定できるexpand-only

(expand-only '()
             '(defun foo (n)
               (when n
                 (list n))))
;=>  (DEFUN FOO (N) (WHEN N (LIST N)))
;    NIL

(expand-only '(when) '(defun foo (n) (when n (list n)))) ;=> (DEFUN FOO (N) ; (IF N ; (PROGN (LIST N)) ; NIL)) ; NIL

多分マクロの中でgensymのリストを作るのに使うfconstantly

(mapcar (fconstantly #'gensym) '(a b c))
;=>  (#:G1915 #:G1916 #:G1917)

レキシカルスコープを曲げるlet-env/let-env*

(let ((x 3))
  (let-env e0
    (let ((x 4))
      (e0 (x) (list x)))))
;=>  (3)

(let ((x 3) (y 4)) (let-env* e0 (x y) (let ((x 4)) x (e0 (list x y))))) ;=> (3 4)

let-env*とmacroletを合体して、let-env*の環境を持ち運ぶマクロに任意の名前を付けられるようにしたmacrolet*

(let ((x 3))
  (macrolet* (x) ((foo (x) x))
    (let ((x 2))
      (foo x))))
;=>  3

ところで、bend-lexicalという表現の大元は、The Scheme Programming Language, 2nd Edition(Kent Dybvig)なんでしょうか。

その他、多値関数でreduceするreducen、指定した回数展開するmacroexpand-n等があります。

まとめ

 今回は、common-idiomsを紹介してみました。
十年前は大活躍していたBrian Mastenbrook氏ですが、この5、6年位はLisp的な活動はしていないようです。
色々活躍していただけに残念ですね。

comments powered by Disqus