我使用循环函数在LISP中写下了这个迭代代码:
(defun loadfile (filename)
(with-open-file (stream filename)
(loop for line = (read-line stream nil 'eof)
until (eq line 'eof)
collect line)))
)
)
有没有办法在没有loop
的情况下以递归方式重写它?
答案 0 :(得分:6)
用GOTO给他们一个惊喜:
(defun loadfile (filename)
(with-open-file (stream filename)
(prog (line lines)
repeat
(setf line (read-line stream nil))
(when line
(push line lines)
(go repeat))
(return (reverse lines)))))
答案 1 :(得分:5)
当然,任何循环都可以在递归中进行转换,但是按时读取整个文件是一个典型的迭代过程,所以我发现这个问题很难激发。
这是一个可能的递归版本,其中递归由内部函数管理:
)
如果文件的行数很大,则此解决方案容易出现堆栈溢出错误。
如果有一个可以执行尾部优化的编译器,下面的替代递归解决方案可以以迭代方式编译,可以避免堆栈溢出:
(defun load-file (filename)
(with-open-file (stream filename)
(labels ((read-recursively ()
(let ((line (read-line stream nil 'eof)))
(if (eq line 'eof)
nil
(cons line (read-recursively))))))
(read-recursively))))