将计划转换为CL

时间:2013-05-26 16:13:49

标签: scheme common-lisp porting

我知道Scheme有点(很久以前就读过SICP),写了这个程序:

(define (prl k m)
  (define (print-line n)
    (cond ((> n 0) (display n)
                   (print-line (- n 1)))
          (else (newline))))
  (print-line k)
  (cond ((> m 1) (prl (+ k 1) (- m 1)))))

示例 - http://ideone.com/LuG45W

但我需要在CL中使用它,而不使用任何宏。你能帮我实施吗?感谢。

4 个答案:

答案 0 :(得分:4)

Common Lisp的方案。

    顶层的
  • SCHEME:DEFINECL:DEFUN
  • SCHEME:DEFINE作为本地定义为CL:FLETCL:LABELS
  • CL默认情况下是标准非尾调用优化。这意味着最好使用a)支持实现的TCO并指导编译器这样做或b)在必要/可能的情况下使用循环。另请注意,大多数解释器都不会在Common Lisp中执行TCO,即使编译器可能支持它。

所以代码将是:

(defun prl (k m)
  (flet ((print-line (n)
           (loop for i downfrom n downto 1 do (write i))
           (terpri)))
    (loop for i from k
          repeat m
          do (print-line i))))

答案 1 :(得分:3)

正如Rainer正确指出的那样,Óscar的解决方案并不完全正确,因为defun全局环境中定义了一个新函数。这应该是一个正确的翻译:

(defun prl (k m)
  (labels ((print-line (n)
             (cond ((> n 0)
                    (princ n)
                    (print-line (1- n)))
                   (t (terpri)))))
    (print-line k))
  (when (> m 1)
    (prl (1+ k) (1- m))))

但请注意,与Scheme不同,CL标准不保证尾调用优化。您必须检查实现的文档。

答案 2 :(得分:2)

在这种情况下从Scheme到CL的翻译非常简单:

(defun prl (k m)
  (labels ((print-line (n)
             (cond ((> n 0)
                    (princ n)
                    (print-line (- n 1)))
                   (t (terpri)))))
    (print-line k)
    (cond ((> m 1)
           (prl (+ k 1) (- m 1))))))

example

(prl 3 4)
(terpri)
(prl 1 4)

321
4321
54321
654321

1
21
321
4321

答案 3 :(得分:0)

(defun prl (k m)                   ; (define (prl k m)
  (prog (n)
    PRL
      (setf n k)                   ;   (print-line k)
    PRINT-LINE                     ;   (define (print-line n)
      (cond ((> n 0) (princ n)     ;     (cond ((> n 0) (display n)
               (decf n)            ;              (print-line (- n 1)))
               (go PRINT-LINE))
            (t (terpri)))          ;           (else (newline))))
      (cond                        ;   (cond 
        ((> m 1)                   ;    ((> m 1) 
         (incf k)                  ;     (prl (+ k 1) (- m 1)))))
         (decf m) (go PRL)))))

测试:

[19]> (prl 3 4)
321
4321
54321
654321
NIL
[20]> (prl 1 4)
1
21
321
4321
NIL