Syntactic sugar to encourage use of named arguments

I find the arguments being made about **kwargs to be mostly an ongoing distraction in trying to follow this thread. I’m not sure what the references to keyword arg type unpacking and typing PEPs are meant to prove, but they seem to me to be mostly off topic – remember that typing is optional and start your arguments from the runtime.

You seem to be saying that using keyword argument unpacking somehow achieves the same thing as this proposed syntax. Please correct me if that’s inaccurate. It’s not a strong and clearly made point at present. And if that is your claim, it’s just not true: a function which accepts arbitrary keyword arguments has different behaviors at runtime from one which does not.


I will say that opening that Reddit thread (instant regret!) almost makes me want to about face and start supporting this PEP to offset the toxicity a bit.
Let’s not let that influence things disproportionately – any of those redditors could come here to voice well-reasoned objections.

1 Like

That’s right. More people can use keyword arguments when calling functions that have positional-or-keyword parameters. The intention here is that there’s no API change, since both positional and keyword calling conventions are already supported, as is the case with the majority of Python code.

If you care about breakage, you already care about breakage. By having an API with pos-or-kw parameters, you make it possible for the rename of a parameter to break someone’s code. This does not change. Everything about this proposal affects the caller, not the callee.

This is true, but some syntax proposals become useful sooner than others. Let’s say that I, being the weirdo that I am, run Python 3.13 already. (Oh hey, that’s exactly the case, how about that.) In MY scripts, all features of Python 3.13 are available! Great! If I give a script to someone else, I have to think about version compatibility, but otherwise, everything’s free game. On the other hand, features that require libraries to adopt them can’t be used until the library drops support for older Pythons. That can be a lot slower.

That’s why this proposal places (almost) zero requirements on the callee. You can take full advantage of this entirely from the caller’s side. The only requirement on the API you’re calling is that it permit keyword arguments, and that’s pretty easy:

def pos_only(x, y, /): ...
def pos_or_kwd(x, y): ...
def kw_only(*, x, y): ...

Most Python code out there does not have the trailing slash that prevents keyword arguments. So it doesn’t have to change, and everything will work fine if you switch to PEP 736 argument passing - since it is exactly equivalent to what can already be done.

Positional-only arguments were only introduced in Python 3.8, so I wouldn’t be surprised that there’s a fair bit of code which has functions of the form:

def f(a, *, b, c): ...

where the intent was:

def f(a, /, *, b, c): ...

but 3.7 and earlier needed to be supported, so the former was used (I know I have written code like this). Having the ability to migrate to the latter (or from pos_or_kwd to either pos_only or kw_only) whilst supporting older Python versions and older versions of the calling code (by having a decorator/decorators that handles both showing a deprecation warning and accepting the old signature whilst changing the function to the new signature) gets us to the same point (more usage of keyword arguments) with less ecosystem breakage and with more improvements to existing code (as this change allows for backports to be produced, whereas syntax changes do not).

1 Like

I agree with all you have said in this thread, @pf_moore; I do not think any of the proposals result in improved readability, so I guess that leaves me -1 to the whole idea described here. IMO, Python does not need this. I also observe that the “proof-of-concept” add-punning-PR submitted to SciKit was rejected as not being an improvement.

8 Likes

Maybe, but if that’s the case, that change is a breaking change with or without PEP 736. That might be acceptable to you (if you consider the acceptance of kwargs to have been a bug), but it’s no different with or without this proposal (if it’s considered a bug, then people who use kwargs are depending on a bug, regardless of syntax).

But this is nothing whatsoever to do with this proposal. If you want to do that, then go ahead and do it, but it won’t have any impact on this.

1 Like

Here’s a vote for f(a, b, **, kw_a, kw_b); if passing one or more **kwargs, then also directly after those.

3 Likes

Looks like a massive improvement to me.

Compare this to := that cleans up some comprehensions that should be better as functions, and removes a line from regex matches.

This proposed change would be the biggest improvement to the readability of code under my control since f-strings.

In my opinion of course.

1 Like

I read a good part of the thread, but not its entirety, apologies if the two following points have been discussed already.

I have seen someone ask about the impact on IDEs. Restating the question here in case it wasn’t further discussed (it is not mentioned in the current text of the PEP): what happens now when you ctrl-click on name=? Previously you could go to the parameter signature and the variable assignment.

Also, similar question for API documentation tools (I’m maintaining one myself): how should I render
thing = call(pos, keyword=)? Previously, I could link to both the keyword parameter signature and possibly the documentation for the keyword variable (given it is documented). Should I therefore transform the code myself back to keyworkd=keyword (during rendering) to retain these docs features?

I’m not sure how it would be different, but sure, you could transform it back to keyword=keyword. It’s by definition exactly equivalent.

The point is that keyword now refers to two different things, meaning that IDEs and other tools want to link to different places in the project.

The easiest solution is to just continue to do what IDEs are already doing: Fill in the other side of the argument:

image

(although pycharm doesn’t actually allow clicking on that filled in name. But that could easily be added if it’s requested)

This is btw also a decent argument against this feature: it often doesn’t even add that much…

(I am not actually for or against this feature at this point. I was originally strongly against it because it’s ugly, but I got used to it. Now I am just not sure if it’s actually worth the effort, so essentially a -0)

2 Likes

“find-and-replace” consideration mentioned here, but having read the whole thread, I don’t think the mouseover/ctrl+click was mentined prior.

It was mentioned here but not discussed any further.

That is a nuisance, but I have been reluctant to disable it in the IDE. Nor has it occurred often. Adding the same feature for the proposed syntax sugar is yet another nuisance, and this time I am more than willing to disable them both.

That feature is also quite different. It’s a hack to make positional arguments better. But in reality they are bad for other reasons than not being able to see the name of the parameter.

1 Like

I considered the first issue about jump-to-declaration in IDEs here

The upshot is the current behavior (in pycharm) jumps to declaration of the parameter in the function signature if the cursor is in front of the equals sign and it jumps to the last modification of the variable if the cursor is after the equals sign.

This behavior is still well defined after the proposal in this PEP.

2 Likes

Both describe the same behavior.

One possible solution is to make the implicit variable visible when clicking Ctrl and hovering its corresponding parameter, allowing you to click it and go to its declaration (last modification).

But I am not a fan of this because it is not obvious without hovering over the parameter. The hidden variable may be shown over the next parameter, creating a mess (one pixel away, and you go to the next parameter definition).

All of this sounds like: We were better off when things were worse.

How are positional parameters handled? If it’s not an insurmountable problem with those, why would it be a problem with these?

My quoted statement may be ambiguous, but I am talking about clicking the variable name, not the parameter. I am not really interested in the parameter (positional or keyword-based) but the variable.

Thanks so much to everyone for contributing your thoughts so far. Apologies I haven’t had headspace in the last week or so to stay on top of this thread.

I have reviewed all the posts I missed and will create a new thread tomorrow in PEPs, summarising the ongoing conversations and collecting feedback specifically on the PEP.

7 Likes