PEP 718: subscriptable functions

I think mainly for symmetry with classes. Your same arguments also apply for classes where generic classes allow this syntax. It is common code to have

class Foo[T]:
  …

Foo(x) # Usually fine but sometimes the right T for x is ambiguous, so

Foo[int](x)

In the class case there’s one more benefit which is int there is actually available at runtime and can be accessed inside Foo to do some dynamic dispatch style logic. Function case could be similar with a way to access the passed type of given, like

def singledispatch[T](x: T):
  element_type = get_function_typevar() or type(x)
  …

This would allow functions like singledispatch in standard library that currently infer their behavior based on type to be given intended type to use for dispatch.

In practice there are alternate ways to write these patterns today. I commonly use pattern of just passing type as it’s own argument like

def load_data[T](typ: type[T], contents: str) -> T:
  …

load_data(MyFoo, “…”)

So overall I mostly see this to allow same patterns/way of specializing that generic classes offer today while generic functions don’t. But I agree that there are reasonable simple alternate ways to do this (your cast or add a type argument).

Edit: The cast approach also grows more complex when return type is not just T (or another type variable like) but some larger type expression that contains T or was affected by T. In that case you need to manually work out what the type checker would end up with when what you know is just intended T to use. Simple example of that is like,

def load_function[T](contents: str) -> Callable[[T], tuple[int,str]]:
  …

Overload case I think can grow more messy. For all of these default Any fallback/ignore still exists vs work it out. It is easier though if you want type checking to give T directly vs figure out what cast would be.

I think with using paramspecs it’s possible to even come up with an example where cast can’t work as there exist types that type checkers can infer but can’t be written down directly. At same time ambiguous case complex enough that cast doesn’t cover it does seem pretty rare and probably not worth being exact.

4 Likes