rtr*_*oso 0 lisp list atomic common-lisp conditional-statements
我试图定义我自己的函数,使我的hw2更容易,但它不起作用.你能看看它并告诉我我错过了什么吗?
(DEFUN testAL(x)
COND ( ( ATOMP(x) ) 'this-is-an-atom )
( ( LISTP(x) ) 'this-is-a-list )
( T 'this-is-neither ) )
Run Code Online (Sandbox Code Playgroud)
我希望这个条件函数接受输入X并输出它是一个原子,列表,还是两者都没有.问题是,当我输入NIL时,我收到一个错误:尝试获取未绑定变量`COND'的值.
作业2包括以下问题:
以下哪一项是原子,哪些列表,哪两个都没有?
一个.零
湾 (例如10 3)
C.(AB)
d.64
即 Ť
F.(没有像家一样的地方)
G.'(+ 3 5 6)
您的括号不在正确的位置.除非引用,括号是函数应用程序的开头.
它以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
Run Code Online (Sandbox Code Playgroud)
我已经删除了额外的括号,x
因为(x)
意味着应用函数,x
而x
意味着变量x
.用x
在不同的位置等(+ x 3)
,然后+
将被应用的功能和x
是其操作数中的一个.
我换atomp
了atom
.由于atom
是50年代第一个LISP定义的第一个原语之一,它没有p
像大多数其他谓词一样的后缀.
编辑:多个匹配
你可以只有几个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)
Run Code Online (Sandbox Code Playgroud)
对于更实用的方法,我会用更高阶函数来完成它,保持代码可测试并提供执行副作用的打印功能.请注意,对于初学者来说,这可能不那么容易阅读:
;; 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."
Run Code Online (Sandbox Code Playgroud)