Re: Functional Programming in the Larger or Functional Oriented Software Engineering

Daniel Yoo <[email protected]> Sun, 18 Mar 2007 14:36:01 -0400 (EDT)
Newsgroups gmane.comp.lang.lightweight
Message-ID <[email protected]>
>> - Functional programming doesn't scale very well. Function composition
>>   seems to be very straightforward because it allows you to take two
>>   functions and combine them into one. However, as soon as functions
>>   are defined recursively by calling themselves, function composition
>>   doesn't work that well anymore. Consider:
>>
>> (define (fac x)
>>   (if (= x 0) 1 (* x (fac (- x 1)))))
>>
>> There is no straightforward way to compose fac with another function in 
>> a way such that the recursive call inside fac to itself gets redirected 
>> to the composite function.


I remember seeing some paper that I think addresses this; there was a 
paper called "Code reuse through polymorphic variants":

     http://www.math.nagoya-u.ac.jp/~garrigue/papers/fose2000.html

The example in Section 4 shows a nice example of modularized recursive 
functions.  A raw example of this might be:

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(define (fac self x)
   (if (= x 0)
       1
       (* x (self self (- x 1)))))

(define (extend/debug f)
   (lambda (self x)
     (display "debug: ")
     (display x)
     (newline)
     (f self x)))

(define (extend/memoize f)
   (let* ([cache '()]
          [lookup (lambda (x) (assoc x cache))]
          [insert! (lambda (k v)
                     (set! cache (cons (cons k v) cache)))])
     (lambda (self x)
       (cond
         [(lookup x) => cdr]
         [else
          (let ([result (f self x)])
            (insert! x result)
            result)]))))

(define debug-fac
   (let ([f (extend/debug fac)])
     (lambda (n)
       (f f n))))

(define memoized-debug-fac
   (let ([f (extend/memoize (extend/debug fac))])
     (lambda (n)
       (f f n))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


Best of wishes!