I'm studying Common Lisp. Don't know Scheme yet.
I have no problem with following compose
in 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)))))
Run Code Online (Sandbox Code Playgroud)
(it's interesting the deep similarity between compose & reduce :) )
Then, reading around, I found an example of compose
in Scheme, but done recursively, like so:
(define (compose . fs)
(if (null? fs) (lambda (x) x)
(lambda (x) ((car fs) ((apply compose (cdr fs)) x)))))
Run Code Online (Sandbox Code Playgroud)
My attempt to translate the above to Common Lisp (rather in the dark here):
(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)))))
Run Code Online (Sandbox Code Playgroud)
Interestingly the above produces:
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]>
Run Code Online (Sandbox Code Playgroud)
So something's working but I missed a function call.
It would be great perhaps if someone could use this example to point out some key differences between Common Lisp and Scheme and to outline the key things one must know in translating.
I already noticed that in scheme it seems possible to evaluate an expression in position zero of an expression, whereas Common Lisp complains that "should be a lambda expression".
Thanks in advance.
(define (compose . fs)
(if (null? fs)
(lambda (x) x)
(lambda (x)
((car fs)
((apply compose (cdr fs)) x)))))
Run Code Online (Sandbox Code Playgroud)
is
(defun compose (&rest fs)
(if (null fs)
(lambda (x) x)
(lambda (x)
(funcall (car fs)
(funcall (apply #'compose (cdr fs)) x)))))
Run Code Online (Sandbox Code Playgroud)
Then:
CL-USER 53 > (mapcar (compose #'list #'abs #'round #'sqrt) '(4 9 16 25 130))
((2) (3) (4) (5) (11))
Run Code Online (Sandbox Code Playgroud)
The main differences in Common Lisp:
FUNCALL
#'some-fun
or (function some-fun)