Compare - Examine Object Equality

Discussion of Common Lisp
Post Reply
Kohath
Posts: 61
Joined: Mon Jul 07, 2008 8:06 pm
Location: Toowoomba, Queensland, Australia
Contact:

Compare - Examine Object Equality

Post by Kohath » Tue Nov 03, 2009 4:36 am

Hey, I've got this function I think some people might be interested in. I've put it into Lisp Paste: http://paste.lisp.org/+1X85, and below:

Code: Select all

(defun compare (a b &optional (out-stream t))
  "This function compares a and b for equality.  The third argument is where to output the result."
  (flet ((outty (string &rest args)
           (apply #'format out-stream string a b args)))
    (cond
      ((eq a b) (outty "The objects ~S & ~S are the same object (eq)."))
      ((eql a b)
        (typecase a
          (number    (outty "The numbers ~S & ~S are the same number type and value (eql)."))
          (character (outty "The characters ~S & ~S are the same character (eql)."))
          (t (outty "The objects ~S & ~S should be eq, but they got to the eql cond."))))
      ((equal a b)
        (typecase a
          (cons         (outty "The conses ~S & ~S are recursively equal (equal)."))
          (string       (outty "The strings ~S & ~S contain the same characters (equal, case-sensitive)."))
          ((vector bit) (outty "The bit vectors ~S & ~S contain the same bits (equal)."))
          (pathname     (outty "The pathnames ~S & ~S are functionally equivalent (equal)."))
          (t (outty "The objects ~S & ~S should be eql or eq, but they got through those (equal)."))))
      ((equalp a b)
        (typecase a
          (cons      (outty "The conses ~S & ~S are recursively equalp (equalp)."))
          (character (outty "The characters ~S & ~S are char-equal (equalp, case-insensitive)."))
          (number    (outty "The numbers ~S & ~S represent the same value (equalp, =)."))
          (array     (outty "The arrays ~S & ~S contain the same elements (equalp)."))
          (t (outty "The objects ~S & ~S are of type ~S and are equalp." (type-of a)))))
      ((equalp (type-of a) (type-of b))
        (outty "The objects ~S & ~S are not the same, but are the same type."))
      (t (outty "The objects ~S & ~S are not the same in any way (not even type)."))))
  (terpri out-stream))
Please let me know what you think of it, if you have something similar, of any improvements, etc.

methusala
Posts: 35
Joined: Fri Oct 03, 2008 6:35 pm

Re: Compare - Examine Object Equality

Post by methusala » Tue Nov 03, 2009 8:57 am

Thanks, this is useful to experiment with. In sbcl I tried:
(setf x 1)
(setf y 2)
(compare x y)
and got:
"The objects 1 & 2 are not the same in any way (not even type)." Which wasn't what I expected.

Investigation showed the reason:

CL-USER> (type-of y)
(INTEGER 0 536870911)

CL-USER> (type-of x)
BIT

With (setf x 3) (compare x y) I got:
"The objects 3 & 2 are not the same, but are the same type."

methusala
Posts: 35
Joined: Fri Oct 03, 2008 6:35 pm

Re: Compare - Examine Object Equality

Post by methusala » Tue Nov 03, 2009 9:04 am

btw, googling on why you may have used flet instead of labels, I found this post on how to define a recursive anonymous function:

http://coding.derkeiler.com/Archive/Lis ... /0905.html

Kohath
Posts: 61
Joined: Mon Jul 07, 2008 8:06 pm
Location: Toowoomba, Queensland, Australia
Contact:

Re: Compare - Examine Object Equality

Post by Kohath » Thu Nov 05, 2009 9:50 pm

Thanks for showing me the strange behaviour for (compare 1 2)! I've made a small modification to print the types when they are not equal, so that it explains why it is so.

The recursive anonymous function thing really confuses me :oops: . I'll have to look into it more :shock: .

gugamilare
Posts: 406
Joined: Sat Mar 07, 2009 6:17 pm
Location: Brazil
Contact:

Re: Compare - Examine Object Equality

Post by gugamilare » Fri Nov 06, 2009 8:44 pm

methusala wrote:btw, googling on why you may have used flet instead of labels, I found this post on how to define a recursive anonymous function:

http://coding.derkeiler.com/Archive/Lis ... /0905.html
Oh, the Y combinator :) The library Arnesi has this function. It comes from lambda calculus. It is more or less the formal demonstration that, in the lambda calculus theory, every function has a fixed point. And the fixed point of a function f is exactly the value returned by (Y f) :)
(note that this is just in theory, it does not work exactly in practice because in practice not everything is a function)

http://en.wikipedia.org/wiki/Y_combinator#Y_combinator

Hum, it was discovered by Haskell B. Curry, who has two languages named after him (Haskell and Curry).

Post Reply