#:g1: (eql ...)型を活用したい

Posted 2021-12-11 14:03:25 GMT

Lisp一人 Advent Calendar 2021 11日目の記事です。

Common Lispには任意のオブジェクトから型指定子を作ることが可能です。 こんな風に使えますが、

(typep 1 '(eql 1))
→ t

deftypeで名前を付けることも可能です。

(deftype one ()
  `(eql 1))

(typep 1 'one) → t

規格には規定されていませんが、このdeftypeに閉じ込められたオブジェクトを取り出す機能は大抵の処理系にあります。 (取り出せないと比較ができないので)

;;; LispWorksの場合
(type:expand-user-type 'one)(eql 1)
  t

これを活用して何かできないでしょうか。

ちょっと思い付くのは、大域変数の代わりにdeftypeを使う、というもの。 下記はend-of-fileをdeftypeだけでどうにかできないか考えてみた例ですが、使い勝手はいまいちです。

(let ((eof '#:eof))
  (deftype eof ()
    `(eql ,eof))
  (defun the-eof ()
    eof))

(with-input-from-string (in (format nil "~{~A~%~}" '("foo" "bar" "baz"))) (loop :for line := (read-line in nil (the-eof)) :until (typep line 'eof) :collect line))("foo" "bar" "baz")

シングルトン系の操作で活躍できそうなのですが、何か良い活用方法はないでしょうか。
何か思い付いたらこのブログに書きます。


HTML generated by 3bmd in LispWorks 7.0.0

comments powered by Disqus