#:g1: Hierarchical Packagesの紹介

Posted 2014-10-28 15:00:00 GMT

(LISP Library 365参加エントリ)

 LISP Library 365 の302日目です。

Hierarchical Packagesとはなにか

 Hierarchical Packagesは、Allegro CLとCMUCLでサポートされている、パッケージを階層分けする仕組みです。

パッケージ情報

パッケージ名Hierarchical Packages
Quicklisp×
参考サイトAllegro CL: Packages
CMUCL: Hierarchical Packages

インストール方法

 上記のAllegro CLのドキュメントに参照実装がありますので適当に動かします。
SBCLに移植してみたものがありますので良かったらどうぞ。find-packageを上書きするので注意してください。

 Quicklispのlocal-projects以下に配置すれば、

(ql:quickload :relative-package-names)

で読み込めます。

試してみる

階層的なパッケージとありますが、階層を「.」で区切るという命名規約と、パッケージの相対位置を指定できるようにするrelative-package-namesの2つから成り立っています。
CMUCLでは、18dからAllegro CLの実装を取り入れたようです。
Allegro CL、CMUCL共に起動時のデフォルトで有効になっていて、*features*に:relative-package-namesが入っています。
relative-package-namesの例としては、

;; utilities
(defun children-names (pkg)
  (nreverse
   (maplist (lambda (cdr)
              (format nil "~{~A~^.~}" (reverse cdr)))
            (nreverse (*:split "\\." (string pkg))))))

(defmacro defpackage/parents (name &body options) (let ((pkgs (children-names name))) `(list ,@(mapcar (lambda (p) (eval-when (:compile-toplevel :load-toplevel :execute) `(or (find-package ,p) (defpackage ,p ,@options)))) pkgs))))

(cl:in-package :cl-user) 

(defpackage/parents :a.b.c.d (:use :cl))

(defpackage/parents :a.b.cc.dd (:use :cl))

(cl:in-package :a.b.c.d)

(defun foo (n) (list :a.b.c.d n))

(cl:in-package :a.b.c)

(defun foo (n) (list :a.b.c (a.b.c.d::foo n)))

(defun bar (x) (list :a.b.c x))

(cl:in-package :a.b.c.d)

(defun bar (x) (list :a.b.c.d (a.b.c::bar x)))

(cl:in-package :a.b.cc.dd)

(defun bar (x) (list :a.b.cc.dd (a.b.c::bar x)))

;;; *EOF*

のようなものが、

(cl:in-package :cl-user) 

(defpackage/parents :a.b.c.d (:use :cl))

(defpackage/parents :a.b.cc.dd (:use :cl))

(cl:in-package :a.b.c.d)

(defun foo (n) (list :a.b.c.d n))

(cl:in-package :..)

(defun foo (n) (list :a.b.c (.d::foo n)))

(defun bar (x) (list :a.b.c x))

(cl:in-package :.d)

(defun bar (x) (list :a.b.c.d (..::bar x)))

(cl:in-package :...cc.dd)

(defun bar (x) (list :a.b.cc.dd (...c::bar x)))

;;; *EOF*

のように書けます。

 なんとなくですが、親子階層シンボルへの参照は便利そう、しかしin-packageで相対指定するとカオスなことになりそう、という印象です。
まだ、使いこんでいないのでどの辺りが便利なのかが実感できていないですが、第一印象としては、あまり便利そうでもないかなというところです。

まとめ

 今回は、Hierarchical Packagesを紹介してみました。
Common Lispの前身のZetalisp(Lisp machine Lisp)のパッケージは階層パッケージでしたが、Zetalispを参考にしつつもCommon Lispは階層パッケージにはなりませんでした。
そのうちZetalispの階層パッケージとも比較してみたいところです。

comments powered by Disqus