简单的LISP代码不会捕获输入错误

时间:2012-09-23 02:50:14

标签: recursion error-handling lisp factorial

我正在为递归因子函数编写一个非常简单的lisp代码。使用数字调用时,它可以正常工作。但是,当我尝试使用不是数字的东西(例如a)调用它时,我收到以下错误:

错误:尝试获取未绑定变量“A”的值。   [条件类型:UNBOUND-VARIABLE]

但是,这应该在我的代码中捕获。这是我的代码:

(defun FactorialRec (num)
   (cond                                                  
      ((not(numberp num))
         (princ "Argument must be a number.")
         (terpri)
         ())
      ((equal num 1) ;base case                                                       
         1)
      ((<= 1 num) (* num(FactorialRec (- num 1))))
   )
)

我不知道为什么numberp没有抓住这个。有任何想法吗?感谢。

3 个答案:

答案 0 :(得分:2)

不要将参数类型检查混合到主逻辑中。在进入函数时使用check-type宏,或者在函数的早期使用,方便:

(defun factorial (num)
  (check-type num (and integer (satisfies plusp)))
  (if (= num 1)
     1
     (* (factorial (1- num)) num))) 

表单(and integer (satisfies plusp))是一个类型表达式。 Lisp类型可以与and等运算符连接,satisfies类型运算符可用于创建任何谓词函数的类型。因此,我们可以指定一个类型,其域值是整数对象,哪些是正数。 check-type将很高兴地验证我们的变量,看它是否属于这种类型。

我还使用了内置的1-函数,该函数从其参数中减去一个而不是(- num 1)。这个1-是符号,而不是特殊语法。

答案 1 :(得分:1)

在调用函数之前发生错误。当您在Lisp解释器中键入函数调用表达式时,它首先计算所有参数并调用函数。如果使用未绑定的变量,则参数评估将失败。

答案 2 :(得分:0)

Break 2 [6]> (FactorialRec "A")
Argument must be a number.

它适用于我的机器。所以我认为你传递的是A而不是"A"