Common Lispのお宅拝見: LispWorks篇 — #:g1

Posted 2017-05-07 15:23:16 GMT

Common Lispを利用する上で普段何気無く利用しているcl-userだが、実は処理系毎にユーティリティの充実度等が結構違っている。
そこで、ホームパッケージであるcl-userパッケージを処理系毎に観察してみよう。

今回は、LispWorks 7.0 を眺める。
LispWorksは様々なプラットフォームで稼動するのでプラットフォーム依存な所はあるのだが、cl-userのが取り込んでいるパッケージは下記の通りで、LISPWORKS(lw)とHARLEQUIN-COMMON-LISP(hcl)を取り込んでいる。

(package-use-list :cl-user)

→ (#<The COMMON-LISP package, 2/4 internal, 978/1024 external> #<The HARLEQUIN-COMMON-LISP package, 0/8 internal, 353/512 external> #<The LISPWORKS package, 0/4 internal, 224/256 external>)

defpackageした際に:useを省略するとデフォルトのパッケージが取り込まれるが、上記3つが:useされるのがLispWorksの標準。

ちなみに、Harlequin Common LispというのはLispWorksを元々作っていた会社がHarlequinということに由来する。
Harlequin社は、〜Worksという名前で製品を作ることが多かったが、元々は、Harlequin CLを中心とした開発環境がLispWorksということだったらしい。

lwパッケージとhclパッケージの使い分けが判然としないが、hclパッケージの方がCLtL1時代からのユーティリティが多い気がするが、lwhclを合せて600近くのシンボルがあるので、結構ごちゃごちゃしているなあという印象はある。

これらユーティリティで有名なところでは、when-letif-letwith-unique-namesrebindingsplit-sequence辺りだろうか。
with-unique-namesは、with-gensymrebindingonce-onlyとして知られているマクロだが結構見掛けることは多いかと思う。
split-sequenceはQuicklispにもあるユーティリティと同名だが、LispWorksがオリジナルなのかもしれない(とはいえ微妙に仕様が違う)

また、オリジナルのloopにあったユーザー定義の構文がデフォルトで使えるので、

(define-loop-macro for)
(define-loop-macro repeat)
(define-loop-macro with)

(for i :from 0 :repeat 10 :collect i) ;=> (0 1 2 3 4 5 6 7 8 9)

こんなこともできるし、さらにユーザーがデータ型の処理方法を任意に定義することもできる(defloop等)

また、非常にどうでも良い所ではあるが、ユーティリティに定義されていることが多いtruefalseも用意されている。

(mapcar #'true (repeat 20 :for i :from 1 :collect i))
;=> (t t t t t t t t t t t t t t t t t t t t) 
(mapcar #'false (repeat 10 :for i :from 1 :collect i))
;=> (nil nil nil nil nil nil nil nil nil nil) 

Common Lispにはconstantlyがあるので不要に思えるのだが、用意している処理系は結構ある。

結び

以前から、処理系ごとにcl-userを比較してみていたが、これまで資料は貯めていたものの何故か書いたことがなかった。
今後、暇潰しに他の処理系についても書いてみるつもりである。


HTML generated by 3bmd in LispWorks 7.0.0

comments powered by Disqus