Re: [Python-ideas] Positional-only parameters

2018-09-06 Thread Yury Selivanov
On Fri, Sep 7, 2018 at 12:31 AM Anders Hovmöller  wrote:
>
> Yury,
>
> I’m sorry if that came off badly, I was not attempting to be snarky. Text is 
> hard and I know I’m not good in emails but rereading the text below I 
> honestly can’t see why my honest attempt at describing my experience can be 
> considered snarky.
>
> I haven’t sought out to discuss positional only parameters, this is something 
> that has just come up in conversation from time to time over the last few 
> years and this has been the response.
>
> If you would explain how you interpreted my mail in this way I would of 
> course be thankful but I also don’t want to take more of your time.

Sure.  (If you choose to reply to this email please do that off-list.)

IMHO your email lacks substance, uses rather strong words like
"disgust" and "disbelief", and ends with "I don't think that's a good
look for Python :P" phrase that doesn't help you to make any point.
You re-surfaced a pretty old email thread where a number of core
developers explained their position and listed quite a few arguments
for having positional-only arguments.  You, on the other hand, didn't
add a lot to the discussion except your own opinion with no serious
arguments to support it.

Please don't feel discouraged from posting to python-ideas though,
just try to keep a higher signal-to-noise ratio. ;)

Yury
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Positional-only parameters

2018-09-06 Thread Cameron Simpson

On 01Mar2017 21:25, Serhiy Storchaka  wrote:

On 28.02.17 23:17, Victor Stinner wrote:

My question is: would it make sense to implement this feature in
Python directly? If yes, what should be the syntax? Use "/" marker?
Use the @positional() decorator?


I'm strongly +1 for supporting positional-only parameters. The main 
benefit to me is that this allows to declare functions that takes 
arbitrary keyword arguments like Formatter.format() or 
MutableMapping.update(). Now we can't use even the "self" parameter 
and need to use a trick with parsing *args manually. This harms clearness and 
performance.


