Last active
August 1, 2018 15:09
-
-
Save patternspandemic/b6d0bcb7a5b7d895e9159d130c2ef3dd to your computer and use it in GitHub Desktop.
Pony: Passing isolates in tuples
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" | |
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