cadence
cadence copied to clipboard
Allow export of function values
Closes #2049
Description
Event though function cannot be serialized, we should still treat them as exportable: values are simply omitted.
This allows the export of composite values that contain function-typed fields. For example, this the NFT metadata standard contains such a definition.
Also, improve the tests by changing the static return type to AnyStruct and asserting the dynamic type checked for exportability.
- [x] Targeted PR against
masterbranch - [x] Linked to Github issue with discussion and accepted design OR link to spec that describes this work
- [x] Code follows the standards mentioned here
- [x] Updated relevant documentation
- [x] Re-reviewed
Files changedin the Github PR explorer - [x] Added appropriate labels
Cadence Benchstat comparison
This branch with compared with the base branch onflow:master commit 77938db03296e2e34fb28fbaf2f94bbbe7b8ef3d
The command for i in {1..N}; do go test ./... -run=XXX -bench=. -benchmem -shuffle=on; done was used.
Bench tests were run a total of 7 times on each branch.
Collapsed results for better readability
| old.txt | new.txt | |||
|---|---|---|---|---|
| time/op | delta | |||
| CheckContractInterfaceFungibleTokenConformance-2 | 119µs ± 2% | 120µs ± 1% | ~ | (p=0.383 n=7+7) |
| ContractInterfaceFungibleToken-2 | 40.9µs ± 1% | 41.1µs ± 1% | ~ | (p=0.535 n=7+7) |
| InterpretRecursionFib-2 | 2.40ms ± 1% | 2.36ms ± 1% | −1.66% | (p=0.001 n=7+6) |
| NewInterpreter/new_interpreter-2 | 1.13µs ± 1% | 1.13µs ± 0% | +0.67% | (p=0.017 n=7+6) |
| NewInterpreter/new_sub-interpreter-2 | 598ns ± 1% | 611ns ± 5% | ~ | (p=0.318 n=7+7) |
| ParseArray-2 | 8.39ms ± 5% | 8.34ms ± 2% | ~ | (p=0.731 n=7+6) |
| ParseDeploy/byte_array-2 | 12.6ms ± 4% | 12.5ms ± 1% | ~ | (p=0.534 n=7+6) |
| ParseDeploy/decode_hex-2 | 1.23ms ± 1% | 1.23ms ± 0% | ~ | (p=0.699 n=6+6) |
| ParseFungibleToken/With_memory_metering-2 | 190µs ± 2% | 193µs ± 4% | ~ | (p=0.073 n=7+7) |
| ParseFungibleToken/Without_memory_metering-2 | 151µs ± 2% | 153µs ± 2% | +1.87% | (p=0.002 n=6+7) |
| ParseInfix-2 | 7.24µs ± 1% | 7.25µs ± 1% | ~ | (p=1.000 n=7+7) |
| QualifiedIdentifierCreation/One_level-2 | 2.35ns ± 0% | 2.35ns ± 0% | ~ | (p=0.717 n=7+6) |
| QualifiedIdentifierCreation/Three_levels-2 | 136ns ± 1% | 138ns ± 0% | +1.65% | (p=0.001 n=6+7) |
| RuntimeFungibleTokenTransfer-2 | 649µs ±25% | 600µs ±29% | ~ | (p=0.902 n=7+7) |
| RuntimeResourceDictionaryValues-2 | 5.27ms ± 3% | 5.29ms ± 3% | ~ | (p=0.805 n=7+7) |
| RuntimeScriptNoop-2 | 20.2µs ±28% | 14.9µs ± 1% | ~ | (p=0.731 n=7+6) |
| ValueIsSubtypeOfSemaType-2 | 94.0ns ± 1% | 95.6ns ± 6% | ~ | (p=0.383 n=7+7) |
| alloc/op | delta | |||
| CheckContractInterfaceFungibleTokenConformance-2 | 50.1kB ± 0% | 50.1kB ± 0% | ~ | (p=1.000 n=7+7) |
| ContractInterfaceFungibleToken-2 | 24.2kB ± 0% | 24.2kB ± 0% | ~ | (all equal) |
| InterpretRecursionFib-2 | 1.00MB ± 0% | 1.00MB ± 0% | ~ | (p=0.385 n=7+6) |
| NewInterpreter/new_interpreter-2 | 752B ± 0% | 752B ± 0% | ~ | (all equal) |
| NewInterpreter/new_sub-interpreter-2 | 200B ± 0% | 200B ± 0% | ~ | (all equal) |
| ParseArray-2 | 2.71MB ± 2% | 2.75MB ± 5% | ~ | (p=0.618 n=7+7) |
| ParseDeploy/byte_array-2 | 4.24MB ± 3% | 4.21MB ± 3% | ~ | (p=0.512 n=7+7) |
| ParseDeploy/decode_hex-2 | 214kB ± 0% | 214kB ± 0% | ~ | (p=0.152 n=7+7) |
| ParseFungibleToken/With_memory_metering-2 | 29.4kB ± 0% | 29.4kB ± 0% | ~ | (p=0.816 n=7+7) |
| ParseFungibleToken/Without_memory_metering-2 | 29.4kB ± 0% | 29.4kB ± 0% | ~ | (p=0.400 n=7+7) |
| ParseInfix-2 | 1.93kB ± 0% | 1.93kB ± 0% | ~ | (p=0.554 n=7+7) |
| QualifiedIdentifierCreation/One_level-2 | 0.00B | 0.00B | ~ | (all equal) |
| QualifiedIdentifierCreation/Three_levels-2 | 64.0B ± 0% | 64.0B ± 0% | ~ | (all equal) |
| RuntimeFungibleTokenTransfer-2 | 103kB ± 1% | 102kB ± 1% | ~ | (p=0.383 n=7+7) |
| RuntimeResourceDictionaryValues-2 | 2.28MB ± 0% | 2.28MB ± 0% | −0.22% | (p=0.007 n=7+7) |
| RuntimeScriptNoop-2 | 8.67kB ± 1% | 8.66kB ± 1% | ~ | (p=1.000 n=7+7) |
| ValueIsSubtypeOfSemaType-2 | 48.0B ± 0% | 48.0B ± 0% | ~ | (all equal) |
| allocs/op | delta | |||
| CheckContractInterfaceFungibleTokenConformance-2 | 900 ± 0% | 900 ± 0% | ~ | (all equal) |
| ContractInterfaceFungibleToken-2 | 434 ± 0% | 434 ± 0% | ~ | (all equal) |
| InterpretRecursionFib-2 | 18.9k ± 0% | 18.9k ± 0% | ~ | (all equal) |
| NewInterpreter/new_interpreter-2 | 13.0 ± 0% | 13.0 ± 0% | ~ | (all equal) |
| NewInterpreter/new_sub-interpreter-2 | 4.00 ± 0% | 4.00 ± 0% | ~ | (all equal) |
| ParseArray-2 | 69.6k ± 0% | 69.6k ± 0% | ~ | (p=0.538 n=6+7) |
| ParseDeploy/byte_array-2 | 104k ± 0% | 104k ± 0% | ~ | (p=1.000 n=7+7) |
| ParseDeploy/decode_hex-2 | 75.0 ± 0% | 75.0 ± 0% | ~ | (all equal) |
| ParseFungibleToken/With_memory_metering-2 | 0.99k ± 0% | 0.99k ± 0% | ~ | (all equal) |
| ParseFungibleToken/Without_memory_metering-2 | 0.99k ± 0% | 0.99k ± 0% | ~ | (all equal) |
| ParseInfix-2 | 60.0 ± 0% | 60.0 ± 0% | ~ | (all equal) |
| QualifiedIdentifierCreation/One_level-2 | 0.00 | 0.00 | ~ | (all equal) |
| QualifiedIdentifierCreation/Three_levels-2 | 2.00 ± 0% | 2.00 ± 0% | ~ | (all equal) |
| RuntimeFungibleTokenTransfer-2 | 2.05k ± 0% | 2.05k ± 0% | ~ | (all equal) |
| RuntimeResourceDictionaryValues-2 | 37.0k ± 0% | 37.0k ± 0% | ~ | (p=1.000 n=7+7) |
| RuntimeScriptNoop-2 | 141 ± 0% | 141 ± 0% | ~ | (all equal) |
| ValueIsSubtypeOfSemaType-2 | 1.00 ± 0% | 1.00 ± 0% | ~ | (all equal) |
Codecov Report
Merging #2052 (baaa95f) into master (77938db) will increase coverage by
0.03%. The diff coverage is72.09%.
@@ Coverage Diff @@
## master #2052 +/- ##
==========================================
+ Coverage 77.71% 77.74% +0.03%
==========================================
Files 304 305 +1
Lines 63543 63572 +29
==========================================
+ Hits 49381 49426 +45
+ Misses 12405 12388 -17
- Partials 1757 1758 +1
| Flag | Coverage Δ | |
|---|---|---|
| unittests | 77.74% <72.09%> (+0.03%) |
:arrow_up: |
Flags with carried forward coverage won't be shown. Click here to find out more.
| Impacted Files | Coverage Δ | |
|---|---|---|
| runtime/common/memorykind_string.go | 40.00% <ø> (ø) |
|
| runtime/common/metering.go | 92.23% <ø> (ø) |
|
| types.go | 90.22% <ø> (ø) |
|
| values.go | 66.10% <43.75%> (-0.42%) |
:arrow_down: |
| runtime/interpreter/function.go | 71.95% <50.00%> (+4.07%) |
:arrow_up: |
| encoding/json/encode.go | 94.52% <83.33%> (+0.03%) |
:arrow_up: |
| runtime/convertValues.go | 80.05% <100.00%> (-0.06%) |
:arrow_down: |
| runtime/format/function.go | 100.00% <100.00%> (ø) |
|
| runtime/sema/type.go | 89.58% <100.00%> (+0.08%) |
:arrow_up: |
| runtime/script_executor.go | 85.61% <0.00%> (-6.17%) |
:arrow_down: |
| ... and 5 more |
Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here.
Just omitting the value seems suspect to me; it gives no information about what was originally present on that field. Can we instead emit some kind of dummy value that indicates that there was a function there originally?
@dsainati1 What do you have in mind? Just an empty "function value"? I guess we could add the static type?
That or some text saying "Function Value Omitted", for example
@dsainati1 Added a cadence.Function value which includes the function's type in acaef39
Nice. We should also update the json spec as well.
@dsainati1 Added documentation in ae1c38c16cb9e8aafe684f032c14b3b3a7367d28