Lisp:不帮助返回一个值?

时间:2011-03-26 19:52:51

标签: lisp common-lisp

我编写了一个接受字符串列表的函数,并逐行打印。

(defun print-to-lines (slist)
    (cond
        ((null slist) slist)
        (t (let ((empty (write-line (car slist)))) (print-to-lines (cdr slist))))))

这很好用,除了在输出结尾有一个额外的返回值(在这种情况下是NIL)(在调试窗口中运行时):

CG-USER(16): (print-to-lines '("adam" "emilio" "eoln"))
adam
emilio
eoln
NIL

我理解额外的NIL来自哪里(它是我的函数的返回值),但我希望它不在那里。我的任务规定这不存在。有没有办法“伪造”它或禁用它?

5 个答案:

答案 0 :(得分:6)

我希望剖析和改进您的代码,同时提供问题的答案。

标准缩进是两个空格。

(defun print-to-lines (slist)
  (cond
    ((null slist) slist)
    (t (let ((empty (write-line (car slist)))) (print-to-lines (cdr slist))))))

您可以在任意两个令牌之间创建换行符。

(defun print-to-lines (slist)
  (cond
    ((null slist) slist)
    (t (let ((empty (write-line (car slist))))
         (print-to-lines (cdr slist))))))

cond形式的条件之后的东西被评估为 隐式progn。您不需要命名抛出的值 不管怎么说。

(defun print-to-lines (slist)
  (cond
    ((null slist) slist)
    (t (write-line (car slist))
       (print-to-lines (cdr slist)))))

要返回任何内容,请使用values。请注意,这通常是 没有必要,因为返回值不是输出的一部分;它是 只是由REPL显示(在语法高亮环境中, 程序输出和REPL输出通常是不同的颜色)。注意 另外,values也可用于返回多个值。

(defun print-to-lines (slist)
  (cond
    ((null slist) (values))
    (t (write-line (car slist))
       (print-to-lines (cdr slist)))))

请注意,此处不需要显式递归。其他一些更简洁的想法:

(defun print-to-lines (slist)
  (dolist (string slist)
    (write-line string)))

(defun print-to-lines (slist)
  (mapcar #'write-line slist))

(defun print-to-lines (slist)
  (format t "~{~a~%~}" slist))

答案 1 :(得分:5)

您可以使用不带参数的values来返回任何值,即(values)

您的函数的更多惯用版本可以使用mapcdolist而不是显式递归(但您仍然需要(values),因为mapc会返回列表, dolist返回nil)。

答案 2 :(得分:3)

答案 3 :(得分:1)

首先,在这种情况下,它不是额外的返回值。您正在打印到*STDOUT*,并且repl也打印到*STDOUT*,所以它看起来就像是。如果您的功能是打印到*FILE*,则不会出现此问题。

由于第三行

,您的代码返回null
1: (defun print-to-lines (slist)
2:   (cond
3:     ((null slist) slist)
4:     (t (let ((empty (write-line (car slist)))) (print-to-lines (cdr slist))))))

在slist为null的情况下,您将返回slist,因此返回nul返回值。你可以重写函数,这样不是返回null slist而是返回另一个值(比如对write-line或其他一些函数调用)。

另请查看格式function

答案 4 :(得分:0)

我会稍微重构一下,以便您在列表搜索中检查空列表,而不是让列表变空。例如:

(defun print-to-lines (slist)
    (cond
        ((null (cdr slist)) (write-line (car slist)))
        (t (let ((empty (write-line (car slist)))) (print-to-lines (cdr slist))))))

以下是运行它的链接:http://ideone.com/tzZrm

希望这有帮助,

杰森