I was a mild +0.1 on this until I saw this argument; now I am +1 (unless 
there's some horrible unforseen performance penalty).


I've been writing quite a few functions lately where it is reasonable for a 
caller to want to pass arbitrary keyword arguments, but where I also want some 
additional parameters for control purposes. The most recent example was 
database related: functions accepting arbitrary keyword arguments indicating 
column values.


As a specific example, what I _want_ to write includes this method:

 def update(self, where, **column_values):

Now, because "where" happens to be an SQL keyword it is unlikely that there 
will be a column of that name, _if_ the database is human designed by an SQL 
person. I have other examples where picking a "safe" name is harder. I can even 
describe scenarios where "where" is plausible: supposing the the database is 
generated from some input data, perhaps supplied by a CSV file (worse, a CSV 
file that is an export of a human written spreadsheet with a "Where" column 
header).  That isn't really even made up: I've got functions whose purpose is 
to import such spreadsheet exports, making namedtuple subclasses automatically 
from the column headers.


In many of these situations I've had recently positional-only arguments would 
have been very helpful. I even had to bugfix a function recently where a 
positional argument was being trouced by a keyword argument by a caller.


Cheers,
Cameron Simpson 
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Positional-only parameters

2018-09-06 Thread Yury Selivanov
On Thu, Sep 6, 2018 at 10:57 PM Anders Hovmöller  wrote:
[..]
> I don't think that's a good look for Python :P

Anders,

Discussing something privately with "a few people", posting snarky
conclusions, and giving baseless recommendations isn't how we strive
to make decisions in Python.  Please refrain from posting in this
manner to python-ideas and python-dev, as emails written this way are
simply distracting and borderline disturbing.

Thanks,
Yury
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Positional-only parameters

2018-09-06 Thread Anders Hovmöller
I think it makes more sense to remove the concept of positional only 
parameters by slowly fixing the standard library. I've discussed the 
existence of positional only with a few people and their response falls in 
to some basic categories:

- disgust
- disbelief
- bargaining (it's not very common right?! in fact yes it is)

I don't think that's a good look for Python :P
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Keyword only argument on function call

2018-09-06 Thread Anders Hovmöller


> Maybe something like this would be better: 
>
> f(=a, =b, =c) 
>

Haha. Look at my PEP, it's under "rejected alternative syntax", because of 
the super angry replies I got on this very mailing list when I suggested 
this syntax a few years ago :P 

I think that syntax is pretty nice personally, but me and everyone at work 
I've discussed this with think that f(*, a, b, c) syntax is even nicer 
since it mirrors "def f(*, a, b, c)" so nicely. Most replies to my new 
syntax has been along the lines of "seems obvious" and "h" :P
 
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Keyword only argument on function call

2018-09-06 Thread Anders Hovmöller


> For calling, we can use 
> https://docs.python.org/3/library/functions.html#locals 
>
>   >>> lcls = locals() 
>
>   >>> a = 'apple' 
>   >>> b = 'banana' 
>   >>> c = 'cherry' 
>
>   >>> dict((k, lcls[k]) for k in ('a', 'b', 'c')) 
>   {'b': 'banana', 'c': 'cherry', 'a': 'apple'} 
>
> So in his example 
>
>foo(a=a, b=b, c=c, d=3, e=e) 
>
> one could instead write 
>
>   foo(d=3, **helper(locals(), ('a', 'b', 'c', 'e'))) 
>
> or perhaps better 
>
> helper(locals(), 'a', 'b', 'c', 'e')(foo, d=3) 
>
> where the helper() picks out items from the locals(). And in the 
> second form, does the right thing with them. 
>

Sure. This was the argument against f-strings too. 

In any case I'm not trying to solve a problem of how to extract things from 
the local namespace anymore than "foo(a, b)" is. I'm trying to minimize the 
advantage positional arguments have over keyword arguments in brevity. If 
that makes sense?
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Keyword only argument on function call

2018-09-06 Thread Anders Hovmöller


On Thursday, September 6, 2018 at 6:51:12 PM UTC+2, Ethan Furman wrote:
>
> On 09/06/2018 07:05 AM, Anders Hovmöller wrote:
> > On Thursday, September 6, 2018 at 3:11:46 PM UTC+2, Steven D'Aprano 
> wrote:
> >> On Thu, Sep 06, 2018 at 12:15:46PM +0200, Anders Hovmöller wrote:
>
> >>> Wouldn't it be awesome if [...]
> >>
> >> No.
> >
> > Heh. I did expect the first mail to be uncivil :P
>
> Direct disagreement is not uncivil, just direct.  You asked a yes/no 
> question and got a yes/no answer.  
>

It's a rhetorical question in a PR sense, not an actual yes/no question. 
 

> D'Aprano's 
> comments further down are also not uncivil, just explicative (not 
> expletive ;) ) of his position.
>
> As for your proposal, I agree with D'Aprano -- this is a lot machinery to 
> support a use-case that doesn't feel 
> compelling to me, and I do tend to name my variables the same when I can.
>

It's not a lot of machinery. It's super tiny. Look at my implementation.

Generally these arguments against sound like the arguments against 
f-strings to me. I personally think f-strings are the one of the best 
things to happen to python in at least a decade, I don't know if people on 
this list agree?
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Keyword only argument on function call

2018-09-06 Thread Anders Hovmöller

>
>
> For comparison, my reaction did indeed involve awe.  It was full of it, 
> in fact :-p  Sorry, but that syntax looks at best highly misleading -- 
> how many parameters are we passing?  I don't like it at all.
>

(nitpick: we're passing arguments, not parameters)

I don't see how this could be confusing. Do you think it's confusing how 
many parameters a function has in python now because of the keyword only 
marker? This suggestion follows the same rules you should already be 
familiar with when counting parameters, why would you now have trouble 
counting when the line doesn't begin with "def " and end with ":"?
 

> >> I'm in favour of consistent naming when it helps the code, when the
> >> names are clear and relevant.
> > 
> > 
> > Which is what I'm saying.
>
> Actually you are not.  Adding specific syntax support is a strong signal 
> that you expect people to use it and (in this case) use consistent 
> naming.  Full stop.  It's a much stronger statement than you seem to think.
>

I expect this to be common enough to warrant nicer language constructs 
(like OCaml has). I expect people today to use positional arguments to get 
concise code, and I think python pushes people in this direction. This is a 
bad direction imo.
 

> >> I disagree that f(*, page) is more readable than an explicit named
> >> keyword argument f(page=page).
> >>
> > 
> > People prefer f(page) today. For some reason. That might refute your
> > statement or not, depending on why they do it.
>
> Evidence?
>

Run my analysis tool. Check the numbers. It's certainly true at work, and 
it's true for Django for example. 
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Keyword only argument on function call

2018-09-06 Thread Anders Hovmöller


On Thursday, September 6, 2018 at 4:13:45 PM UTC+2, David Mertz wrote:
>
> Steven's point is the same as my impression. It's not terribly uncommon in 
> code I write or read to use the same name for a formal parameter (whether 
> keyword or positional) in the calling scope.  But it's also far from 
> universal.  Almost all the time where it's not the case, it's for a very 
> good reason.
>
> Functions by their nature are *generic* in some sense.  That is, they 
> allow themselves to be called from many other places.  Each of those places 
> has its own semantic context where different names are relevant to readers 
> of the code in that other place.  As a rule, the names used in function 
> parameters are less specific or descriptive because they have to be neutral 
> about that calling context.  So e.g. a toy example:
>
> for record in ledger:
> if record.amount > 0:
> bank_transaction(currency=currencies[record.country],
>  deposit=record.amount,
>  account_number=record.id)
>
> Once in a while the names in the two scopes align, but it would be code 
> obfuscation to *force* them to do so (either by actual requirement or 
> because "it's shorter").
>

Pythons normal arguments already gives people an option to write something 
else "because it's shorter" though: just use positional style. So your 
example is a bit dishonest because it would be:

bank_transaction(currencies[record.country],
 record.amount,
 record.id)

...in many many or even most code bases. 

And I would urge you to try out my analysis tool on some large code base 
you have access to. I do have numbers to back up my claims. I don't have 
numbers on all the places where the names don't align but would be *better* 
if they did align though, because that's a huge manual task, but I think 
it's pretty obvious these places exists.

___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Keyword only argument on function call

2018-09-06 Thread Greg Ewing

Rhodri James wrote:
that syntax looks at best highly misleading -- 
how many parameters are we passing?  I don't like it at all.


Maybe something like this would be better:

   f(=a, =b, =c)

Much more suggestive that you're passing a keyword argument.

As for whether consistent naming is a good idea, seems to
me it's the obvious thing to do when e.g. you're overriding
a method, to keep the signature the same for people who want
to pass arguments by keyword. You'd need to have a pretty
strong reason *not* to keep the parameter names the same.

Given that, it's natural to want a way to avoid repeating
yourself so much when passing them on.

So I think the underlying idea has merit, but the particular
syntax proposed is not the best.

--
Greg
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Keyword only argument on function call

2018-09-06 Thread Brett Cannon
On Thu, 6 Sep 2018 at 09:51 Ethan Furman  wrote:

> On 09/06/2018 07:05 AM, Anders Hovmöller wrote:
> > On Thursday, September 6, 2018 at 3:11:46 PM UTC+2, Steven D'Aprano
> wrote:
> >> On Thu, Sep 06, 2018 at 12:15:46PM +0200, Anders Hovmöller wrote:
>
> >>> Wouldn't it be awesome if [...]
> >>
> >> No.
> >
> > Heh. I did expect the first mail to be uncivil :P
>
> Direct disagreement is not uncivil, just direct.  You asked a yes/no
> question and got a yes/no answer.  D'Aprano's
> comments further down are also not uncivil, just explicative (not
> expletive ;) ) of his position.
>

It also wouldn't have hurt to say "I don't think so" versus the hard "no"
as it means the same thing. You're right that blunt isn't necessarily
uncivil, but bluntness is also interpreted differently in various cultures
so it's something to avoid if possible.

-Brett


>
> As for your proposal, I agree with D'Aprano -- this is a lot machinery to
> support a use-case that doesn't feel
> compelling to me, and I do tend to name my variables the same when I can.
>
> --
> ~Ethan~
> ___
> Python-ideas mailing list
> Python-ideas@python.org
> https://mail.python.org/mailman/listinfo/python-ideas
> Code of Conduct: http://python.org/psf/codeofconduct/
>
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] On evaluating features [was: Unpacking iterables for augmented assignment]

2018-09-06 Thread Franklin? Lee
n Thu, Sep 6, 2018 at 2:47 PM Chris Angelico  wrote:
>
> On Fri, Sep 7, 2018 at 4:38 AM, Franklin? Lee
>  wrote:
> > The following are equivalent and compile down to the same code:
> > a, b, c = lst
> > [a, b, c] = lst
> >
> > The left hand side is not an actual list (even though it looks like
> > one). The brackets are optional. The docs call the left hand side a
> > target list: 
> > https://docs.python.org/3/reference/simple_stmts.html#assignment-statements
> >
> > "Target list" is not a real type. You can't construct such an object,
> > or hold one in memory. You can't make a class that emulates it
> > (without interpreter-specific hacks), because it is a collection of
> > its names, not a collection of values.
>
> A target list is a syntactic element, like a name, or an operator, or
> a "yield" statement. You can't construct one, because it isn't an
> object type. It's not a "virtual type". It's a completely different
> sort of thing.

I didn't think I gave the impression that I was complaining about not
being able to construct it. I gave an explanation for how it isn't a
real type, because you asked how you could modify the behavior, and
because I wanted to give an explanation for more than just you.

There are constructs that correspond to types (such as slices and
functions). There are those that don't. We call `3:2` (in the right
context) a slice, even though it's technically a construct which is
compiled down to a `slice` object. I see no problem there.

I called it a "virtual type" and explained why I called it that. You
reject the use of that term, but you don't even acknowledge that I
gave reasons for it.

> > target_list.__iadd__ also does not exist, because target_list does not
> > exist. However, target_list can be thought of as a virtual type, a
> > type that the compiler compiles away. We can then consider
> > target_list.__iadd__ as a virtual operator, which the compiler will
> > understand but hide from the runtime.
> >
> > I was making the point that, because the __iadd__ in the example does
> > not refer to list.__iadd__, but rather a virtual target_list.__iadd__,
> > there is not yet a violation of the rule.
>
> What you're suggesting is on par with trying to say that:
>
> for += 5
>
> should be implemented as:
>
> current_loop.__iadd__(5)
>
> where "current_loop" doesn't really exist, but it's a virtual type
> that represents a 'for' loop.

I explained how target_list could be thought of as a special imaginary
type which only exists in the compiler's "mind", and then extended
that to an imaginary method on that type. Of course your example shows
absurdity: you didn't try to say how a for-loop is like an object in
the first place.

> That doesn't make sense, because there
> is no object in Python to represent the loop. There is no class/type
> that represents all loops, on which a method like this could be added.
> The word 'for' is part of the grammar, not the object model. And
> "target list" is the same. There's no way to attach an __iadd__ method
> to something that doesn't exist.

But I'm not using the word `for`. I am using constructs like `[a,b,c]`
(where it is not a list). At least use `(for x in y: z) += 5` as your
example. You're effectively accusing me of trying to make `[` (a
single token, not a full construct) an object.

Your argument here is that there is no Python object to represent a
loop, but that really means there's no _runtime_ object to represent a
loop. I already said that target lists don't exist in memory (i.e.
runtime).

"Target list" does exist, just not as a runtime type. It exists as an
abstraction not available to the runtime, and we can extend that
abstraction in ways not available to the runtime. That means that you
can't attach it during the runtime. It does not mean you can't reason
with it during compile-time.

> So for your proposal to work, you would need to break that rule, and
> give a *different* meaning to this.

It is not my proposal. I was questioning how there was a rule
violation about x+=y translating to `x = x.__iadd__(y)`. You're
talking about a different, made-up rule about how syntactical
constructs can't correspond to compile-time imaginary objects or
runtime objects. But there are syntactical constructs that DO
correspond to runtime types (slice, list, class), there are those
which don't but can (let's not get into that), there are those which
can stay compile-time (f-strings, target lists), and there are those
which probably can't be thought of as types at all (import).
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Keyword only argument on function call

2018-09-06 Thread Jonathan Fine
Summary: I addressed the DEFINING problem. My mistake. Some rough
ideas for the CALLING problem.

Anders has kindly pointed out to me, off-list, that I solved the wrong
problem. His problem is CALLING the function fn, not DEFINING fn.
Thank you very much for this, Anders.

For calling, we can use https://docs.python.org/3/library/functions.html#locals

  >>> lcls = locals()

  >>> a = 'apple'
  >>> b = 'banana'
  >>> c = 'cherry'

  >>> dict((k, lcls[k]) for k in ('a', 'b', 'c'))
  {'b': 'banana', 'c': 'cherry', 'a': 'apple'}

So in his example

   foo(a=a, b=b, c=c, d=3, e=e)

one could instead write

  foo(d=3, **helper(locals(), ('a', 'b', 'c', 'e')))

or perhaps better

helper(locals(), 'a', 'b', 'c', 'e')(foo, d=3)

where the helper() picks out items from the locals(). And in the
second form, does the right thing with them.

Finally, one might be able to use

  >>> def fn(*, a, b, c, d, e): f, g, h = 3, 4, 5
  >>> fn.__code__.co_kwonlyargcount
  5
  >>> fn.__code__.co_varnames
  ('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h')
  >>> fn.__code__.co_argcount
 0

to identify the names of all keyword arguments of the function foo(),
and they provide the values in locals() as the defaults. Of course,
this is somewhat magical, and requires strict conformance to
conventions. So might not be a good idea.

The syntax could then be

localmagic(foo, locals())(d=3)

which, for magicians, might be easier. But rightly in my opinion,
Python is reluctant to use magic.

On the other hand, for a strictly controlled Domain Specific Language,
it might, just might, be useful. And this list is for "speculative
language ideas" (see
https://mail.python.org/mailman/listinfo/python-ideas).

-- 
Jonathan
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] On evaluating features [was: Unpacking iterables for augmented assignment]

2018-09-06 Thread Chris Angelico
On Fri, Sep 7, 2018 at 4:38 AM, Franklin? Lee
 wrote:
> The following are equivalent and compile down to the same code:
> a, b, c = lst
> [a, b, c] = lst
>
> The left hand side is not an actual list (even though it looks like
> one). The brackets are optional. The docs call the left hand side a
> target list: 
> https://docs.python.org/3/reference/simple_stmts.html#assignment-statements
>
> "Target list" is not a real type. You can't construct such an object,
> or hold one in memory. You can't make a class that emulates it
> (without interpreter-specific hacks), because it is a collection of
> its names, not a collection of values.

A target list is a syntactic element, like a name, or an operator, or
a "yield" statement. You can't construct one, because it isn't an
object type. It's not a "virtual type". It's a completely different
sort of thing.

> target_list.__iadd__ also does not exist, because target_list does not
> exist. However, target_list can be thought of as a virtual type, a
> type that the compiler compiles away. We can then consider
> target_list.__iadd__ as a virtual operator, which the compiler will
> understand but hide from the runtime.
>
> I was making the point that, because the __iadd__ in the example does
> not refer to list.__iadd__, but rather a virtual target_list.__iadd__,
> there is not yet a violation of the rule.

What you're suggesting is on par with trying to say that:

for += 5

should be implemented as:

current_loop.__iadd__(5)

where "current_loop" doesn't really exist, but it's a virtual type
that represents a 'for' loop. That doesn't make sense, because there
is no object in Python to represent the loop. There is no class/type
that represents all loops, on which a method like this could be added.
The word 'for' is part of the grammar, not the object model. And
"target list" is the same. There's no way to attach an __iadd__ method
to something that doesn't exist.

So for your proposal to work, you would need to break that rule, and
give a *different* meaning to this.

ChrisA
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] On evaluating features [was: Unpacking iterables for augmented assignment]

2018-09-06 Thread Franklin? Lee
On Thu, Sep 6, 2018 at 2:23 PM Chris Angelico  wrote:
>
> On Fri, Sep 7, 2018 at 4:11 AM, Franklin? Lee
>  wrote:
> > On Tue, Aug 28, 2018 at 6:37 PM Greg Ewing  
> > wrote:
> >>
> >> Guido van Rossum wrote:
> >> > we might propose (as the OP did) that this:
> >> >
> >> >   a, b, c += x, y, z
> >> >
> >> > could be made equivalent to this:
> >> >
> >> >   a += x
> >> >   b += y
> >> >   c += z
> >>
> >> But not without violating the principle that
> >>
> >> lhs += rhs
> >>
> >> is equivalent to
> >>
> >> lhs = lhs.__iadd__(lhs)
> >
> > (Corrected: lhs = lhs.__iadd__(rhs))
> >
> > Since lhs here is neither a list nor a tuple, how is it violated? Or
> > rather, how is it any more of a special case than in this syntax:
> >
> > # Neither name-binding or setitem/setattr.
> > [a,b,c] = items
> >
> > If lhs is a Numpy array, then:
> > a_b_c += x, y, z
> > is equivalent to:
> > a_b_c = a_b_c.__iadd__((x,y,z))
> >
> > We can translate the original example:
> > a, b, c += x, y, z
> > to:
> > a, b, c = target_list(a,b,c).__iadd__((x,y,z))
> > where `target_list` is a virtual (not as in "virtual function") type
> > for target list constructs.
>
> What is the virtual type here, and what does its __iadd__ method do? I
> don't understand you here. Can you go into detail? Suppose I'm the
> author of the class that all six of these objects are instances of;
> can I customize the effect of __iadd__ here in some way, and if so,
> how?

I shouldn't have used jargon I had to look up myself.

The following are equivalent and compile down to the same code:
a, b, c = lst
[a, b, c] = lst

The left hand side is not an actual list (even though it looks like
one). The brackets are optional. The docs call the left hand side a
target list: 
https://docs.python.org/3/reference/simple_stmts.html#assignment-statements

"Target list" is not a real type. You can't construct such an object,
or hold one in memory. You can't make a class that emulates it
(without interpreter-specific hacks), because it is a collection of
its names, not a collection of values.

target_list.__iadd__ also does not exist, because target_list does not
exist. However, target_list can be thought of as a virtual type, a
type that the compiler compiles away. We can then consider
target_list.__iadd__ as a virtual operator, which the compiler will
understand but hide from the runtime.

I was making the point that, because the __iadd__ in the example does
not refer to list.__iadd__, but rather a virtual target_list.__iadd__,
there is not yet a violation of the rule.
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] On evaluating features [was: Unpacking iterables for augmented assignment]

2018-09-06 Thread Jonathan Fine
Hi Franklin Lee

Thank you for your message. You wrote:

> We can translate the original example:
> a, b, c += x, y, z
> to:
> a, b, c = target_list(a,b,c).__iadd__((x,y,z))
> where `target_list` is a virtual (not as in "virtual function") type
> for target list constructs.

Yes, we can.I think all are agreed that that such semantics for

  a, b, c += x, y, z

could be provided in a future version of Python.  At present we get

   >>> a, b, c += [4, 5, 6]
  SyntaxError: illegal expression for augmented assignment

Where we're not agreed, I think, is whether doing so would be a good
idea. The proposers think it is a good idea. However, unless the
proposers convince sufficient users that it is a good idea to do so,
it probably won't be added to Python.

By the way, I think it's easier to get users for a pure Python module
(and hence perhaps get it into the standard library) than it is to
make a language syntax and semantics change. And I also like that
things are this way.

-- 
Jonathan
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] On evaluating features [was: Unpacking iterables for augmented assignment]

2018-09-06 Thread Chris Angelico
On Fri, Sep 7, 2018 at 4:11 AM, Franklin? Lee
 wrote:
> On Tue, Aug 28, 2018 at 6:37 PM Greg Ewing  
> wrote:
>>
>> Guido van Rossum wrote:
>> > we might propose (as the OP did) that this:
>> >
>> >   a, b, c += x, y, z
>> >
>> > could be made equivalent to this:
>> >
>> >   a += x
>> >   b += y
>> >   c += z
>>
>> But not without violating the principle that
>>
>> lhs += rhs
>>
>> is equivalent to
>>
>> lhs = lhs.__iadd__(lhs)
>
> (Corrected: lhs = lhs.__iadd__(rhs))
>
> Since lhs here is neither a list nor a tuple, how is it violated? Or
> rather, how is it any more of a special case than in this syntax:
>
> # Neither name-binding or setitem/setattr.
> [a,b,c] = items
>
> If lhs is a Numpy array, then:
> a_b_c += x, y, z
> is equivalent to:
> a_b_c = a_b_c.__iadd__((x,y,z))
>
> We can translate the original example:
> a, b, c += x, y, z
> to:
> a, b, c = target_list(a,b,c).__iadd__((x,y,z))
> where `target_list` is a virtual (not as in "virtual function") type
> for target list constructs.

What is the virtual type here, and what does its __iadd__ method do? I
don't understand you here. Can you go into detail? Suppose I'm the
author of the class that all six of these objects are instances of;
can I customize the effect of __iadd__ here in some way, and if so,
how?

ChrisA
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] On evaluating features [was: Unpacking iterables for augmented assignment]

2018-09-06 Thread Franklin? Lee
On Tue, Aug 28, 2018 at 6:37 PM Greg Ewing  wrote:
>
> Guido van Rossum wrote:
> > we might propose (as the OP did) that this:
> >
> >   a, b, c += x, y, z
> >
> > could be made equivalent to this:
> >
> >   a += x
> >   b += y
> >   c += z
>
> But not without violating the principle that
>
> lhs += rhs
>
> is equivalent to
>
> lhs = lhs.__iadd__(lhs)

(Corrected: lhs = lhs.__iadd__(rhs))

