Odd word problem/SimpleCoroutineSupportForJ: Difference between revisions

From Rosetta Code
Content added Content deleted
mNo edit summary
(bug fix (Aai emailed me both the problem and solution here))
 
(2 intermediate revisions by the same user not shown)
Line 8: Line 8:
verb=. u
verb=. u
noun=. y
noun=. y
while. do.
while. do. context=. verb noun
context=. verb noun
select. (0 {:: context) * 1+*#stack
select. (0 {:: context) * 1+*#stack
case. 0 do. NB. yield
case. 0 do. NB. yield
stack=. stack, 2 { context
stack=. stack, 1 { context
verb=. (3 { context)`:0
verb=. (2 { context)`:0
noun=. 1 {:: context
noun=. 3 {:: context
case. 1 do. NB. return (with empty stack)
case. 1 do. NB. return (with empty stack)
1 {:: context return.
1 {:: context return.
Line 27: Line 26:
)
)


NB. u yield v y return. NB. deferred result 0: u v y
NB. u yield v y return. NB. 0 -- deferred result, will be executing: u v y
yield=: 2 :0
yield=: 2 :0
0; y; u ` v
0; u ` v,< y
)
)


NB. return y return. NB. immediate result 1: y
NB. return y return. NB. 1 -- immediate result: y
return=: 3 :0
return=: 3 :0
1; y
1; y

Latest revision as of 15:45, 9 August 2012

Here is a simplistic coroutine implementation for J.

Note that this version does not support switching between coroutine contexts -- that would have been an unnecessary complication for this task. (So, technically, it might be better to call this "coroutine inspired".)

<lang j>NB. u coroutine y NB. execute u in new coroutine context coroutine=: 1 :0

 stack=. 
 verb=. u
 noun=. y
 while. do. context=. verb noun
   select. (0 {:: context) * 1+*#stack
     case. 0 do.                   NB. yield
       stack=. stack, 1 { context
       verb=. (2 { context)`:0
       noun=.  3 {:: context
     case. 1 do.                   NB. return (with empty stack)
       1 {:: context return.
     case. 2 do.                   NB. return (with work remaining on stack)
       verb=. ({: stack)`:0
       noun=. 1 {:: context
       stack=. }: stack
     case. do.                     NB. (default)
       invalid coroutine 1 :'error.'
   end.
 end.

)

NB. u yield v y return. NB. 0 -- deferred result, will be executing: u v y yield=: 2 :0

 0; u ` v,< y

)

NB. return y return. NB. 1 -- immediate result: y return=: 3 :0

 1; y

)</lang>

The philosophy here, is: A noun represents code which has already been executed (it's the result of that code having been executed). A verb represents code which has not yet been executed.

A coroutine verb must return a result built by one of the two helper verbs return or yield. If yield is used, it must be supplied with two verbs and a noun. The coroutine context will stack u (the left verb) for later execution and it's argument will be the result of whatever verb was most recently executed by the coroutine context. Meanwhile the coroutine context will execute v (the right verb) right away and its argument will be the noun which was supplied to yield. Both u and v must be coroutine verbs (so they also must must provide a result prepared by return or yield).