Skip to content
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

Parametric type aliases #568

Closed
JukkaL opened this issue Jan 31, 2015 · 6 comments
Closed

Parametric type aliases #568

JukkaL opened this issue Jan 31, 2015 · 6 comments

Comments

@JukkaL
Copy link
Collaborator

JukkaL commented Jan 31, 2015

It should be possible to define type aliases that take type parameters by having free type variables in the alias initializer. For example, this should be valid:

from typing import TypeVar, Union

T = TypeVar('T')
OrInt = Union[T, int]  # type alias, T is a free type variable

def f(x: OrInt[str]) -> None: ...  # same as x: Union[str, int]

Another example:

from typing import TypeVar, Dict

T = TypeVar('T')
Namespace = Dict[str, T]

def lookup(ns: Namespace[int], name: str) -> ...: ...

For this to work generally, List[x], Union[...], etc. must be indexable at runtime (this is related to #530 and #556 -- these should be implemented before this issue).

@gvanrossum
Copy link
Member

Hm, in an earlier version of the code I have in typehinting/prototyping I tried this, and I ended up not liking the complexity (of the implementation, and of the semantics). I don't think the PEP prescribes this behavior.

@gvanrossum
Copy link
Member

I now recall where I got in trouble. It seems reasonable to have parameters that are themselves complex, e.g.:

CallbackMap = Mapping[str, Callable[[int], str]]

This cannot be parameterized further. But this can:

CallbackMapT = Mapping[T, Callable[[int], T]]

and then it would seem reasonable to define the following as equivalent as the first definition above:

CallbackMap = CallbackMapT[str]

We could even have something like this:

Foo = Dict[str, Tuple[int, int, Union[T, List[T]]]]

and assume that Bar = Foo[int] is equivalent to:

Bar = Dict[str, Tuple[int, int, Union[int, List[int]]]]

This may all be easy enough for mypy, but supporting this at runtime and figuring out exactly how many parameters Foo has became pretty complex. Plus, if a type has, say, three "free variables", can you index it with fewer than three? And in which order are they then satisfied? What if I have e.g. Dict[Union[T, U], Union[U, T]] ? (The two unions are equivalent as types, yet swapping them would change the meaning of the resulting type object by swapping the parameter order, presumably.)

In the end I think there's not enough use to require all this complexity.

@refi64
Copy link
Contributor

refi64 commented Feb 1, 2015

@gvanrossum This is why C++ makes you specify template argument order separately:

template <typename A, typename B>
using MyType = MyOtherType<int, B, char, A>;

What if an explicit type used for this? For instance, you last example would be written as:

MyType = ParameterizedType[T, U][Dict[Union[T, U], Union[U, T]]]

Also, ParameterizedType could use PEP 472 for defaults (ParameterizedType[T, U=default_value]).

As for runtime issues, ParameterizedType could determine everything when it is instantiated (maybe lambdas could be used).

@JukkaL
Copy link
Collaborator Author

JukkaL commented Feb 6, 2015

Okay, marking this as an enhancement proposal for now. If there isn't enough interest (and PEP 484 does not include anything of the like) then I'll probably close this at some point.

@roganov
Copy link

roganov commented Oct 10, 2016

Looks like a duplicate of #606

@gvanrossum
Copy link
Member

Agreed, closing this one as it's the shorter one (though not by much).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants