Description
I'm trying to make some wraps for different "Tensor" like objects, and give them a unified interface. One typical use case unified shape function for np.ndarray and tf.Tensor, the problem is tf.Tensor's shape property does not return list/tuple object.
import tensorfolow as tf
import numpy as np
from typing import Generic, List, Optional, TypeVar
T = TypeVar('T')
class Tensor(Generic[T]):
def __init__(self, data: T):
self.data = data
@dispatch()
def shape(t: Tensor[np.ndarray]) -> List[int]:
return list(t.data.shape)
@dispatch()
def shape(t: Tensor[tf.Tensor]) -> List[Optional[int]]:
return t.data.shape.as_list()
To make things easier, we may first have an minimal example, can we have the following code work:
@dispatch()
def foo(xs: List[int]):
return [x**2 for x in xs]
@dispatch()
def foo(xs: List[str]):
return [x + '1' for x in xs]
foo([1,2,3]) # [1, 4, 9]
foo(['1', '2']) # ['11', '12']
I've noticed these problems:
- Generic types in typing can not be used in
issubclassorisinstance; - covariant/contravariant/invariant problem, this might be marked by
TypeVar, but how to use it in multidipatch? (Julia seems has good solution for this) TypeVarinformation is not kept after init, there might be no actual difference between different concrete types objects after instantiated, like:
from typing import Generic, TypeVar
T = TypeVar('T')
class D(Generic[T]):
def __init__(self, data: T):
self.data = data
d = D[int](1)
s = D[str]('s')
type(d) is type(s) # True
There might be much more problem than I noticed. A solution I can image is creating a new Generic metaclass, and let it produce truly concrete type when subscribed like Generic[T] (cache maybe needed).
IMO, type system might be not expressive enough in python, it might be ok if we don't use multidispatch. But it becomes somehow inconvenient if we use multidispatch heavily in our program.
I'm have not seriously used/learned type theory yet, this might completely a wrong issue.
So,
- is this a "true" issue, or is this just a misunderstanding/wrong usage of
Genericor multidispatch? - if it is a proper issue, do we have solution/work around for this?
Activity