Skip to content

Instantly share code, notes, and snippets.

@patternspandemic
Last active August 1, 2018 15:09
Show Gist options
  • Save patternspandemic/b6d0bcb7a5b7d895e9159d130c2ef3dd to your computer and use it in GitHub Desktop.
Save patternspandemic/b6d0bcb7a5b7d895e9159d130c2ef3dd to your computer and use it in GitHub Desktop.
Pony: Passing isolates in tuples
"""
Sometimes it's useful to put an `iso` into a tuple. However, given iso's extreme
reference restrictions, it may not be clear as how to extract said isolate from
the tuple later on. The main thing to remember about any isolates in a tuple is
that there's no extracting them without completely breaking apart the tuple.
The reference to the containing tuple must be consumed, and therefor destroyed
so that the extracted iso is the only iso.
(Note: types are made explicit for clarity, but also provides the compiler our
intent of dealing with an iso, and not an alias (iso!). Doing this will often
get you the compiler error message you want to see, rather than one that is a
result of miss-understanding you intention.)
"""
class Foo
fun apply(): String =>
"Foo iso took a ride on a tuple!"
actor Main
new create(env: Env val) =>
// The items we'll put into a tuple.
let foo: Foo iso = Foo
let n: USize = 2
// In order to put `foo` into the tuple, and not an alias of it, foo must
// be consumed into the tuple's construction:
let t: (Foo iso, USize) = (consume foo, n) // So long `foo`!
// When it comes time to access elements of the tuple, extracting what was
// `foo` as a resurrected iso cannot be done directly. Only an alias can
// be created this way:
let alias_of_iso: Foo iso! = t._1 // OK, but not really useful.
// Attempting to consume the tuple element directly results in:
// Error: Consume expressions must specify a single identifier
//let bar: Foo iso = consume t._1
// The above is not allowed because the tuple `t` would still exist with its
// reference to the Foo iso, and with isolates there can be only one. Even
// if the above did work, `t` would be left incomplete of its type, only
// containing the element `n`. One might think a destructive read could be
// used to swap out the tuple's iso element, but tuples are simple immutable
// shells, and do not support reassignment of elements.
//
// The solution is to consume the entire tuple, and destructure it into its
// elemental parts:
(let foo': Foo iso, let n') = consume t // So long, tuple shell!
env.out.print(foo'())
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment