Python 3.12 just landed this ability, via the special Unpack[T]
type that you can use in argument lists to “unpack” the fields of the type T
into the argument list for people to call directly, in a statically-typed manner:
class Movie(TypedDict):
name: str
year: int
def foo(**kwargs: Unpack[Movie]) -> None: ...
foo(name="The Meaning of Life", year=1983) # OK!
kwargs: Movie = ...
foo(**kwargs)
This makes it much easier to
- (a) define related methods that share some - but not all - of their arguments, without having to have the user manually bundle them up into a config object to pass in
- (b) while still having the arguments & types be statically known
This is a big improvement in Python over **kwargs
which do (a) and not (b), but would also be a big improvement in Scala where you can do (b) but not (a). e.g. this comes up in the com-lihaoyi/requests-scala code, where we have copy-pasted-but-slightly-different argument lists between Requester#apply, Requester#stream, and Request#apply, as well as some overloads where we do unpacking e.g. here
How hard would it be to implement something like this in Scala? I feel like it would greatly improve the ergonomics of defining and managing many of these “direct-style” APIs where you call methods and pass parameters without having to manually construct elaborate trees of nested configuration objects to pass in.