unison
unison copied to clipboard
Add a "TypeTag" primitive type (and means to instantiate it)
Problem statement
At the time of writing this, persistent named constructs (such as tables, services, etc) are typically expressed as phantom types. As such, they do not carry the necessary information to allow for pre-emptive runtime-checks that would validate that the type information they were initially created from has not changed by the time of querying. I think this will lead to unfortunate situations where the type safety we get at compile time will not translate to the reality of ever-evolving software.
Imagined solution
I think this problem could be easily mitigated by the existence of a built-in TypeTag a construct that'd allow to capture the immutable hash of a type at compile time and make it accessible to the runtime, for comparison purposes, whilst retaining the type information. Alongside a built-in function that'd be conceptually similar to typeLink but that would retain type information.
Although it'd be cool to have a poly-kinded TypeTag, an initial implementation could certainly be constrained to fully-applied types for simplicity.
Outside of a built-in function to construct TypeTags, the desired interface would be :
-- gets underlying hash as a text
toText: TypeTag a -> Text
-- compares the underlying hashes
equals: TypeTag a -> TypeTag b -> Boolean
I think this would open the door to a bunch of interesting solutions, like registering nodes with a cluster by the set of abilities they provide, or facilitating hot-migrations of tables, or even having type-indexed maps for whatever purpose.
Alternatives considered
I don't think there's anything currently provided by the language or its base library that would allow the kind of pre-emptive runtime checks that would verify that types have not changed between the creation of a persistent construct and its use.