729442eea8d8548842a6e0947e333c7b

Most people have worked with a simple kind of function composition: one that is essentially (lambda (f g) (lambda (x) (f (g x)))). SRFI 41 (http://srfi.schemers.org/srfi-41/srfi-41.html) describes a more general composition, that takes an arbitrary number of functions, and that allows each function to return multiple values. Here's my version of the same idea, but using "reduce" from SRFI 1 (http://srfi.schemers.org/srfi-1/srfi-1.html), which I think is much cleaner from a functional programming point of view. Feel free to refactor this to make it even more functional. :-)

(Original version used "fold"; thanks to zbigniew on freenode #scheme for suggesting to use "reduce", to remove the redundant "values" call; plus, as Riastradh points out, that makes it tail-recursive also.)

(define (compose . fns)
  (define (make-chain fn chain)
    (lambda args
      (call-with-values (lambda () (apply fn args)) chain)))
  (reduce make-chain values fns))

Refactorings

No refactoring yet !

729442eea8d8548842a6e0947e333c7b

Chris Jester-Young

April 22, 2009, April 22, 2009 05:07, permalink

No rating. Login to rate!

zbigniew from freenode #scheme suggests that "fold" be replaced with "reduce"; this would then strip out the (redundant) "values" call at the start of the function chain. Thanks!

(define (compose . fns)
  (define (make-chain fn chain)
    (lambda args
      (call-with-values (lambda () (apply fn args)) chain)))
  (reduce make-chain values fns))
729442eea8d8548842a6e0947e333c7b

Chris Jester-Young

October 17, 2010, October 17, 2010 16:29, permalink

No rating. Login to rate!

Just for fun, I decided to make a pure define-only version, just to be slightly easier on the eyes. :-P Not really a serious entry compared to the above, but you get to see defines nested 4 deep!

(define (compose . fns)
  (define (make-chain fn chain)
    (define (call-chain . args)
      (define (call) (apply fn args))
      (call-with-values call chain))
    call-chain)
  (reduce make-chain values fns))

Your refactoring





Format Copy from initial code

or Cancel