From: ·········@hotmail.com
Subject: Newbie question: writing a composer function in Lisp
Date: 
Message-ID: <1190176560.992787.246750@z24g2000prh.googlegroups.com>
Hi,

I am a newbie inLisp, and thought I could try things that would be
hard in other languages. I am trying to write a composer function.
That is, it takes a list of functions f1, f2, f3, ... fn and returns a
function that does, in regular math notation, f1 (f2 (f3 ...
(fn))...).

Here is my code, but evidently, I am not too good with the Lisp
syntax. Any pointers would be greatly appreciated. Of course, I
thought I would try the single argument lambda on the function first,
and then use the &rest there too (and find out if it works). Thanks in
advance!

Regards,

SK

Code:
(defun my-compose (&rest function-list)
           (if (= 1 (length function-list))
               #'(lambda(x) (funcall (car function-list) x))
               #'(lambda(x) (funcall (car function-list) (funcall (my-
compose (cdr function-list)) x)))))

Invocation to compose the compound function:
(setf b (my-compose (list #'sin #'cos)))

Invocation to use it:
(funcall b 0.5)

I get an error message. BTW, I am using Emacs SLIME, which I believe
is Common Lisp.

From: Dimiter "malkia" Stanev
Subject: Re: Newbie question: writing a composer function in Lisp
Date: 
Message-ID: <5lboubF7gcmcU1@mid.individual.net>
Hi,

> Code:
> (defun my-compose (&rest function-list)
>            (if (= 1 (length function-list))
>                #'(lambda(x) (funcall (car function-list) x))
>                #'(lambda(x) (funcall (car function-list) (funcall (my-
> compose (cdr function-list)) x)))))
> 

If you change car to caar, it would work:

(defun my-compose (&rest function-list)
   (if (= 1 (length function-list))
     #'(lambda(x) (funcall (caar function-list) x))
     #'(lambda(x) (funcall (caar function-list)
                           (funcall (my-compose (cdr function-list)) x)))))

But it won't be correct.

The problem is that you are using (&rest function-list), which would 
would put all the rest arguments in list itself, and that's why you need 
double car - caar.

In fact, you don't need (&rest function-list), so the correct solution is:

(defun my-compose (function-list)
   (if (= 1 (length function-list))
     #'(lambda(x) (funcall (car function-list) x))
     #'(lambda(x) (funcall (car function-list)
                           (funcall (my-compose (cdr function-list)) x)))))

Thanks,
Dimiter "malkia" Stanev.
From: Barry Margolin
Subject: Re: Newbie question: writing a composer function in Lisp
Date: 
Message-ID: <barmar-521E4F.01123019092007@comcast.dca.giganews.com>
In article <························@z24g2000prh.googlegroups.com>,
 ·········@hotmail.com wrote:

> Hi,
> 
> I am a newbie inLisp, and thought I could try things that would be
> hard in other languages. I am trying to write a composer function.
> That is, it takes a list of functions f1, f2, f3, ... fn and returns a
> function that does, in regular math notation, f1 (f2 (f3 ...
> (fn))...).
> 
> Here is my code, but evidently, I am not too good with the Lisp
> syntax. Any pointers would be greatly appreciated. Of course, I
> thought I would try the single argument lambda on the function first,
> and then use the &rest there too (and find out if it works). Thanks in
> advance!
> 
> Regards,
> 
> SK
> 
> Code:
> (defun my-compose (&rest function-list)
>            (if (= 1 (length function-list))

Simpler: (if (null (cdr function-list))

This doesn't require counting the length of the list on each recursion.

>                #'(lambda(x) (funcall (car function-list) x))

This is equivalent to (car function-list).

>                #'(lambda(x) (funcall (car function-list) (funcall (my-
> compose (cdr function-list)) x)))))

In your recursive call, you're passing a list of functions as a single 
argument, rather than spreading them out as an &rest argument.  You need 
to use APPLY:

#'(lambda (x) (funcall (car function-list)
                       (funcall (apply #'my-compose (cdr function-list))
                                x)))

