Nyquist / XLISP 2.0  -  Contents | Tutorials | Examples | Reference

cl:equalp


(equalp expr1 expr2)
exprN - arbitrary Lisp expressions
returns -  T  if the expressions are structurally equal, NIL otherwise

Two expressions are 'equalp':

Note that only 'equalp' can compare arrays.

(defun cl:equalp (expr-1 expr-2)
  (or (equal expr-1 expr-2)
      (and (numberp expr-1) (numberp expr-2) (= expr-1 expr-2))
      (let ((type (type-of expr-1)))
        (when (eq type (type-of expr-2))
          (case type
            (character (char-equal expr-1 expr-2))
            (string    (string-equal expr-1 expr-2))
            (cons      (do ((x (first expr-1)
                               (if (consp expr-1) (first expr-1) expr-1))
                            (y (first expr-2)
                               (if (consp expr-2) (first expr-2) expr-2)))
                           ((or (null expr-1)
                                (null expr-2)
                                (not (equalp x y)))
                            (and (null expr-1)
                                 (null expr-2)))
                         (setq expr-1 (and (consp expr-1) (rest expr-1))
                               expr-2 (and (consp expr-2) (rest expr-2)))))
            (array     (let ((end (length expr-1)))
                         (when (eql end (length expr-2))
                           (dotimes (index end t)
                             (and (not (equalp (aref expr-1 index)
                                               (aref expr-2 index)))
                                  (return nil)))))))))))

cons: do is used instead of recursion because XLISP has only two kilobytes stack size. The (consp expr) tests are necessary because in a dotted list the last rest element is not a cons.

Examples:

(cl:equalp 1 1.0)                            => T
(cl:equalp #\a #\A)                          => T
(cl:equalp "Abc" "aBc")                      => T
(cl:equalp '(1 #\a "Abc") '(1.0 #\A "aBc"))  => T
(cl:equalp #(1 #\a "Abc") #(1.0 #\A "aBc"))  => T

Nested expressions only match if the nesting matches:

(cl:equalp '(1 (2 3)) '(1.0 (2.0 3.0))  => T
(cl:equalp '(1 (2 3)) '((1.0 2.0) 3.0)  => NIL
(cl:equalp '((1 2) 3) '((1.0 2.0) 3.0)  => T
(cl:equalp '((1 2) 3) '(1.0 (2.0 3.0))  => NIL

A character does not match a string with the same character:

(cl:equalp #\a "a")  => NIL

  Back to top


Nyquist / XLISP 2.0  -  Contents | Tutorials | Examples | Reference