#:g1: CDR 8: Generic Equality and Comparison for Common Lispの紹介

Posted 2014-07-15 12:30:00 GMT

(LISP Library 365参加エントリ)

 LISP Library 365 の196日目です。

CDR 8: Generic Equality and Comparison for Common Lispとはなにか

 CDR 8: Generic Equality and Comparison for Common Lispは、Marco Antoniottiが提案した総称関数で拡張可能な同値述語です。csziacobus氏による実装がQuicklispで入手できるようになった様子。

パッケージ情報

パッケージ名CDR 8: Generic Equality and Comparison for Common Lisp
Quicklisp
CDRGeneric Equality and Comparison for Common Lisp

インストール方法

(ql:quickload :equals)

試してみる

 どんな関数があるかは、そのうち多分Quickdocsで確認できます。

 equal等を拡張したいということは、たまにある気もしますが、一番多そうなのは、equalとequalpの間の挙動の違いかなと思います。
equalpにすると再帰的にコンテナの中身まで比較しますが、そこまでゆるくして欲しくないということもあります。
例えば、構造体が文字列のスロットを持つ場合、こんな感じになります。

(defstruct kalki string list)

(equal (make-kalki :string "foo" :list '(1 2 3 4)) (make-kalki :string "foo" :list '(1 2 3 4))) ;=> NIL

(equalp (make-kalki :string "foo" :list '(1 2 3 4)) (make-kalki :string "foo" :list '(1 2 3 4))) ;=> T

(equalp (make-kalki :string "FOO" :list '(1 2 3 4)) (make-kalki :string "foo" :list '(1 2 3 4))) ;=> T

文字列はstring=で比較して欲しいことが多そうですが、equalpではもっとゆるくなってしまいます。
こういう時にequalsを使えば、

(defmethod equals:equals ((x kalki) (y kalki) &key)
  (and (string= (kalki-string x)
                (kalki-string y))
       (equal (kalki-list x)
              (kalki-list y))))

(equals:equals (make-kalki :string "FOO" :list '(1 2 3 4)) (make-kalki :string "foo" :list '(1 2 3 4))) ;=> NIL

(equals:equals (make-kalki :string "foo" :list '(1 2 3 4)) (make-kalki :string "foo" :list '(1 2 3 4))) ;=> T

こんな感じで総称関数なのでユーザーが好きなようにカスタマイズして書けるという訳です。

まとめ

 今回は、CDR 8: Generic Equality and Comparison for Common Lispを紹介してみました。
いまいちぱっとしないCDRですが、地道に頑張って欲しいところです。

comments powered by Disqus