Вашей скобка не в правильных местах. Скобки, если они не указаны, являются началом приложения-функции.
Он начинается с переменной cond
, которая не связана. Это не специальная форма (cond (predicate consequent) (predicate2 consequent2))
, так как она не начинается с открытой круглой скобки.
С отступом в одиночку я думаю, вы имели в виду, чтобы написать:
(DEFUN testAL (x)
(COND ((ATOM x) 'this-is-an-atom)
((LISTP x) 'this-is-a-list)
(T 'this-is-neither)))
(testal 'test) ; ==> THIS-IS-AN-ATOM
(testal '(a b c)) ; ==> THIS-IS-A-LIST
я удалил лишние скобки вокруг x
начиная (x)
средства применить функцию x
в то время как x
означает переменную x
. С x
в другом положении, например (+ x 3)
, тогда +
- это функция, которая должна быть применена, и x
является одним из своих операндов.
I изменено atomp
до atom
. Так как atom
является одним из первых примитивов, определяемых с самого первого LISP в 50-х годах, он не имеет постфикса p
, как и большинство других предикатов.
Edit: Multiple матч
Вы можете просто иметь несколько cond
(или if
, так как у вас есть только один тест в каждом) и делать побочные эффекты, такие как (print "THIS-IS-AN-ATOM")
с момента вашего базового случая никогда не вызовет (ничего не является ни список ни атома в CL). Это, пожалуй, простое решение.
(DEFUN testAL (x)
(if (ATOM x) (print 'this-is-an-atom))
(if (LISTP x) (print 'this-is-a-list)))
(testal '()) ; ==> THIS-IS-A-LIST (but prints both)
Для более функционального подхода, который я сделал бы это с более высокими функциями порядка сохраняя код проверяемой и поставить печать-функцию, которая делает побочные эффекты. Помните, что это может быть не так легко читать для новичков:
;; a list of pairs of predicate and their desription
(defparameter *type-predicates-and-description*
'((douglasp . this-is-the-answer-to-everything)
(floatp . this-is-a-floating-pont-number)
(integerp . this-is-an-integer)
(numberp . this-is-a-number)
(null . this-is-null)
(listp . this-is-a-list)
(characterp . this-is-a-character)
(stringp . this-is-a-string)))
;; custom made predicate
(defun douglasp (x)
(and (numberp x) (= x 42)))
;; returns all the types of a particular value
(defun get-type-info (x)
"return a list if types thet describes argument"
(flet ((check-type (acc type-pair)
"Accumulate description when predicate match"
(if (funcall (car type-pair) x)
(cons (cdr type-pair) acc)
acc)))
;; test x for each type predicate-description
(let ((res (reduce #'check-type
*type-predicates-and-description*
:initial-value '())))
;; check of empty list (no types matched)
(if (null res)
(list 'this-is-neither)
res))))
;; test it
(get-type-info '()) ; ==> (THIS-IS-A-LIST THIS-IS-NULL)
(get-type-info 42) ; ==> (THIS-IS-A-NUMBER
; THIS-IS-AN-INTEGER
; THIS-IS-THE-ANSWER-TO-EVERYTHING)
(get-type-info #()) ; ==> (THIS-IS-NEITHER)
;; Make a function to do side effects
(defun print-type-info (x)
(format t "~{~a~^, ~}." (get-type-info x)))
(print-type-info '()) ; ==> NIL
; and prints "THIS-IS-A-LIST, THIS-IS-NULL."
Что такое hw2? Как это облегчит ситуацию? –
@ JoshuaTaylor Технически это было бы больше работы, но я пытаюсь выучить язык. Я добавил hw2 к вопросу выше. – rtrigoso