I'm pretty new to lisp; I was wondering if anyone here could help me out.
I have the following code snippet:
(defun write-lookup (binding-list pattern fact)
(cond
; No bindings have been stored
; Return the binding list with a new one!
((not binding-list) (cons (cons pattern fact) nil))
; A list of bindings is being stored
(cond
; The current binding matches
((equal (caar binding-list) pattern)
; Return the binding-list if value matches, nil else
(if (compare pattern fact) binding-list nil))
; Recursively search the rest of the list for the binding
((cdr binding-list) (write-lookup (cdr binding-list) pattern fact))
; The list doesn't have the binding.
; Return the binding-list with the added pattern
( T (cons (cons pattern fact) binding-list)))))
When I try to run it, I get the following:
*** - SYSTEM::%EXPAND-FORM: (EQUAL (CAAR BINDING-LIST) PATTERN) should be a
lambda expression
Could someone please point out my error? Thanks!
First you need to indent your code properly:
(defun write-lookup (binding-list pattern fact)
(cond
; No bindings have been stored
; Return the binding list with a new one!
((not binding-list) (cons (cons pattern fact) nil))
; A list of bindings is being stored
(cond
; The current binding matches
((equal (caar binding-list) pattern)
; Return the binding-list if value matches, nil else
(if (compare pattern fact) binding-list nil))
; Recursively search the rest of the list for the binding
((cdr binding-list) (write-lookup (cdr binding-list) pattern fact))
; The list doesn't have the binding.
; Return the binding-list with the added pattern
(T (cons (cons pattern fact) binding-list)))))
A typical Lisp editor will do that for you on a keystroke.
Now you can easily spot that a T clause is missing for the first COND. Let me add it:
(defun write-lookup (binding-list pattern fact)
(cond
; No bindings have been stored
; Return the binding list with a new one!
((not binding-list) (cons (cons pattern fact) nil))
; A list of bindings is being stored
(t (cond
; The current binding matches
((equal (caar binding-list) pattern)
; Return the binding-list if value matches, nil else
(if (compare pattern fact) binding-list nil))
; Recursively search the rest of the list for the binding
((cdr binding-list) (write-lookup (cdr binding-list) pattern fact))
; The list doesn't have the binding.
; Return the binding-list with the added pattern
(T (cons (cons pattern fact) binding-list))))))
I would also move the comment out of the code:
(defun write-lookup (binding-list pattern fact)
(cond ((not binding-list) ; No bindings have been stored
(cons (cons pattern fact) nil)) ; Return the binding list with a new one!
(t ; A list of bindings is being stored
(cond ((equal (caar binding-list) pattern) ; The current binding matches
(if (compare pattern fact) ; Return the binding-list if value matches, nil else
binding-list
nil))
((cdr binding-list) ; Recursively search the rest list for the binding
(write-lookup (cdr binding-list) pattern fact))
(T ; The list doesn't have the binding.
(cons (cons pattern fact) ; Return the binding-list adding the pattern
binding-list))))))
Your nested use of cond looks suspect. You could try the following form using if:
(defun write-lookup (binding-list pattern fact)
; No bindings have been stored
; Return the binding list with a new one!
(if (not binding-list)
(cons (cons pattern fact) nil)
(cond
; The current binding matches
((equal (caar binding-list) pattern)
; Return the binding-list if value matches, nil else
(if (compare pattern fact) binding-list nil))
; Recursively search the rest of the list for the binding
((cdr binding-list) (write-lookup (cdr binding-list) pattern fact))
; The list doesn't have the binding.
; Return the binding-list with the added pattern
(T (cons (cons pattern fact) binding-list)))))
Sorry for the slight change of formatting; emacs like to put comments over to the right.