ABI: ABI Subroutine Improvements
- Dominant language
- Python
- Stars
- 288
- Forks
- 138
- PR merge metrics
- No merged PRs in 30d
Description
## Problem
Usage of ABI subroutines is more verbose than necessary. For example, consider these 2 cases:
```python
Int65 = Tuple2[Bool, Uint64]
@ABIReturnSubroutine
def int65_negate(x: Int65, *, output: Int65):
x0 = Bool()
x1 = Uint64()
z0 = Bool()
z1 = Uint64()
return Seq(
x0.set(x[0]),
x1.set(x[1]),
z0.set(Not(x0.get())),
z1.set(x1.get()),
output.set(z0, z1),
)
# can't just call:
# return output.set(Not(x[0].get()), x[1])
Complex130 = Tuple2[Int65, Int65]
# @ABIReturnSubroutines defined "previously":
# * int65_sub()
# * int65_add()
# * int65_mult()
@ABIReturnSubroutine
def complex130_mult(x: Complex130, y: Complex130, *, output: Complex130):
x0 = make(Int65)
x1 = make(Int65)
y0 = make(Int65)
y1 = make(Int65)
t1 = make(Int65)
t2 = make(Int65)
t3 = make(Int65)
t4 = make(Int65)
z0 = make(Int65)
z1 = make(Int65)
return pt.Seq(
x0.set(x[0]),
x1.set(x[1]),
y0.set(y[0]),
y1.set(y[1]),
t1.set(int65_mult(x0, y0)),
t2.set(int65_mult(x1, y1)),
t3.set(int65_mult(x0, y1)),
t4.set(int65_mult(x1, y0)),
z0.set(int65_sub(t1, t2)),
z1.set(int65_add(t3, t4)),
output.set(z0, z1),
)
# can't just call:
# return output.set(
# int65_sub(int65_mult(x[0], y[0]), int65_mult(x[1], y[1])),
# int65_add(int65_mult(x[0], y[1]), int65_mult(x[1], y[0])),
# )
```
* the first example is illegal for 2 reasons:
1. [**CANNOT set() WITH Expr**] we are attempting `Tuple.set(Expr, ...)` - i.e, attempting to set a tuple with an an element that is neither a `ComputedValue` nor a `BaseType`, but an `Expr`
2. [**CANNOT get() Expr FROM ComputedValue**] we are attempting `TupleElement.get()` - which does not exist
* [**CANNOT chain ABIReturnSubroutine**] the second example is illegal because we are attempting to supply a `ComputedValue` as input to an `ABIReturnSubroutine` and only `Expr | ScratchVar | abi.BaseType` are acceptable.
## Solution
As pointed out above, there are 3 categorical problems here:
1. [**CANNOT set() WITH Expr**]
2. [**CANNOT get() Expr FROM ComputedValue**]
3. [**CANNOT chain ABIReturnSubroutine**]
It appears that (3) is easier than (1) and (2) because it only involves making `ABIReturnSubroutine` accept `ComputedValue` params. However, in solving this problem, it is likely that (2) will need to be solved as well.
## Dependencies
None
## Urgency
Medium - though these additions are not strictly necessary for PyTEAL developers, they can allow more succinctness, and reduce the chance of programming error (generally speaking, less lines of code is correlated with less bugs).
Contributor guide
Assessment
This issue has not been assessed yet.