From: shrchin@csug.cs.reading.ac.uk (Jonathan H. N. Chin)
Newsgroups: comp.lang.scheme
Subject: Re: trampolines
Date: 5 Sep 92 04:43:25 GMT
Organization: University of Reading

sm86+@andrew.cmu.edu (Stefan Monnier) writes:
>Excerpts from netnews.comp.lang.scheme: 4-Sep-92 trampolines Jonathan H.
>N. Chin@csug (2303)
>> Ignoring promises that refer to their own values, it seems that the
>> above code would after the first "force" always have to perform a
>> redundant `if' test of `result-ready?'.  I should have thought that
>> this requirement could be removed, and the code I have tried seems to
>> do this:
>>
>> (define make-trampoline
>>   (lambda (proc)
>>     (letrec ((the-promise (lambda()
>>                             (let ((result (proc)))
>>                               (begin
>>                                 (set! the-promise (lambda()
>>                                                     result))
>>                                 result)))))
>>       the-promise)))
>>
>> where `make-trampoline' is used in place of `make-promise'.
>> (aside: what would be a reasonable way to reformat the above?)

> [...makes the legitimate point that my code is wrong...]
>Bad Luck !

Rats. Thought I had tested that code. Obviously not. Okay then. How about
we add another level thus:

(define make-trampoline[2]
  (lambda (proc)
    (letrec ((dummy (lambda()
                      (let ((result (proc)))
                        (begin
                          (set! dummy (lambda()
                                        result))
                           result)))))
      (lambda()
        (dummy)))))

I tried this code, and it worked (or at least it seemed to... 8^).

However, I now have an extra layer of indirection -- the extra function call.
So, have I just lost the advantage of removing the test in the first place?

I tend to think in C terms. Would I be correct to think that in code such as:

(define x 0)
(define trampoline (make-trampoline (lambda()
                                      (+ x 1)))) 

that `trampoline' "points to" the closure created by the `letrec', rather
than pointing to `the-promise' which points to the closure. And hence when
`the-promise' changes, there is no affect on `trampoline'. Something like:

                     trampoline

                         |
                         v

   the-promise  -->  #<closure>

instead of:

   trampoline --> the-promise --> #<closure>

The question I then have is why does changing `dummy' in `make-trampoline[2]'
affect the closure "(lambda() (dummy))" although changes to `the-promise'
in the definition of `trampoline' (substituting `make-trampoline' for
`make-trampoline[2]') are *not* propagated?


From my previous post:
1) What prevents the R^4 `make-promise' from recursing indefinitely?

and now
2) Does `make-trampoline[2]' save over `make-promise' ?
3) If (2), how do I extend `make-trampoline[2]' to allow promises that
   refer to their values?

Thanks again,
Jonathan
-- 
Jonathan H N Chin (9 kyu) \ Dept. of Cybernetics, \ "Respondeo, etsi mutabor"
shrchin@uk.ac.rdg.susssys1 \ University of Reading \
bq305@cleveland.freenet.edu \ Box 225, Whiteknights \ < Rosenstock-Huessy >
jockstrap,mandy@CyberSpaceII \ Reading, RG6 2AY, U K \