laria
laria copied to clipboard
How in the world will types be represented in bytecode/Rust?
Suppose we have some Laria types:
// This is an opaque native type
extern type Entity;
enum Option[T] {
Some(T),
None,
}
struct Foo[T] {
maybe_tup: Option[(T, T)],
arr: Array[T, 0],
zst: (),
}
type Baz = Foo[i64];
How should these be represented in the VM? What would accessing/constructing these types look like from Rust? The first thing that comes to mind is a set of FromLaria/ToLaria traits that can either pull a type from a VM or push a type into a VM.
Possibility: Structs are restricted HashMaps
Lua, JavaScript, and Python all use dictionaries for their object type. It's possible that Laria could adopt this philosophy. At first blush, it seems like this goes against the statically-checked nature of Laria, but it's possible that we might be able to control what gets to modify these HashMaps, such as by only exposing free insertion methods to laria_vm. Script bindings would only be able to insert into existing fields, and types would be checked upon insertion. The runtime type check here is probably fine since there's no(?) feasible way to check native bindings at script compile time.
Structs might not end up being only HashMaps (it's unclear if it'd be better to stick methods on the type or in the VM's list of functions), but that'd be the primary interface for interacting with fields.
How generics would be represented is an open question, especially if having novel generic instantiations at runtime would be desirable (eg. creating a MyType[i32] in a binding even if no Laria functions do so). Perhaps some sort of type_params field on the struct could be used?
Possibility: Extern types are Arc<dyn Any>
Simply put, the implementation of extern types look something like this:
pub enum Value {
// ...
// This allocation seems pretty unfortunate...
Extern(Arc<dyn Any>),
}
Unfortunately, there doesn't seem to be a way to register a native type for a given extern type and check that any Laria values with that extern type have that same native type. TypeId sounds promising, but there is no way to downcast using a TypeId.
Prior art
- Lua typically uses tables for types. Lua's exact approach doesn't quite fit since such dynamic/duck-typish approaches defer errors to runtime, though the general concept might be useful.
- Lua also has userdata for native types.