Я изучаю Common Lisp. Схема еще не знаю.
У меня нет проблем со следующим compose
в Common Lisp
(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)))))
(интересно глубокое сходство между составлением и уменьшением :))
Затем, читая вокруг, я нашел пример из compose
в Схеме, но сделал рекурсивно, вот так:
(define (compose . fs)
(if (null? fs) (lambda (x) x)
(lambda (x) ((car fs) ((apply compose (cdr fs)) x)))))
Моя попытка перевести вышеприведенное в Common Lisp (скорее в темноте):
(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)))))
Интересно, что вышеперечисленное производит:
COMPOSE-R
[179]> (mapcar (compose-r #'list #'abs #'round #'sqrt) '(4 9 16 25 130))
((#<FUNCTION :LAMBDA (X) (FUNCALL (CAR FS) (COMPOSE-R (CDR FS) X))>)
(#<FUNCTION :LAMBDA (X) (FUNCALL (CAR FS) (COMPOSE-R (CDR FS) X))>)
(#<FUNCTION :LAMBDA (X) (FUNCALL (CAR FS) (COMPOSE-R (CDR FS) X))>)
(#<FUNCTION :LAMBDA (X) (FUNCALL (CAR FS) (COMPOSE-R (CDR FS) X))>)
(#<FUNCTION :LAMBDA (X) (FUNCALL (CAR FS) (COMPOSE-R (CDR FS) X))>))
[180]>
Итак, что-то работает, но я пропустил вызов функции.
Было бы здорово, если бы кто-то мог использовать этот пример, чтобы указать на некоторые ключевые различия между Common Lisp и Scheme, а также наметить ключевые вещи, которые нужно знать при переводе.
Я уже заметил, что в схеме представляется возможным оценить выражение в нулевой позиции выражения, тогда как Common Lisp жалуется, что «должно быть лямбда-выражением».
Заранее спасибо.