vyper icon indicating copy to clipboard operation
vyper copied to clipboard

VIP: Allow declaring tuple types at the definition site

Open charles-cooper opened this issue 4 years ago • 6 comments

Simple Summary

Something like this should compile:

(a: bool, b: uint256) = True, 1

Motivation

External calls can return tuples. Let's say there is an interface like def foo() -> (bool, uint256): view

Currently the way to use it is

a: bool = False
b: uint256 = 0
a, b = <some contract>.foo()

Everybody understands what is happening but it's not very ergonomic. This would be more ergonomic (and save a couple MSTOREs too):

(a: bool, b: uint256) = <some contract>.foo()

I don't really see any downside to allowing this besides a bit more complexity in the type checker.

Will also make https://github.com/vyperlang/vyper/issues/2400 easier to use, the pattern will be like follows:

(success: bool, ret: Bytes[...]) = raw_call(<some contract>, ..., revert_on_failure=False)

Backwards Compatibility

Backwards compatible

Dependencies

References

Copyright

Copyright and related rights waived via CC0

charles-cooper avatar Oct 07 '21 16:10 charles-cooper

Note that this is currently invalid Python syntax (as of Python 3.8), so a custom parser would be needed.

fubuloubu avatar Oct 07 '21 17:10 fubuloubu

Assuming we had a custom parser, what would the ideal syntax be?

charles-cooper avatar Oct 22 '21 15:10 charles-cooper

I think the mentioned syntax or even just a: bool, b: uint256 =...

fubuloubu avatar Oct 22 '21 18:10 fubuloubu

I think the mentioned syntax or even just a: bool, b: uint256 =...

OK I like this, with the caveat that if PEP484 ever gets updated to allow this (declaring tuple types at the definition site), for syntactic compatibility with python we should throw out our way of doing it in favor of the PEP484 way.

charles-cooper avatar Nov 09 '21 19:11 charles-cooper

we can do this by adding a pre-parser rule which translates to valid python by mangling the identifiers together. for instance,

preparser:
x: int, y: int = 1, 1 => x___y: (int, int) = 1, 1

then later in the analysis we can handle these mangled identifiers, e.g.

ast analysis:
if Name.contains("___")
... handle tuple annotation like for t in Name.split("___")...

h/t to @electriclilies for the idea of handling in the pre parser

charles-cooper avatar Mar 24 '22 02:03 charles-cooper

better solution for mangling! in the python AST, non-name nodes can be the target. see the docs https://docs.python.org/3/library/ast.html#ast.AnnAssign, especially that these examples are syntactically valid: a.b: int, a[1]: int.

charles-cooper avatar Aug 18 '22 17:08 charles-cooper