Since lhs here is neither a list nor a tuple, how is it violated? Or
rather, how is it any more of a special case than in this syntax:

# Neither name-binding or setitem/setattr.
[a,b,c] = items

If lhs is a Numpy array, then:
a_b_c += x, y, z
is equivalent to:
a_b_c = a_b_c.__iadd__((x,y,z))

We can translate the original example:
a, b, c += x, y, z
to:
a, b, c = target_list(a,b,c).__iadd__((x,y,z))
where `target_list` is a virtual (not as in "virtual function") type
for target list constructs.
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Keyword only argument on function call

2018-09-06 Thread Jonathan Fine
I missed an important line of code. Here it is:

>>> aaa = 'telltale'

Once you have that, these will work:

  >>> eval('aaa', fn.__globals__)
  'telltale'

  >>> __name__
  '__main__'
  >>> import sys
  >>> getattr(sys.modules[__name__], 'aaa')
 'telltale'

-- 
Jonathan
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Keyword only argument on function call

2018-09-06 Thread Ethan Furman

On 09/06/2018 07:05 AM, Anders Hovmöller wrote:

On Thursday, September 6, 2018 at 3:11:46 PM UTC+2, Steven D'Aprano wrote:

On Thu, Sep 06, 2018 at 12:15:46PM +0200, Anders Hovmöller wrote:



Wouldn't it be awesome if [...]


No.


Heh. I did expect the first mail to be uncivil :P


Direct disagreement is not uncivil, just direct.  You asked a yes/no question and got a yes/no answer.  D'Aprano's 
comments further down are also not uncivil, just explicative (not expletive ;) ) of his position.


As for your proposal, I agree with D'Aprano -- this is a lot machinery to support a use-case that doesn't feel 
compelling to me, and I do tend to name my variables the same when I can.


--
~Ethan~
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Keyword only argument on function call

2018-09-06 Thread Jonathan Fine
Hi Anders

Thank you for your interesting message. I'm sure it's based on a real
need. You wrote:

> I have a working implementation for a new syntax which would make using 
> keyword arguments a lot nicer. Wouldn't it be awesome if instead of:
> foo(a=a, b=b, c=c, d=3, e=e)
> we could just write:
> foo(*, a, b, c, d=3, e)
> and it would mean the exact same thing?

I assume you're talking about defining functions.  Here's something
that already works in Python.

  >>> def fn(*, a, b, c, d, e): return locals()
  >>> fn.__kwdefaults__ = dict(a=1, b=2, c=3, d=4, e=5)
  >>> fn()
  {'d': 4, 'b': 2, 'e': 5, 'c': 3, 'a': 1}

And to pick up something from the namespace

  >>> eval('aaa', fn.__globals__)
  'telltale'

Aside: This is short, simple and unsafe. Here's a safer way

  >>> __name__
  '__main__'
  >>> import sys
  >>> getattr(sys.modules[__name__], 'aaa')
 'telltale'

>From this, it should be easy to construct exactly the dict() that you
want for the kwdefaults.

-- 

Jonathan
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Keyword only argument on function call

2018-09-06 Thread Rhodri James

On 06/09/18 15:05, Anders Hovmöller wrote:



On Thursday, September 6, 2018 at 3:11:46 PM UTC+2, Steven D'Aprano wrote:


On Thu, Sep 06, 2018 at 12:15:46PM +0200, Anders Hovmöller wrote:


I have a working implementation for a new syntax which would make
using keyword arguments a lot nicer. Wouldn't it be awesome if instead
of:

 foo(a=a, b=b, c=c, d=3, e=e)

we could just write:

 foo(*, a, b, c, d=3, e)

and it would mean the exact same thing?


No.



Heh. I did expect the first mail to be uncivil :P


For comparison, my reaction did indeed involve awe.  It was full of it, 
in fact :-p  Sorry, but that syntax looks at best highly misleading -- 
how many parameters are we passing?  I don't like it at all.



I'm in favour of consistent naming when it helps the code, when the
names are clear and relevant.



Which is what I'm saying.


Actually you are not.  Adding specific syntax support is a strong signal 
that you expect people to use it and (in this case) use consistent 
naming.  Full stop.  It's a much stronger statement than you seem to think.



I disagree that f(*, page) is more readable than an explicit named
keyword argument f(page=page).



People prefer f(page) today. For some reason. That might refute your
statement or not, depending on why they do it.


Evidence?

--
Rhodri James *-* Kynesim Ltd
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Keyword only argument on function call

2018-09-06 Thread David Mertz
Steven's point is the same as my impression. It's not terribly uncommon in
code I write or read to use the same name for a formal parameter (whether
keyword or positional) in the calling scope.  But it's also far from
universal.  Almost all the time where it's not the case, it's for a very
good reason.

Functions by their nature are *generic* in some sense.  That is, they allow
themselves to be called from many other places.  Each of those places has
its own semantic context where different names are relevant to readers of
the code in that other place.  As a rule, the names used in function
parameters are less specific or descriptive because they have to be neutral
about that calling context.  So e.g. a toy example:

for record in ledger:
if record.amount > 0:
bank_transaction(currency=currencies[record.country],
 deposit=record.amount,
 account_number=record.id)

Once in a while the names in the two scopes align, but it would be code
obfuscation to *force* them to do so (either by actual requirement or
because "it's shorter").

On Thu, Sep 6, 2018 at 9:11 AM Steven D'Aprano  wrote:

> > I have a working implementation for a new syntax which would make
> > using keyword arguments a lot nicer. Wouldn't it be awesome if instead
> >   foo(a=a, b=b, c=c, d=3, e=e)
> > we could just write:
> >   foo(*, a, b, c, d=3, e)
> You say that as if consistent naming is *in and of itself* a good thing,
> merely because it is consistent.
> I'm in favour of consistent naming when it helps the code, when the
> names are clear and relevant. But why should I feel bad about failing to
> use the same names as the functions I call?


-- 
Keeping medicines from the bloodstreams of the sick; food
from the bellies of the hungry; books from the hands of the
uneducated; technology from the underdeveloped; and putting
advocates of freedom in prisons.  Intellectual property is
to the 21st century what the slave trade was to the 16th.
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Keyword only argument on function call

2018-09-06 Thread Anders Hovmöller


On Thursday, September 6, 2018 at 3:11:46 PM UTC+2, Steven D'Aprano wrote:
>
> On Thu, Sep 06, 2018 at 12:15:46PM +0200, Anders Hovmöller wrote: 
>
> > I have a working implementation for a new syntax which would make 
> > using keyword arguments a lot nicer. Wouldn't it be awesome if instead 
> > of: 
> > 
> > foo(a=a, b=b, c=c, d=3, e=e) 
> > 
> > we could just write: 
> > 
> > foo(*, a, b, c, d=3, e) 
> > 
> > and it would mean the exact same thing? 
>
> No.


Heh. I did expect the first mail to be uncivil :P
 

>  
>

> > This would not just be shorter but would create an incentive for 
> > consistent naming across the code base. 
>
> You say that as if consistent naming is *in and of itself* a good thing, 
> merely because it is consistent. 
>

If it's the same thing yes. Otherwise no.
 

> I'm in favour of consistent naming when it helps the code, when the 
> names are clear and relevant. 


Which is what I'm saying.
 

> But why should I feel bad about failing to 
> use the same names as the functions I call? 


Yea, why would you feel bad? If you should have different names, then do. 
Of course.
 

> If some library author names 
> the parameter to a function "a", why should I be encouraged to use 
> that same name *just for the sake of consistency*? 
>

It would encourage library authors to name their parameters well. It 
wouldn't do anything else.
 

> > So the idea is to generalize the * keyword only marker from function 
> > to also have the same meaning at the call site: everything after * is 
> > a kwarg. With this feature we can now simplify keyword arguments 
> > making them more readable and concise. (This syntax does not conflict 
> > with existing Python code.) 
>
> It's certainly more concise, provided those named variables already 
> exist, but how often does that happen? You say 30% in your code base. 
>

(Caveat: 30% of the cases where my super simple and stupid tool can find.)

It's similar for django btw. 
 

> I disagree that f(*, page) is more readable than an explicit named 
> keyword argument f(page=page). 
>

People prefer f(page) today. For some reason. That might refute your 
statement or not, depending on why they do it.
 

>
> My own feeling is that this feature would encourage what I consider a 
> code-smell: function calls requiring large numbers of arguments. Your 
> argument about being concise makes a certain amount of sense if you are 
> frequently making calls like this: 
>

I don't see how that's relevant (or true, but let's stick with relevant). 
There are actual APIs that have lots of arguments. GUI toolkits are a great 
example. Another great example is to send a context dict to a template 
engine. 

To get benefit from your syntax, I would need to 
> extract out the arguments into temporary variables: 
> which completely cancels out the "conciseness" argument. 
>
> First version, with in-place arguments: 
> 1 statement 
> 2 lines 
> 120 characters including whitespace 
>
> Second version, with temporary variables: 
> 3 statements 
> 3 lines 
> 138 characters including whitespace 
>
>
> However you look at it, it's longer and less concise if you have to 
> create temporary variables to make use of this feature. 


Ok. Sure, but that's a straw man

/ Anders
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Keyword only argument on function call

2018-09-06 Thread Todd
Sorry, nevermind.  I think I misunderstood the idea.

On Thu, Sep 6, 2018 at 9:56 AM Todd  wrote:

> I have encountered situations like this, and generally I just use **kwargs
> for non-critical  and handle the parameter management in the body of the
> function.
>
> This also makes it easier to pass the arguments to another function.  You
> can use a dict comprehension to copy over the keys you want, then unpack
> them as arguments to the next function.
>
> On Thu, Sep 6, 2018 at 6:16 AM Anders Hovmöller 
> wrote:
>
>> I have a working implementation for a new syntax which would make using
>> keyword arguments a lot nicer. Wouldn't it be awesome if instead of:
>>
>> foo(a=a, b=b, c=c, d=3, e=e)
>>
>> we could just write:
>>
>> foo(*, a, b, c, d=3, e)
>>
>> and it would mean the exact same thing? This would not just be shorter
>> but would create an incentive for consistent naming across the code base.
>>
>> So the idea is to generalize the * keyword only marker from function to
>> also have the same meaning at the call site: everything after * is a kwarg.
>> With this feature we can now simplify keyword arguments making them more
>> readable and concise. (This syntax does not conflict with existing Python
>> code.)
>>
>> The full PEP-style suggestion is here:
>> https://gist.github.com/boxed/f72221e7e77370be3e5703087c1ba54d
>>
>> I have also written an analysis tool you can use on your code base to see
>> what kind of impact this suggestion might have. It's available at
>> https://gist.github.com/boxed/610b2ba73066c96e9781aed7c0c0b25c . The
>> results for django and twisted are posted as comments to the gist.
>>
>> We've run this on our two big code bases at work (both around 250kloc
>> excluding comments and blank lines). The results show that ~30% of all
>> arguments would benefit from this syntax.
>>
>> Me and my colleague Johan Lübcke have also written an implementation that
>> is available at: https://github.com/boxed/cpython
>>
>> / Anders Hovmöller
>> ___
>> Python-ideas mailing list
>> Python-ideas@python.org
>> https://mail.python.org/mailman/listinfo/python-ideas
>> Code of Conduct: http://python.org/psf/codeofconduct/
>>
>
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Keyword only argument on function call

2018-09-06 Thread Todd
I have encountered situations like this, and generally I just use **kwargs
for non-critical  and handle the parameter management in the body of the
function.

This also makes it easier to pass the arguments to another function.  You
can use a dict comprehension to copy over the keys you want, then unpack
them as arguments to the next function.

On Thu, Sep 6, 2018 at 6:16 AM Anders Hovmöller  wrote:

> I have a working implementation for a new syntax which would make using
> keyword arguments a lot nicer. Wouldn't it be awesome if instead of:
>
> foo(a=a, b=b, c=c, d=3, e=e)
>
> we could just write:
>
> foo(*, a, b, c, d=3, e)
>
> and it would mean the exact same thing? This would not just be shorter but
> would create an incentive for consistent naming across the code base.
>
> So the idea is to generalize the * keyword only marker from function to
> also have the same meaning at the call site: everything after * is a kwarg.
> With this feature we can now simplify keyword arguments making them more
> readable and concise. (This syntax does not conflict with existing Python
> code.)
>
> The full PEP-style suggestion is here:
> https://gist.github.com/boxed/f72221e7e77370be3e5703087c1ba54d
>
> I have also written an analysis tool you can use on your code base to see
> what kind of impact this suggestion might have. It's available at
> https://gist.github.com/boxed/610b2ba73066c96e9781aed7c0c0b25c . The
> results for django and twisted are posted as comments to the gist.
>
> We've run this on our two big code bases at work (both around 250kloc
> excluding comments and blank lines). The results show that ~30% of all
> arguments would benefit from this syntax.
>
> Me and my colleague Johan Lübcke have also written an implementation that
> is available at: https://github.com/boxed/cpython
>
> / Anders Hovmöller
> ___
> Python-ideas mailing list
> Python-ideas@python.org
> https://mail.python.org/mailman/listinfo/python-ideas
> Code of Conduct: http://python.org/psf/codeofconduct/
>
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Keyword only argument on function call

2018-09-06 Thread Robert Vanden Eynde
I'm trying to see how it can be done with current python.

from somelib import auto

auto(locals(), function, 'a', 'b', 'c', d=5)
auto(locals(), function).call('a', 'b', 'c', d=5)
auto(locals(), function)('a', 'b', 'c', d=5)
auto(locals()).bind(function).call('a', 'b', 'c', d=5)

One of those syntax for a class auto could be chosen but it allows you to
give locals in the call.

However, locals() gives a copy of the variables so it must be given as this
code illustrates :

 def f(x):
  y = x+1
  a = locals()
  g = 4
  print(a)

f(5)  # {'y': 6, 'x': 5}


Le jeu. 6 sept. 2018 à 15:18, Calvin Spealman  a
écrit :

>
>
> On Thu, Sep 6, 2018 at 9:11 AM Steven D'Aprano 
> wrote:
>
>> On Thu, Sep 06, 2018 at 12:15:46PM +0200, Anders Hovmöller wrote:
>>
>> > I have a working implementation for a new syntax which would make
>> > using keyword arguments a lot nicer. Wouldn't it be awesome if instead
>> > of:
>> >
>> >   foo(a=a, b=b, c=c, d=3, e=e)
>> >
>> > we could just write:
>> >
>> >   foo(*, a, b, c, d=3, e)
>> >
>> > and it would mean the exact same thing?
>>
>> No.
>>
>>
>> > This would not just be shorter but would create an incentive for
>> > consistent naming across the code base.
>>
>> You say that as if consistent naming is *in and of itself* a good thing,
>> merely because it is consistent.
>>
>> I'm in favour of consistent naming when it helps the code, when the
>> names are clear and relevant. But why should I feel bad about failing to
>> use the same names as the functions I call? If some library author names
>> the parameter to a function "a", why should I be encouraged to use
>> that same name *just for the sake of consistency*?
>>
>
> I've been asking this same question on the Javascript/ES6 side of my work
> ever since unpacking was introduced there which baked hash-lookup into
> the unpacking at a syntax level.
>
> In that world its impacted this same encouragement of "consistency" between
> local variable names and parameters of called functions and it certainly
> seems
> popular in that ecosystem. The practice still feels weird to me and I'm on
> the fence
> about it.
>
> Although, to be honest, I'm definitely leaning towards the "No, actually,
> it is a
> good thing." I grew up, development-speaking, in the Python world with a
> strong emphasis drilled into me that style constraints make better code and
> maybe this is just an extension of that.
>
> Of course, you might not always want the same name, but it is only
> encouraged
> not required. You can always rename variables.
>
> That said... I'm not actually a fan of the specific suggested syntax:
>
> >  foo(*, a, b, c, d=3, e)
>
> I just wanted to give my two cents on the name consistency issue.
>
>
>
>> > So the idea is to generalize the * keyword only marker from function
>> > to also have the same meaning at the call site: everything after * is
>> > a kwarg. With this feature we can now simplify keyword arguments
>> > making them more readable and concise. (This syntax does not conflict
>> > with existing Python code.)
>>
>> It's certainly more concise, provided those named variables already
>> exist, but how often does that happen? You say 30% in your code base.
>>
>> (By the way, well done for writing an analysis tool! I mean it, I'm not
>> being sarcastic. We should have more of those.)
>>
>> I disagree that f(*, page) is more readable than an explicit named
>> keyword argument f(page=page).
>>
>> My own feeling is that this feature would encourage what I consider a
>> code-smell: function calls requiring large numbers of arguments. Your
>> argument about being concise makes a certain amount of sense if you are
>> frequently making calls like this:
>>
>> # chosing a real function, not a made-up example
>> open(file, mode=mode, buffering=buffering, encoding=encoding,
>>  errors=errors, newline=newline, closefd=closefd, opener=opener)
>>
>> If 30% of your function calls look like that, I consider it a
>> code-smell.
>>
>> The benefit is a lot smaller if your function calls look more like this:
>>
>> open(file, encoding=encoding)
>>
>> and even less here:
>>
>> open(file, 'r', encoding=self.encoding or self.default_encoding,
>>  errors=self.errors or self.default_error_handler)
>>
>> for example. To get benefit from your syntax, I would need to
>> extract out the arguments into temporary variables:
>>
>> encoding = self.encoding or self.default_encoding
>> errors = self.errors or self.default_error_handler
>> open(file, 'r', *, encoding, errors)
>>
>> which completely cancels out the "conciseness" argument.
>>
>> First version, with in-place arguments:
>> 1 statement
>> 2 lines
>> 120 characters including whitespace
>>
>> Second version, with temporary variables:
>> 3 statements
>> 3 lines
>> 138 characters including whitespace
>>
>>
>> However you look at it, it's longer and less concise if you have to
>> create temporary variables to make use of 

Re: [Python-ideas] Keyword only argument on function call

2018-09-06 Thread Calvin Spealman
On Thu, Sep 6, 2018 at 9:11 AM Steven D'Aprano  wrote:

> On Thu, Sep 06, 2018 at 12:15:46PM +0200, Anders Hovmöller wrote:
>
> > I have a working implementation for a new syntax which would make
> > using keyword arguments a lot nicer. Wouldn't it be awesome if instead
> > of:
> >
> >   foo(a=a, b=b, c=c, d=3, e=e)
> >
> > we could just write:
> >
> >   foo(*, a, b, c, d=3, e)
> >
> > and it would mean the exact same thing?
>
> No.
>
>
> > This would not just be shorter but would create an incentive for
> > consistent naming across the code base.
>
> You say that as if consistent naming is *in and of itself* a good thing,
> merely because it is consistent.
>
> I'm in favour of consistent naming when it helps the code, when the
> names are clear and relevant. But why should I feel bad about failing to
> use the same names as the functions I call? If some library author names
> the parameter to a function "a", why should I be encouraged to use
> that same name *just for the sake of consistency*?
>

I've been asking this same question on the Javascript/ES6 side of my work
ever since unpacking was introduced there which baked hash-lookup into
the unpacking at a syntax level.

In that world its impacted this same encouragement of "consistency" between
local variable names and parameters of called functions and it certainly
seems
popular in that ecosystem. The practice still feels weird to me and I'm on
the fence
about it.

Although, to be honest, I'm definitely leaning towards the "No, actually,
it is a
good thing." I grew up, development-speaking, in the Python world with a
strong emphasis drilled into me that style constraints make better code and
maybe this is just an extension of that.

Of course, you might not always want the same name, but it is only
encouraged
not required. You can always rename variables.

That said... I'm not actually a fan of the specific suggested syntax:

>  foo(*, a, b, c, d=3, e)

I just wanted to give my two cents on the name consistency issue.



> > So the idea is to generalize the * keyword only marker from function
> > to also have the same meaning at the call site: everything after * is
> > a kwarg. With this feature we can now simplify keyword arguments
> > making them more readable and concise. (This syntax does not conflict
> > with existing Python code.)
>
> It's certainly more concise, provided those named variables already
> exist, but how often does that happen? You say 30% in your code base.
>
> (By the way, well done for writing an analysis tool! I mean it, I'm not
> being sarcastic. We should have more of those.)
>
> I disagree that f(*, page) is more readable than an explicit named
> keyword argument f(page=page).
>
> My own feeling is that this feature would encourage what I consider a
> code-smell: function calls requiring large numbers of arguments. Your
> argument about being concise makes a certain amount of sense if you are
> frequently making calls like this:
>
> # chosing a real function, not a made-up example
> open(file, mode=mode, buffering=buffering, encoding=encoding,
>  errors=errors, newline=newline, closefd=closefd, opener=opener)
>
> If 30% of your function calls look like that, I consider it a
> code-smell.
>
> The benefit is a lot smaller if your function calls look more like this:
>
> open(file, encoding=encoding)
>
> and even less here:
>
> open(file, 'r', encoding=self.encoding or self.default_encoding,
>  errors=self.errors or self.default_error_handler)
>
> for example. To get benefit from your syntax, I would need to
> extract out the arguments into temporary variables:
>
> encoding = self.encoding or self.default_encoding
> errors = self.errors or self.default_error_handler
> open(file, 'r', *, encoding, errors)
>
> which completely cancels out the "conciseness" argument.
>
> First version, with in-place arguments:
> 1 statement
> 2 lines
> 120 characters including whitespace
>
> Second version, with temporary variables:
> 3 statements
> 3 lines
> 138 characters including whitespace
>
>
> However you look at it, it's longer and less concise if you have to
> create temporary variables to make use of this feature.
>
>
> --
> Steve
> ___
> Python-ideas mailing list
> Python-ideas@python.org
> https://mail.python.org/mailman/listinfo/python-ideas
> Code of Conduct: http://python.org/psf/codeofconduct/
>
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Keyword only argument on function call

2018-09-06 Thread Steven D'Aprano
On Thu, Sep 06, 2018 at 12:15:46PM +0200, Anders Hovmöller wrote:

> I have a working implementation for a new syntax which would make 
> using keyword arguments a lot nicer. Wouldn't it be awesome if instead 
> of:
> 
>   foo(a=a, b=b, c=c, d=3, e=e)
> 
> we could just write:
> 
>   foo(*, a, b, c, d=3, e)
> 
> and it would mean the exact same thing?

No.


> This would not just be shorter but would create an incentive for
> consistent naming across the code base. 

You say that as if consistent naming is *in and of itself* a good thing, 
merely because it is consistent.

I'm in favour of consistent naming when it helps the code, when the 
names are clear and relevant. But why should I feel bad about failing to 
use the same names as the functions I call? If some library author names 
the parameter to a function "a", why should I be encouraged to use 
that same name *just for the sake of consistency*?


> So the idea is to generalize the * keyword only marker from function 
> to also have the same meaning at the call site: everything after * is 
> a kwarg. With this feature we can now simplify keyword arguments 
> making them more readable and concise. (This syntax does not conflict 
> with existing Python code.)

It's certainly more concise, provided those named variables already 
exist, but how often does that happen? You say 30% in your code base.

(By the way, well done for writing an analysis tool! I mean it, I'm not 
being sarcastic. We should have more of those.)

I disagree that f(*, page) is more readable than an explicit named 
keyword argument f(page=page).

My own feeling is that this feature would encourage what I consider a 
code-smell: function calls requiring large numbers of arguments. Your 
argument about being concise makes a certain amount of sense if you are 
frequently making calls like this:

# chosing a real function, not a made-up example
open(file, mode=mode, buffering=buffering, encoding=encoding, 
 errors=errors, newline=newline, closefd=closefd, opener=opener)

If 30% of your function calls look like that, I consider it a 
code-smell.

The benefit is a lot smaller if your function calls look more like this:

open(file, encoding=encoding)

and even less here:

open(file, 'r', encoding=self.encoding or self.default_encoding, 
 errors=self.errors or self.default_error_handler)

for example. To get benefit from your syntax, I would need to 
extract out the arguments into temporary variables:

encoding = self.encoding or self.default_encoding
errors = self.errors or self.default_error_handler
open(file, 'r', *, encoding, errors)

which completely cancels out the "conciseness" argument.

First version, with in-place arguments:
1 statement
2 lines
120 characters including whitespace

Second version, with temporary variables:
3 statements
3 lines
138 characters including whitespace


However you look at it, it's longer and less concise if you have to 
create temporary variables to make use of this feature.


-- 
Steve
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Keyword only argument on function call

2018-09-06 Thread Anders Hovmöller
I have a working implementation for a new syntax which would make using keyword 
arguments a lot nicer. Wouldn't it be awesome if instead of:

foo(a=a, b=b, c=c, d=3, e=e)

we could just write:

foo(*, a, b, c, d=3, e)

and it would mean the exact same thing? This would not just be shorter but 
would create an incentive for consistent naming across the code base. 

So the idea is to generalize the * keyword only marker from function to also 
have the same meaning at the call site: everything after * is a kwarg. With 
this feature we can now simplify keyword arguments making them more readable 
and concise. (This syntax does not conflict with existing Python code.)

The full PEP-style suggestion is here: 
https://gist.github.com/boxed/f72221e7e77370be3e5703087c1ba54d

I have also written an analysis tool you can use on your code base to see what 
kind of impact this suggestion might have. It's available at 
https://gist.github.com/boxed/610b2ba73066c96e9781aed7c0c0b25c . The results 
for django and twisted are posted as comments to the gist. 

We've run this on our two big code bases at work (both around 250kloc excluding 
comments and blank lines). The results show that ~30% of all arguments would 
benefit from this syntax.

Me and my colleague Johan Lübcke have also written an implementation that is 
available at: https://github.com/boxed/cpython 

/ Anders Hovmöller
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/