-
Notifications
You must be signed in to change notification settings - Fork 96
Using interfaces
In order to abstract away actual data types, the object model supports interfaces. An interface defines a set of methods that are more or less semantically related.
Contrary to interfaces in most programming languages, which are implemented only by certain data types, interfaces in the VM object model are conceptually implemented by all data types. It's just that interface methods have a default implementation (for data types that do not provide a specific one). For most operations, this default implementation raises a type error exception.
In a previous page, we used the following trivial code:
UnstableNode node = SmallInt::build(vm, 5);
RichNode richNode = node;
assert(richNode.is<SmallInt>());
cout << richNode.as<SmallInt>().value() << endl;
Let us now update this code to use the IntegerValue
interface:
UnstableNode node = SmallInt::build(vm, 5);
nativeint value = IntegerValue(node).intValue(vm);
cout << value << endl;
Now, we have abstracted away our code from the actual data type which was SmallInt
. The method IntegerValue::intValue()
takes care of the dispatching for us.
Now, what if the Oz value in node
was not an integer? If it had another type (say a Boolean), then this will raise a type error. If however it is an unbound variable (or any other transient, for that matter), then the code will automatically wait for that variable. At the C++ level, in both cases an exception is thrown, which is catched by emulator loop, which knows what to do with such things.