Jeffrey Siegal <jbs@quiotix.com> wrote:
+---------------
| emdpek wrote:
| > (define (compose-many . args)
| > (if (null? args)
| > (lambda (y) y)
| > (let ((first (car args))
| > (rest (cdr args)))
| > (lambda (x) (first ((apply compose-many rest) x))))))
|
| A better solution is:
| (define (compose-many . 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 3rd-arg (compose car cdr cdr list))
> (3rd-arg 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
(call-with-values
(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 euclidean-metric
(compose sqrt
(curry apply +)
(curry map (curry-r expt 2))
list))
> (euclidean-metric 3 4)
5
> (euclidean-metric 5 12)
13
> (euclidean-metric 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 euclidean-metric
(compose sqrt + list->values (curry map (curry-r expt 2)) list))
> (euclidean-metric 3 4)
5
>
-Rob
p.s. "curry" & "curry-r" left as an exercise for the reader... ;-}
-----
Rob Warnock, 30-3-510 <rpw3@sgi.com>
SGI Network Engineering <http://reality.sgi.com/rpw3/>
1600 Amphitheatre Pkwy. Phone: 650-933-1673
Mountain View, CA 94043 PP-ASEL-IA
[Note: aaanalyst@sgi.com and zedwatch@sgi.com aren't for humans ]