0

I am losing my mind over evaluating this code to find the error. I am not sure why I am getting an undefined function. Would someone please guide me to understand why? thanks!

O is supposed to be an object, and L a list. I am trying to attach O to the end of the list and return the list

(defun my_attach(O L)
    (cond ((eq L nil )
        O )
        (t (cons (car L) (my-attach O (cdr L)) )
        )
    )
)
Renzo
  • 26,848
  • 5
  • 49
  • 61
Drunkhydra
  • 47
  • 2
  • `(eq x nil)` is usually written `(null x)` or `(not x)`. These are equivalent. `null` is typically used in a situation when `nil` represents the empty list; `not` is used when the `nil` is denoting a Boolean false. – Kaz Oct 28 '19 at 05:30
  • A two-clause `cond` of the form `(cond (x y) (t z))`, where `x`, `y` and `z` are all single expressions, is usually written `(if x y z)`. – Kaz Oct 28 '19 at 05:31
  • Avoid using `O` as an identifier in programs; it can be confused for zero. – Kaz Oct 28 '19 at 05:35
  • `(defun my-attach (oh list) (if (null list) oh (cons (car list) (my-attach oh (cdr list)))))` – Kaz Oct 28 '19 at 05:36
  • If we test the list for not being null and swap the two clauses, we can shorten it: `(defun my-attach (oh list) (if list (cons (car list) (my-attach oh (cdr list))) oh))` – Kaz Oct 28 '19 at 05:38

1 Answers1

5

If you have copied correctly your code in the post, you have used two different names for the same function: my_attach (_ is the underscore character) and my-attach (- is the dash character).

Simply use the same name. For instance:

(defun my-attach(O L)
  (cond ((eq L nil ) O)
        (t (cons (car L) (my-attach O (cdr L))))))

But note that this will not produce the desired result (in fact it does not produce a proper list). Rather, you should use (list O) instead of O in the terminal case:

CL-USER> (defun my-attach(O L)
           (cond ((eq L nil) O)
                 (t (cons (car L) (my-attach O (cdr L))))))
MY-ATTACH
CL-USER> (my-attach 3 '(1 2))
(1 2 . 3)
CL-USER> (my-attach 3 '())
3
CL-USER> (defun my-attach(O L)
           (cond ((eq L nil) (list O))
                 (t (cons (car L) (my-attach O (cdr L))))))
MY-ATTACH
CL-USER> (my-attach 3 '(1 2))
(1 2 3)
CL-USER> (my-attach 3 '())
(3)

Finally, a note about the common writing conventions for Common Lisp programs:

  1. it is preferred to use lower case identifiers;

  2. compound words in identifiers are separated by -, not by _ as in other languages;

  3. it is preferred to use if when there are only two cases in a conditional statement;

  4. check for a value which is nil is commonly done with the predicate null;

  5. the parentheses at the end of an expression are usually written on the same line of the last part of the expression.

So your function could be rewritten as:

(defun my-attach (o l)
  (if (null l)
      (list o)
      (cons (car l) (my-attach o (cdr l)))))
Renzo
  • 26,848
  • 5
  • 49
  • 61