On Mon, Oct 25, 2021 at 11:41 PM Jon Kiparsky
I would prefer to build on the fact that arguments already come in two flavors with somewhat different behaviors, and that the ordering of these is determined. Going by this analogy, it would make sense to have late-binding arguments following keyword arguments, set off by some separator, such as a double-pipe:
def my_func(positional_arg, some_kwarg="foo" || late_binding_arg=[]]: # body of func
or
def my_func(positional_arg, some_kwarg="foo" || late_binding_arg=[]): # body of func
Interesting, but what are the consequences at the call site? Bear in mind that default argument values can be applied to any argument, or not applied to any argument, and these have implications on what is optional and what is mandatory: def f(a, b=1, /, d=2, *, e, f=3): print(a, b, "(c)", d, e, f) def g(a, /, c, d=2, *, e, f=3): print(a, "(b)", c, d, e, f) You can't have a positional-only argument with a default, followed by a positional-or-keyword argument without, so I can't show all six options in a single function. But all six options are possible, and they have these implications: * a must be passed positionally, and omitting it will TypeError * b may be passed positionally or omitted * c may be passed positionally or by name, but must be provided * d may be passed either way or not at all * e must be passed by name, and omitting it will TypeError * f may be passed by name, or may be omitted (d is so accommodating - he's a nice friendly fellow, he doesn't judge.) Having a new category of function parameters would make these calls even more complicated. It also overemphasizes, in my opinion, the difference between ways that optional arguments are provided with their values. But I do find this suggestion interesting. ChrisA