Mercurial > repos > other > SevenLanguagesInSevenWeeks
changeset 49:03782444978f
Add coroutine, actor and futures code
author | IBBoard <dev@ibboard.co.uk> |
---|---|
date | Fri, 22 Sep 2017 20:38:44 +0100 |
parents | 46a807289724 |
children | b94161b72db6 |
files | 2-Io/day3-concurrency.io |
diffstat | 1 files changed, 58 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/2-Io/day3-concurrency.io Fri Sep 22 20:38:44 2017 +0100 @@ -0,0 +1,58 @@ +# Concurrency and coroutines don't appear to need any special syntax beyond "yield" +# and a slight tweak to how you invoke the method/send the message + +vizzini := Object clone +vizzini talk := method( + "Fezzik, are there rocks ahead?" println + yield + "No more rhymes now, I mean it." println + yield +) + +fezzik := Object clone +fezzik rhyme := method( + yield + "If there are, we'll all be dead." println + yield + "Anoybody want a peanut?" println +) + +# The magic happens here - call it with "@@" and it gets kicked off in a thread +vizzini @@talk; fezzik @@rhyme +# And further magic with classes/functions we never knew existed before, +# which holds the thread open until the threads are done +# (Initially this looked like two lines of Coroutine output joined together in print!) +#Coroutine currentCoroutine pause +# It's not clear WHY they're yielding to each other. Nothing in the code appears to +# create a relationship, and in other languages then the threads would run at +# arbitrary slices and (semi-randomly) intersperse their output without the yields. +# But Io. +# Oh, and apparently we can't use it when we want to do other things afterwards, +# because we get "Scheduler: nothing left to resume so we are exiting". So +# it isn't the same as "join" in other languages to wait for threads to finish/merge + +# Apparently "asyny messages" (@@) makes something an actor +slower := Object clone +slower start := method(wait(2); writeln("2s delay")) +faster := Object clone +faster start := method(wait(1); writeln("1s delay")) +# Even though slower starts first, they should be threaded so faster should print first +slower @@start; faster @@start; wait(3) + + +# Futures use a single "@" and are more sensible. They return a placeholder straight away +# but let you carry on with other things, then block when you call them until the value +# is *actually* available +slow_method := method(wait(3); return "Some slow value") +"Calling slow method" println +value := @slow_method +"Now we do other stuff…" println +"And a bit more" println +"And now we try to print the value…" println +value println +"That should have paused, but not due to the outer code" println +"Wut?" println +"Now everything prints twice!" println +"What is going on?" println +"It's as if Io created a second thread for no discernable reason!" println +"But it isn't anything to do with our slower/faster threads, because everything before printing 'value' is fine" println \ No newline at end of file