> 
> Invocation to compose the compound function:
> (setf b (my-compose (list #'sin #'cos)))
> 
> Invocation to use it:
> (funcall b 0.5)
> 
> I get an error message. BTW, I am using Emacs SLIME, which I believe
> is Common Lisp.

-- 
Barry Margolin, ······@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***
*** PLEASE don't copy me on replies, I'll read them in the group ***
From: D Herring
Subject: Re: Newbie question: writing a composer function in Lisp
Date: 
Message-ID: <8uOdnXG4iuHcKm3bnZ2dnUVZ_qWtnZ2d@comcast.com>
·········@hotmail.com wrote:
> Code:
> (defun my-compose (&rest function-list)
>            (if (= 1 (length function-list))
>                #'(lambda(x) (funcall (car function-list) x))
>                #'(lambda(x) (funcall (car function-list) (funcall (my-
> compose (cdr function-list)) x)))))
> 
> Invocation to compose the compound function:
> (setf b (my-compose (list #'sin #'cos)))
> 
> Invocation to use it:
> (funcall b 0.5)

This should fix it (borrowing from Barry's reply):
(defun my-compose (&rest function-list)
   (if (cdr function-list)
       (lambda (x)
         (funcall (car function-list)
                  (funcall (apply 'my-compose (cdr function-list)) x)))
       (lambda (x)
         (funcall (car function-list) x))))
(funcall (my-compose 'sqrt 'sqrt) 16)

Here's another variant of compose.
(defun compose (f &optional (g f))
   (lambda (x)
     (funcall f (funcall g x))))
(funcall (compose 'sqrt) 16)


FWIW, multiple compositions might be worth a macro...


> I get an error message. BTW, I am using Emacs SLIME, which I believe
> is Common Lisp.

Nitpick: Slime is an editing environment that attaches to Lisp; 
(lisp-implementation-type) and (lisp-implementation-version) should 
tell you which one its using.

OT: For kicks, try (describe 'my-compose).

- Daniel
From: ········@yahoo.es
Subject: Re: Newbie question: writing a composer function in Lisp
Date: 
Message-ID: <1190227793.005959.256170@57g2000hsv.googlegroups.com>
On 19 sep, 07:48, D Herring <········@at.tentpost.dot.com> wrote:
> ·········@hotmail.com wrote:
> > Code:
> > (defun my-compose (&rest function-list)
> >            (if (= 1 (length function-list))
> >                #'(lambda(x) (funcall (car function-list) x))
> >                #'(lambda(x) (funcall (car function-list) (funcall (my-
> > compose (cdr function-list)) x)))))
>
> > Invocation to compose the compound function:
> > (setf b (my-compose (list #'sin #'cos)))
>
> > Invocation to use it:
> > (funcall b 0.5)
>
> This should fix it (borrowing from Barry's reply):
> (defun my-compose (&rest function-list)
>    (if (cdr function-list)
>        (lambda (x)
>          (funcall (car function-list)
>                   (funcall (apply 'my-compose (cdr function-list)) x)))
>        (lambda (x)
>          (funcall (car function-list) x))))
> (funcall (my-compose 'sqrt 'sqrt) 16)
>
> Here's another variant of compose.
> (defun compose (f &optional (g f))
>    (lambda (x)
>      (funcall f (funcall g x))))
> (funcall (compose 'sqrt) 16)
>
> FWIW, multiple compositions might be worth a macro...
>
> > I get an error message. BTW, I am using Emacs SLIME, which I believe
> > is Common Lisp.
>
> Nitpick: Slime is an editing environment that attaches to Lisp;
> (lisp-implementation-type) and (lisp-implementation-version) should
> tell you which one its using.
>
> OT: For kicks, try (describe 'my-compose).
>
> - Daniel

; This one use dolist:

(defun compose(&rest fs)
  (let ( (fs (reverse fs)) re)
    (lambda(x)  (setq re x)
      (dolist(f fs re)
        (setq re (funcall f re))))))

;example (funcall (compose (lambda(x)(* x x)) (lambda(x)(+ x 4)))   5)
81