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!