该功能未定义。 (递归)

时间:2012-03-24 22:42:50

标签: function recursion lisp undefined

我正在编写一个简单的成员函数,它返回与该成员关联的值。条件的第一行(测试第一个值是否是我们正在寻找的那个)工作正常,但递归部分(为了测试列表的更多部分)每次都会返回错误。

这是我的功能:

(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程序,所以我假设答案非常简单,但我已经尝试过很多东西而且还没有成功。

1 个答案:

答案 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)))

为了便于阅读,请在结束括号和打开括号之间插入更多空格。