On Sun, Apr 19, 2020 at 7:06 PM Stephen J. Turnbull <turnbull.stephen.fw@u.tsukuba.ac.jp> wrote:
Alex Hall writes:

 > OK, that's fair. What about `{foo::}`?

I don't like any of them.  People who are going to use the syntax
should choose it, not those of us who won't.

First of all, if this proposal went through, even if you didn't write code using it, you'd still have to read it.

Secondly these discussions are often not just about how we personally would be affected by a proposal, but others too, especially beginners who haven't seen a particular syntax beforehand.

So you don't have to tell us which one is your favourite, but I think it's fair to ask if you have specific objections to a specific syntax, or if one syntax (e.g. `foo::`) resolves the objection you had against another syntax (`::foo`). Of course, if you don't want to spend energy or time explaining, that's understandable too.
 

 > I would personally be quite happy if I could replace:
 >
 > ```
 > class A:
 >     def __init__(self, foo, bar, spam):
 >         self.foo = foo
 >         self.spam = spam
 >         self.bar = bar
 > ```
 >
 > with something like:
 >
 > ```
 > class A:
 >     def __init__(self, foo, bar, spam):
 >         setattrs(self, **, foo, bar, spam)
 > ```
 >
 > Wouldn't you?

No, I doubt I would use that.  It's not so much the repetition of
identifiers alone, it's the combination with the repetition of self:
two dimensional redundancy!

But...this solves exactly that! self went from three appearances to one (not counting the signature). I don't get what you're saying.
 
> Please make a PR showing how you would refactor some of these.

Again, you must be joking.  You need to show that this is useful
enough to be worth a syntax change, which is a high bar.  A dozen
examples in the whole stdlib?  I'm not going to do hours of work
understanding those modules to refactor perfectly good code.

Well, one of your original claims was that code that has these same-names generally could have been written better to avoid it. When we tried to provide counterexamples, you said:

I can't speak for your needs, only guess.  But these
examples of function *calls* don't give me enough information to
decide for myself whether I think there's a need to write them, much
less show you how I would write the program without them.

So now I've given you examples where you can see the context and your response is that it's "perfectly good code" that isn't worth the effort to refactor. Even in your descriptions of what you 'would' do it sounds like you'd pretty much leave them as they are in most cases. Therefore I think it's safe to say that we're often stuck with this pattern, and we have reason to try to make the best of it.
 
In code not intended to be
maintained, I'd likely use positional arguments and just copy the
prototypes (deleting defaults and type annotations).


I'd like to highlight this in relation to my other messages about positional arguments. The current syntax encourages dangerous judgements like "this code probably doesn't need to be maintained, I'll take the easy route".

Also I'm hearing that the redundancy bothers you enough that you'd like to avoid it where you can, even at a cost. That suggests that there is a problem worth fixing.
 
That leaves four various other examples in the whole stdlib, not very
many.  Although I'm sure you'd find more with a lower limit, I doubt
they're as convincing as the ones with many same name arguments.
We'll see what the senior committers have to say, but I think you have
an uphill battle on your hands.

Well, here's some more data. If I take all the dicts and calls with same-names and put the number of same-names into a Counter, here's what I get for various projects:

CPython: Counter({1: 631, 2: 174, 3: 58, 4: 27, 5: 12, 6: 9, 8: 5, 7: 4, 10: 4})
pandas: Counter({1: 2785, 2: 864, 3: 363, 4: 165, 5: 86, 6: 55, 7: 48, 9: 23, 8: 20, 10: 11, 11: 8, 12: 7, 13: 7, 15: 4, 16: 2, 14: 2, 17: 2, 18: 2, 25: 1, 48: 1, 22: 1, 19: 1})
IPython: Counter({1: 1184, 2: 284, 3: 85, 4: 44, 5: 28, 6: 12, 7: 9, 11: 5, 10: 2, 8: 2, 14: 2})
scikit-learn: Counter({1: 817, 2: 188, 3: 81, 4: 30, 5: 27, 7: 15, 6: 14, 10: 10, 8: 10, 11: 7, 13: 5, 9: 5, 14: 4, 15: 4, 12: 3, 23: 3, 17: 3, 19: 3, 22: 1, 16: 1, 21: 1})
Django: Counter({1: 562, 2: 130, 3: 48, 5: 13, 4: 12, 7: 3, 6: 3, 10: 2, 9: 2, 18: 1, 12: 1, 8: 1})
matplotlib: Counter({1: 783, 2: 181, 3: 76, 4: 34, 6: 22, 5: 10, 7: 10, 9: 7, 10: 5, 13: 4, 12: 2, 15: 2, 8: 2, 25: 1, 16: 1, 14: 1, 17: 1})

Regarding the large number of calls with just a few same-names: yes, there is less benefit to changing them to a new syntax, but there's similarly less cost to doing so.