-
Notifications
You must be signed in to change notification settings - Fork 140
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Get the run-time type of an object #195
Comments
Thanks for the feature request @kharlov-art! I think adding
|
For most values it is pretty straightforward to return their static type. For containers (array, dictionary, optional values, etc.), we currently don’t store the static element type, so I can't see how we could implement this in a backwards-compatible way for those types. |
I think we only need this for resources to satisfy the immediate use cases. So this could be a function on AnyResource. If we force unwrap an optional to get a resource can we get the static Type of the resulting resource in the same straightforward way? |
Right, we could just start with composite types for now (resources, structs, etc.) and of course the other primitive values (number types, string, bool, path, etc.). We couldn't have the type function/field on For optionals, you wouldn't want to force-unwrap, because there could be no value, but yes, you could get the type of the optional's value if there is one. |
I would suggest that we can make it a run-time error to query the type of a container in the first implementation, or just have built-in Most critically, I think we need the ability to query a Vault to know which fungible token we've been handed, especially in the FT DEX or NFT Marketplace contexts. Additionally, lots of off-chain NFT code will want the ability to use scripts to get a string version of an NFT's type, so it can show users the detail of NFTs that are stored in contexts where the concrete type isn't available statically. |
A more future-proof way to handle the array/dictionary cases might be to add the ability to check what kind of resource/struct something is. So Type.kind or Type.isArray(), Type.isResource() etc. That would be somewhat related to #442 . But we don't need that right now so I think an error might be best, as that makes sure nobody relies on something we will change later. |
A quick sketch of how this would help with an FT DEX:
|
@dete @robmyers What do you think about making this function return an optional, i.e. have it be We would start storing the static type for arrays, dictionaries, and optionals, for new values, that we could return the type for those values; and for backwards-compatiblity, we would just return |
Some notes:
|
I'm curious what a "Type" is. I assume it's a value type, not a resource. Are there any limits on creating a Type object? Could I create a Type value that doesn't reference any actual types defined in the system? If it's not too difficult, I would be inclined to return a "sentinel" Type value that is inert for now, but will have additional functionality in the future. So, maybe calling getType on an array/dictionary/optional returns the "Internal Type" type, that today is just an opaque empty thing that is no more useful that the Of course, if that's too much effort, I do think returning an optional is totally okay for now. |
Correct, it's a value type, not a resource.
Types can only be acquired for static types, so it's not possible to create a type that is not declared somewhere.
That's a great idea! I like the idea of not having to introduce the optional / bug developers with handling the "unknown" case. 👍 |
Just thinking this through, this would mean that we cannot construct a Type with an SDK then pass it in to Cadence as a transaction/script argument - the entity that we wish to fetch the Type of must be accessible within the body of the code. Given this I am wondering about types in events: do they represent useful information, or are they likely to mislead developers who will want to capture them off-chain and then feed them back in to transactions?
Yes I agree with this. |
Does this require changing data currently stored by nodes on the live network?
Does this introduce much run-time overhead? |
Good point, but what I meant was not that we should prohibit importing types in general, just not ones that don't exist / "are not declared in the system". I looked at the current code and saw that we do not support this yet. I opened #491 to implement it.
Good point! I think this is a great idea and would be very useful. Again, I checked the code and saw that we currently don't allow types to be used in events (event parameters cannot have type
The problem is that we cannot add type information to existing data stored on networks, we can only add it to new values.
Not much I think. We already copy/box these values, we'd need to look up the type information from the checker's elaboration, which will likely be just a hashmap lookup. |
Issue To Be Solved
Using interfaces we can't check what type is really used at run-time, sometimes it's required to check a specific type. Need to know the full name of a type I'm working with.
(Optional): Suggest A Solution
I know you are working to add a new type
Type
, so maybe you can add something likefun getType(): Type
and also afun toString(): String
to theType
if it doesn't exist now.I'd expect to call it in the following way:
obj.getType().toString()
.The format of a name of a type can be for instance:
T.{account_address}.{contract_name}.{type_name}
The text was updated successfully, but these errors were encountered: