Defaults anywhere in positional-only parameters

Ok, I think we can close this discussion. Using a native extension, I was able to create a wrapper class that calls functions with positional defaults with comparable performance to the undecorated functions. What’s more, since applying the defaults is now a method call, I think I could leverage the vectorcall protocol to apply a single left-default (i.e. the most common use case) with zero overhead.

Besides, the decorator has the added benefit that you can fill defaults in arbitrary order, which the language feature could never deliver.

3 Likes

I can find a reference to **kwargs from May 2000 on the Python mailing list, while PEP 318 Decorators for Functions and Methods was created on 05-Jun-2003. So it seems **kwargs came first. Did I misunderstand what you meant?

I’d be surprised if you didn’t misunderstand, since I wrote wrong things. I meant the def f(*, x): ... syntax for marking x as keyword-only. I suppose it’s been around for a while (maybe the beginning) in Python 3, but we supported Python 2 up through its official end-of-life, so we had to use a decorator until then.

1 Like

Perhaps one way to understand this is to think of it as one function with multiple signatures - something like this:

@multi_sig  # similar to @multipledispatch.dispatch
def range(start, stop, step=1):
    ...

@multi_sig
def range(stop, step=1):
    return range(0, stop, step)

That’s a super-common pattern in strictly-signatured languages, I’ve written (and abused) such things zillions of times in the olden Java days, for example. It doesn’t end up being super flexible, but I think it’s more flexible than the OP’s proposal, and probably a bit more clear about what’s happening?

5 Likes

This is overloading and it works great, but you have thrown the baby out with the bath water: We want to use defaults because we want to keep it to a single signature.

PS: This seems to be more popular. Interesting! I actually have a fast overload implemented for positional-only arguments, so I might add that as well