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