我正在编写一个简单的成员函数,它返回与该成员关联的值。条件的第一行(测试第一个值是否是我们正在寻找的那个)工作正常,但递归部分(为了测试列表的更多部分)每次都会返回错误。
这是我的功能:
(defun mem (prop L)
(cond
((eq (caar L) prop) (print cadar L)))
(t (mem (prop (cdr L)))))) // error is on this line!
所以,如果我输入
(mem `i `((i 1) (j 2)))
它正确返回1.但是,如果我输入
(mem `j `((i 1) (j 2)))
它返回“函数prop未定义”的错误。
如何让程序知道prop不是函数,而只是一个输入参数?
这是我的第一个lisp程序,所以我假设答案非常简单,但我已经尝试过很多东西而且还没有成功。
答案 0 :(得分:4)
问题尤其是代码段:(prop (cdr L))
。这会尝试调用prop
,并将其传递给(cdr L)
。要将其作为参数传递给mem
,只需省略额外的括号:(mem prop (cdr L))
。
如果你在确定一般放置括号的位置时遇到问题,请注意Lisp语法与函数的数学语法非常相似,除了函数在括号内部(并且你使用空格而不是逗号) ,但这不是问题)。例如,用数学符号表示,您有:mem(prop(cdr(L)))
,而不是mem(prop, cdr(L))
。
看起来你在cond
的第一个分支之后有一个额外的括号,它会提前结束。使用带括号匹配的编辑器/ IDE来捕获此类错误。 Emacs和DrRacket一样。前者可以通过SLIME与Common LISP一起使用(在网上搜索您的平台的设置说明),而后者则支持Scheme。
分号(“;”)是大多数LISP中使用的注释字符。
此函数不需要 print
,并且(取决于其行为)可能不正确。在一些LISP(例如Common LISP)中,它返回其参数,但在其他LISP中,它可能返回nil或某些void类型的实例。
Quasiquote(又名backquote,反引号)也是不必要的。 Quasiquote允许您引用一些符号,而其他符号(以逗号为前缀)将替换为其值。由于您不需要在引用的表达式中进行替换,因此普通引用将起作用:(mem 'j '((i 1) (j 2)))
。
为了便于阅读,请在结束括号和打开括号之间插入更多空格。