class Map<K, V> {
...
V getOrSignal(K key) {
if containsKey(key) {
return get(key);
} else {
MissingKeySignal signal = throw new MissingKeyException(this, key);
return switch signal {
case ReturnValueSignal(value) -> defaultValue,
case PutAndReturnValueSignal(value) -> {
put(key, value);
return value;
},
case TryAnotherKeySignal(otherKey) -> getOrSignal(otherKey)
}
}
}
}
class MissingKeyException<K, V> extends ResumableException<MissingKeySignal<K, V>> { ... }
sealed interface MissingKeySignal<K, V> permits ReturnValueSignal, PutAndReturnValueSignal, TryAnotherKeySignal {}
record ReturnValueSignal<K, V>(V defaultValue) implements MissingKeySignal<K, V> {}
record PutAndReturnValueSignal<K, V>(V value) implements MissingKeySignal<K, V> {}
record TryAnotherKeySignal<K, V>(K otherKey) implements MissingKeySignal<K, V> {}
class MyVideogameApp {
public static void main(String... args) {
try {
...
} catch resumably (MissingKeyException e) {
... show exception to user, ask for what signal they want to send back ...
... this could show a GUI dialog instead of printing to the console and reading input ...
MissingKeySignal response = printExceptionAndAskForMissingKeyResponseSignal(e);
resume response; // resume at the point the exception was thrown, sending response as the signal
// if the resume keyword isn't called, the exception propagates as usual
// any catch blocks with resume statements in them prevent finally blocks from running until after
// it's known whether or not the exception will fatally throw or not.
// if the exception is rethrown, all paused finally blocks execute.
}
}
}
Created
June 30, 2022 21:43
-
-
Save jackfirth/d22dc4ea592ac39d76739f665eb7bbf8 to your computer and use it in GitHub Desktop.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment