On 27 June 2013 02:16, Ethan Furman <ethan@stoneleaf.us> wrote:
On 06/26/2013 04:15 PM, Joshua Landau wrote:
On 26 June 2013 16:24, Ethan Furman <ethan@stoneleaf.us> wrote:
On 06/26/2013 07:46 AM, Joshua Landau wrote:
I feel that:
1) This is nearly unreadable - it does not say what it does in the slightest
And the '*' and '**' in function defintions do?
Yes. The "*" symbol means "unpack" across a very large part of python, and the lone "*" was a simple extension to what it already did. There was no leap; I could've guessed what it did. It does not mean "magically make an object know what its name is and then unpack both of those -- implicitly over all of the following args!".
Until recently the '*' meant 'pack' if it was in a function header, and 'unpack' if it was in a function call, and wasn't usable anywhere else. Now it also means 'unpack' in assignments, as well as 'keywords only after this spot' in function headers.
True; but "unpack" and "pack" are synonymous operations; and as I said the "keywords-only" wasn't a new feature, really. It was just a *restricted* version of its previous usage; packing. It didn't actually add anything but a useful subset of what we already had. I say "pack" and "unpack" are synonymous in the same way I think that these are synonymous uses of "+": a + 5 = 10 # So a = 5 a = 5 + 10 # So a = 15 You do the "same thing" but on different sides of the equation, or function call. The definition you seem to want to add is completely different.
Likewise with '**' (except for the assignments part).
I don't know about you, but the first time I saw * and ** I had no idea what they did and had to learn it.
Yeah, true. *However*, and this is the point I'm trying to make: after I knew what def func(first_arg, *rest_of_args): pass did, I was able to guess (approximately) what: first_arg, *rest_of_args = iterable did. If you cannot, you probably need more trust in the developers. I would *never* have thought that: func(*, arg): pass meant func(arg=arg): pass despite that I sort of get the *very slight* (but not really even that) symmetry (now that you've explained it).
2) It's added syntax - that's a high barrier. I'm not convinced it's worth it yet.
It is a high barrier; but this does add a bit of symmetry to the new '*'-meaning-keyword-only symbol.
I don't think it does - there's no symmetry as they have completely different functions.
Like pack and unpack are completely different? ;)
No, they are symmetrical; like ◀ and ▶ are symmetrical. They are different, but the *same shape*.
I see it as:
function header: '*' means only keywords accepted after this point
function call: '*' okay, here's my keywords ;)
But you don't give keywords, they magically appear. My "gut reaction" would be that: foo(*, blah) causes an error ("only keywords allowed after *"). I know it's pointless thing to do, but it's what it looks like. I would then go and "make up" several things to make it seem non-useless like: foo(*, mapping1, mapping2) == foo(**mapping1, **mapping2) but again it makes no sense. I feel no real symmetry from this. Something like: foo(*=blah, *=foo) would make a lot more sense and actually be symetrical, but I agree it's not as clean (nor am I a fan of it; this was just an example). Please remember that: def foo(*, a) != def foo(*, a=b) despite that both are valid -- you are seeing, I think, a false symmetry. I don't think I've really made my point clear in this last section, but I tried.