view 2-Io/day3-concurrency.io @ 90:c27c87cd0f08

Add most of the Day 2 exercises for Haskell
author IBBoard <dev@ibboard.co.uk>
date Sun, 16 Jun 2019 21:09:33 +0100
parents 03782444978f
children
line wrap: on
line source

# 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