Lisp:不帮助返回一个值?

Ada*_*m S 5 lisp common-lisp

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

(defun print-to-lines (slist)
    (cond
        ((null slist) slist)
        (t (let ((empty (write-line (car slist)))) (print-to-lines (cdr slist))))))
Run Code Online (Sandbox Code Playgroud)

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

CG-USER(16): (print-to-lines '("adam" "emilio" "eoln"))
adam
emilio
eoln
NIL
Run Code Online (Sandbox Code Playgroud)

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

Rör*_*örd 6

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

你的函数的更多惯用版本可以用显式递归编写mapcdolist代替显式递归(但你仍然需要(values)因为mapc返回列表并dolist返回nil).


Sva*_*nte 6

我想剖析和改进您的代码,同时提供您的问题的答案.

标准缩进是两个空格.

(defun print-to-lines (slist)
  (cond
    ((null slist) slist)
    (t (let ((empty (write-line (car slist)))) (print-to-lines (cdr slist))))))
Run Code Online (Sandbox Code Playgroud)

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

(defun print-to-lines (slist)
  (cond
    ((null slist) slist)
    (t (let ((empty (write-line (car slist))))
         (print-to-lines (cdr slist))))))
Run Code Online (Sandbox Code Playgroud)

cond表单中的条件之后的内容将以隐式方式进行评估progn.无论如何,您都不需要命名被丢弃的值.

(defun print-to-lines (slist)
  (cond
    ((null slist) slist)
    (t (write-line (car slist))
       (print-to-lines (cdr slist)))))
Run Code Online (Sandbox Code Playgroud)

为了什么都不返回,请使用values.请注意,这通常不是必需的,因为返回值不是输出的一部分; 它只是由REPL显示(在语法高亮环境中,程序输出和REPL输出通常是不同的颜色).另请注意,values也可用于返回多个值.

(defun print-to-lines (slist)
  (cond
    ((null slist) (values))
    (t (write-line (car slist))
       (print-to-lines (cdr slist)))))
Run Code Online (Sandbox Code Playgroud)

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

(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))
Run Code Online (Sandbox Code Playgroud)