[REBOL] Re: CPS transformations on func tion! values
From: maarten:koopmans:surfnet:nl at: 1-Mar-2003 13:14
Hey Joel,
> I had thought about this, but hit the wall except for thoughts to
> would be the subject of further articles in the series of articles
> on REBOLforces (Recursion->Iteration->Objects->Tasks).
>
I don't want to limit myself to tasks only. Migratable processes! I know
stackless python was there and will be there soon (again).
> But to me, storing control flow is part of the state.
>
> For some simple cases, such as the example below (forgive me for the
> definition of VOWELS, speakers of something other than English, I'm
> just trying to make a small example ;-)
>
> vowels: charset "AEIOUaeiou"
> count-vowels: func [s [string!] /local count] [
> count: 0
> parse s [
> any [
> vowels (count: count + 1)
> |
> skip
> ]
> ]
> count
> ]
> foreach message [
> "Eat at Joe's!"
> "Hello, world!"
> "My dog has fleas."
> ][
> yield reduce [count-vowels message tab message]
> ]
>
> Let's imagine that the word YIELD somehow saves state in a place/way
> that it can be RESUMEd later, and returns the value of the following
> expression.
>
> I can understand how to transform all of this into an object with a
> STEP method, which returns for each call a single YIELDed result:
>
> my-obj: make object! [
> vowels: charset "AEIOUaeiou"
> count-vowels: func [s [string!] /local count] [
> count: 0
> parse s [
> any [
> vowels (count: count + 1)
> |
> skip
> ]
> ]
> count
> ]
> messages: []
> start: func [b [block!]] [messages: copy/deep b]
> step: func [/local message] [
> if not tail? messages [
> message: first messages
> messages: next messages
> return reduce [
> count-vowels message tab message
> ]
> ]
> ]
> ]
>
> my-obj/start [
> "Eat at Joe's!"
> "Hello, world!"
> "My dog has fleas."
> ]
> print my-obj/step
>
> ; ... arbitrary other unrelated stuff occurs
>
> print my-obj/step
>
> ; ... more unrelated stuff
>
> while [found? answer: my-obj/step] [print answer]
>
> but if the YIELD had been placed inside the PARSE, as in
>
> vowels: charset "AEIOUaeiou"
> yield-vowels: func [s [string!] /local vowel] [
> parse s [
> any [
> vowel: vowels (yield first vowel)
> |
> skip
> ]
> ]
> none
> ]
> foreach message [
> "Eat at Joe's!"
> "Hello, world!"
> "My dog has fleas."
> ][
> yield reduce [count-vowels message tab message]
> ]
>
> then implementing this would require substantial rewriting of the
> use of PARSE (assuming that we don't have a way to get/set the
> state of an in-process PARSE evaluation).
>
> My conclusion was that if I were going to be able to model a
> yield/resume scenario (within my lifetime, at least ;-), I'd be
> better off writing each one individually rather than trying to
> come up with an automatic rewriting mechanism. Of course, there
> are folks who can probably do more with this idea than I...
>
Yes, but your mindset is yield/resume. In a CPS transformation you pass
in a continuation and never return (as a function). You simply call the
continuation (which basically is what-to-do-next). To do that you'll
need to transform a function body to tail-form, and there lies my problem.
How do you deal with do/reduce/compose and the likes?
Where is that Guru (Carl) when you need him ;-)
--Maarten