#:g1: serapeumの紹介

Posted 2014-09-16 14:30:00 GMT

(LISP Library 365参加エントリ)

 LISP Library 365 の259日目です。

serapeumとはなにか

 serapeumは、Paul M. Rodriguez氏作のユーティリティ集ですがAlexandriaと併用して使うことを意図しているものだそうです。

パッケージ情報

パッケージ名serapeum
Quicklisp
QuickdocsQuickdocs

インストール方法

(ql:quickload :serapeum)

試してみる

 どんな関数があるかは、Quickdocsで確認できます。

 定義されているユーティリティは下記のように結構沢山あります。
これらのシンボルは、alexandriaとは競合しないものが選択されているとのことで、一緒に:use :alexandria :serapeum できるとのことです。
リファレンスがあるので詳細はそちらを参照のこと。

 この中でfbindというのが面白そうなので、ちょっと試してみました。
これは(setf fdefinition)のローカル版という感じですが、LISP-2だとこれを実現するのはなかなか厄介です。
とりあえず、こんな感じで書けます。

(serapeum:fbind ((add1 (lambda (n) (+ 1 n))))
  (add1 8))
;=>  9

(serapeum:fbind ((add1 #'1+)) (add1 8)) ;=> 9

それぞれ

;==>
(LET ()
  (LET ()
    (FLET ((ADD1 (N)
             (+ 1 N)))
      (ADD1 8))))

;==> (LET () (LET ((#:ADD11318 (ALEXANDRIA:ENSURE-FUNCTION #'1+))) (DECLARE (FUNCTION #:ADD11318)) (FLET ((ADD1 (&REST SERAPEUM::ARGS) (DECLARE (DYNAMIC-EXTENT SERAPEUM::ARGS)) (APPLY #:ADD11318 SERAPEUM::ARGS))) (ADD1 8))))

こんな感じに展開されますが、fletに展開されるようです。
後者は、関数の情報を元に展開している訳ではないので、可変長引数として扱う他ないのかなと思いますが、やはりこういうのは処理系内部の機能を使わない限り効率の良いものを作るのは難しそうです。
とはいえ、前者のようにfletにきっちり嵌ると、

; disassembly for LATUMAPIC (assembled 11 bytes)
;        MOV EDX, 18                      ; no-arg-parsing entry point
;        MOV RSP, RBP
;        CLC
;        POP RBP
;        RET

のように定数を返す関数というところまで畳みこめたりはするようです。

まとめ

 今回は、serapeumを紹介してみました。
メジャーなユーティリティライブラリと併用する、というのはなかなか新しいスタイルですね。

comments powered by Disqus