Jeffrey Siegal <jbs@quiotix.com> wrote:
+
 emdpek wrote:
 > (define (composemany . args)
 > (if (null? args)
 > (lambda (y) y)
 > (let ((first (car args))
 > (rest (cdr args)))
 > (lambda (x) (first ((apply composemany rest) x))))))

 A better solution is:
 (define (composemany . args)
 (lambda (x)
 (let loop ((args args))
 (if (null? args)
 x
 (let ((first (car args))
 (rest (cdr args)))
 (first (loop rest)))))))
+
Well, the only problems is that neither of your solutions permit the
last function (first applied) to accept multiple arguments, as in:
> (define 3rdarg (compose car cdr cdr list))
> (3rdarg 0 1 2 3 4)
2
>
"Compose" was discussed at length back in May of this year, and
the final version that seemed most useful to me was Al Petrofsky's
[a variant of the one by Matthias Blume]:
(define (compose . procs)
(if (null? procs)
values
(lambda args
(callwithvalues
(lambda () (apply (apply compose (cdr procs)) args))
(car procs)))))
This has the following advantages:
 Allows the last function to take multiple arguments, as shown above,
or as in this example:
> (define euclideanmetric
(compose sqrt
(curry apply +)
(curry map (curryr expt 2))
list))
> (euclideanmetric 3 4)
5
> (euclideanmetric 5 12)
13
> (euclideanmetric 1 2 3 4 5)
7.416198487095663
>
 Returns "values" when called with no args, which allows (compose)
to act as the identity function for both single and multiple values,
on both on the left & right sides:
> ((compose (compose) reverse (compose) list (compose)) 1 2 3 4)
(4 3 2 1)
>
 Allows the intermediate results to be multiple values.
> (define list>values (curry apply values))
> (define euclideanmetric
(compose sqrt + list>values (curry map (curryr expt 2)) list))
> (euclideanmetric 3 4)
5
>
Rob
p.s. "curry" & "curryr" left as an exercise for the reader... ;}

Rob Warnock, 303510 <rpw3@sgi.com>
SGI Network Engineering <http://reality.sgi.com/rpw3/>
1600 Amphitheatre Pkwy. Phone: 6509331673
Mountain View, CA 94043 PPASELIA
[Note: aaanalyst@sgi.com and zedwatch@sgi.com aren't for humans ]