在Lisp中编程的正确方法?

4 lisp common-lisp

我是Common Lisp的新手,发现自己利用方式函数返回值.以下是两个简单的例子:

(defun safe-avg (a b)
    (and (numberp a) (numberp b) (/ (+ a b) 2)))

(defun safe-div (a b)
    (and (numberp a) (numberp b) (> b 0) (/ a b)))
Run Code Online (Sandbox Code Playgroud)

但我可以这样写(可以说更清楚):

(defun safe-avg (a b)
    (if (and (numberp a) (numberp b))
        (/ (+ a b) 2)))

(defun safe-div (a b)
    (if (and (numberp a) (numberp b) (> b 0))
        (/ a b)))
Run Code Online (Sandbox Code Playgroud)

在我开始滥用这个习惯之前,我想知道做这样的事情及其背后的推理的首选方法是什么.

Sva*_*nte 7

由于您不使用"else"分支,您可以使用when:

(defun safe-div (a b)
  (when (and (numberp a) (numberp b) (> b 0))
    (/ a b)))
Run Code Online (Sandbox Code Playgroud)

这与:

(defun safe-div (a b)
  (if (and (numberp a) (numberp b) (> b 0))
      (/ a b)
      nil))
Run Code Online (Sandbox Code Playgroud)

这与您的版本相同,但更明确.

无论如何,这些都是功能相同的.我宁愿考虑如何使用这些功能.如果你这样做,每次调用这些函数时都必须进行空检查,这很乏味.

最好通过类型声明,通过断言或通过显式when... signal表单来使用条件.然后,您可以为程序的整个部分定义处理程序并重新启动这些条件.进一步阅读:Practical Common Lisp,ch.19.

在这种情况下,我根本不会在这里处理:

(defun safe-div (a b)
  (/ a b))
Run Code Online (Sandbox Code Playgroud)

(或者更确切地说,只是使用/).

如果/得到错误的参数,它将发出一个错误,然后你可以在外面处理,你知道那可能意味着什么.