[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Chicken-users] Difference in behaviour with code compiled with csc
From: |
Thomas Chust |
Subject: |
Re: [Chicken-users] Difference in behaviour with code compiled with csc and code run with csi. |
Date: |
Sun, 7 Dec 2014 15:16:15 +0100 (CET) |
User-agent: |
Alpine 2.03 (LNX 1266 2009-07-14) |
On Sat, 6 Dec 2014, Joe Python wrote:
I was experimenting with a coroutine example which i got from the c2
website. see link below for code.
http://paste.call-cc.org/paste?id=cf4489b9de4820b330dc34371ea3b73a18115a4b#a0
I get the expected output when I run the code using csi
[...]
However when i run the executable which i compiled with csc, i get [...]
unexpected output.
[...]
Hello Joe,
this seems to have something to do with the fact that the toplevel behaves
slightly differently in compiled and interpreted code. While the toplevel
expressions of each compilation unit essentially form a single procedure
body, the toplevel expressions fed to the interpreter are processed
independently. This can make a difference when capturing the continuation
of a toplevel expression.
Furthermore, the control flow in your code is probably not what you expect
it and want it to be: Your coroutine constructor arranges for the
continuation of the *first* coroutine invocation to be captured and used
for returns of *every* yield statement.
You can easily verify the combined effect of these phenomena by inserting
some print statements around the coroutine invocations at the end of your
program. In the interpreted case, the captured continuation incidentally
returns control to the surrounding read eval loop, however in the compiled
case the captured continuation returns you to the place in the program
between the first an second explicit coroutine invocation, effectively
constructing an endless loop around the second invocation.
A quick fix for the problem would be to actually use the new return
continuations returned by the yield expressions upon re-entry into the
coroutine: Simply replace every call of (yield WHATEVER) in your coroutine
body by (set! yield (yield WHATEVER)) and the program will behave
identically (and correctly, I might add) in compiled and interpreted mode.
If you find that solution inelegant, you might want to encapsulate this
behaviour of yield into a macro or use parameters to implement a global
yield procedure instead.
I hope this helps :-)
Ciao,
Thomas
--
When C++ is your hammer, every problem looks like your thumb.