普通Lisp中的递归“组合”(从方案翻译)

时间:2019-04-26 14:29:11

标签: common-lisp

我正在学习Common Lisp。还不知道Scheme。

在Common Lisp中关注 crypto.subtle.digest('SHA-512', stringvar); 没问题

compose

(有趣的是compose和reduce之间的深层相似性)

然后,在阅读中,我在Scheme中找到了(defun compose (&rest fns) (destructuring-bind (fn1 . rest) (reverse fns) #'(lambda (&rest args) (reduce #'(lambda (v f) (funcall f v)) rest :initial-value (apply fn1 args))))) 中的example,但是像这样递归地完成了:

compose

我试图将以上内容翻译成Common Lisp(在这里比较黑暗):

(define (compose . fs)
  (if (null? fs) (lambda (x) x)
      (lambda (x) ((car fs) ((apply compose (cdr fs)) x)))))

有趣的是上面的东西产生了:

(defun compose-r (&rest fs)
  (if (null fs)
      #'(lambda (x) x)                   ; base case
      #'(lambda (x) (funcall (car fs)    ; first given fn, applied to...
                     (compose-r (cdr fs) x)))))

所以有些事情可行,但是我错过了一个函数调用。

如果有人可以使用此示例指出Common Lisp和Scheme之间的一些关键区别,并概述在翻译时必须知道的关键事情,那也许很棒。

我已经注意到,在方案中,似乎可以在表达式的位置零处评估一个表达式,而Common Lisp则抱怨“应该是lambda表达式”。

谢谢。

1 个答案:

答案 0 :(得分:5)

(define (compose . fs)
  (if (null? fs)
      (lambda (x) x)
      (lambda (x)
        ((car fs)
         ((apply compose (cdr fs)) x)))))

(defun compose (&rest fs)
  (if (null fs)
      (lambda (x) x)
      (lambda (x)
        (funcall (car fs)
                 (funcall (apply #'compose (cdr fs)) x)))))

然后:

CL-USER 53 > (mapcar (compose #'list #'abs #'round #'sqrt) '(4 9 16 25 130))
((2) (3) (4) (5) (11))

Common Lisp的主要区别:

  • 使用FUNCALL
  • 调用函数对象
  • 使用#'some-fun(function some-fun)检索功能对象