[Python-ideas] Re: zip(x, y, z, strict=True)

2020-05-07 Thread Kirill Balunov
On Thu, May 7, 2020 at 3:07 AM Christopher Barker 
wrote:

> On Wed, May 6, 2020 at 1:42 PM Kirill Balunov 
> wrote:
>
>> I'm totally agree with everything you said here. From my perspective,
>> comparing three main cases:
>> 1. zip(*iters, strict= (False | True))
>> 2. zip(*iters, mode = ('shortest' | 'equal' | 'longest'))
>> 3. zip_equal(*iters)
>>
>
> Thanks for enumerating these. I think that's helpful so I'll flesh it out
> a bit more. I *think* these are the options on the table:
>
> (note, I'm keeping different names for things as the same option, and in
> no particular order)
>
> 1) No change
> zip(*iters)
> itertools.zip_longest(*iters, fillvalue=None)
>
> 2) Add boolean strict flag to zip
> zip(*iters, strict= (False | True))
> itertools.zip_longest(*iters, fillvalue=None)
>
> 3) Add a ternary mode flag to zip
> zip(*iters, mode = ('shortest' | 'equal' | 'longest'), fillvalue=None)
>
> 4) Add a new function to itertools
> zip(*iters)
> itertools.zip_longest(*iters, fillvalue=None)
> itertools.zip_equal(*iters)
>
>
I think there are two more cases which can be added to the list:

0) No change
zip(*iters)
itertools.zip_longest(*iters, fillvalue=None)
+ add a recipe about zip_equal in itertools docs

6) Add functionality through  zip methods (as proposed in a separate
thread, but maybe it is off topic for the current thread).

-gdg
___
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/ZBGIGXWL2PZY6H2JWU6UZOPHVBMUE6HW/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: PEP 618: Add Optional Length-Checking To zip

2020-05-07 Thread Kirill Balunov
On Thu, May 7, 2020 at 10:56 AM Alex Hall  wrote:

> On Thu, May 7, 2020 at 9:48 AM Kirill Balunov 
> wrote:
>
>> Sorry for off topic. Isn't this chain.from_iterable just a historical
>> legacy... now we have PEP 448 and I see no differences* between
>> chain(*iterable) vs chain.from_iterable(iterable). Are there?
>>
>> * chain.from_iterable is a little bit faster for small iterables, but if
>> at that time we had PEP 448, would this small speed benefits be enough to
>> make additional method to chain. I think no.
>>
>> -gdg
>>
>
> `chain(*iterable)` converts iterable into a tuple, concretizing it in
> memory. chain.from_iterable(iterable) is lazy and goes through the elements
> one a time, meaning iterable can be infinite.
>
> I don't think PEP 448 has any bearing on that.
>

Heh, surely, I misunderstood the point of PEP 448, and checked that it was
also possible in Python 2.

"meaning iterable can be infinite"  -  thank you, I missed this part, but
to be honest I don’t remember when I do something useful with
infinite iterables.

-gdg
___
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/EC3XT7CUC5EZ2DGC24DLTKFOGCLJQH5A/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: PEP 618: Add Optional Length-Checking To zip

2020-05-07 Thread Kirill Balunov
Sorry for off topic. Isn't this chain.from_iterable just a historical
legacy... now we have PEP 448 and I see no differences* between
chain(*iterable) vs chain.from_iterable(iterable). Are there?

* chain.from_iterable is a little bit faster for small iterables, but if at
that time we had PEP 448, would this small speed benefits be enough to make
additional method to chain. I think no.

-gdg

On Thu, May 7, 2020 at 3:24 AM David Mertz  wrote:

> The only precedent that jumps out for me is itertools.chain() and
> itertools.chain.from_iterable(). It's quite likely that something I don't
> use much has used the same pattern though.
>
> On Wed, May 6, 2020, 8:17 PM Christopher Barker 
> wrote:
>
>> On Wed, May 6, 2020 at 10:31 AM Alex Hall  wrote:
>> zip.shortest(...)  # same as zip(...)
>> zip.longest(...)
>> zip.checksame(...)
>>
>> I presume that zip() would keep its current behavior, yes?
>>
>> I kind of like this -- is there any precedent for it in the standard
>> library?
>>
>> The PEP seems to reject this saying:
>>
>> The actual zip type is an undocumented implementation detail. Adding
>>> additional methods or constructors is really a much larger change that is
>>> not necessary to achieve the stated goal.
>>
>>
>> well, yes and no -- the first part indicates that we could totally change
>> the type of the zip, as long as it's a collable that returns an iterator.
>>
>> Whether adding additional methods is too large a change -- that's totally
>> a matter of opinion.
>>
>> > Having these alternative 'methods' would be similar to having different
>> functions in itertools,
>> indeed -- same idea, different namepace.
>>
>> -CHB
>>
>> --
>> Christopher Barker, PhD
>>
>> Python Language Consulting
>>   - Teaching
>>   - Scientific Software Development
>>   - Desktop GUI and Web Development
>>   - wxPython, numpy, scipy, Cython
>> ___
>> Python-ideas mailing list -- python-ideas@python.org
>> To unsubscribe send an email to python-ideas-le...@python.org
>> https://mail.python.org/mailman3/lists/python-ideas.python.org/
>> Message archived at
>> https://mail.python.org/archives/list/python-ideas@python.org/message/5EC4BLXEUZWEE2D7PP43WK6BAGEVFRPB/
>> Code of Conduct: http://python.org/psf/codeofconduct/
>>
> ___
> Python-ideas mailing list -- python-ideas@python.org
> To unsubscribe send an email to python-ideas-le...@python.org
> https://mail.python.org/mailman3/lists/python-ideas.python.org/
> Message archived at
> https://mail.python.org/archives/list/python-ideas@python.org/message/3BOXVZKFRF7APL5IRBWXQSQOLQWTMBPW/
> Code of Conduct: http://python.org/psf/codeofconduct/
>
___
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/EUV4TEJWNLVR6V3AJXHXNPFSDG7WTHVK/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: zip(x, y, z, strict=True)

2020-05-06 Thread Kirill Balunov
On Wed, May 6, 2020 at 6:49 PM Christopher Barker 
wrote:

> On Tue, May 5, 2020 at 5:43 PM Steven D'Aprano 
> wrote:
>
>> Christopher's quoting is kinda messed up and I can't be bothered fixing
>> it, sorry, so you'll just have to guess who said what :-)
>>
>
> Ideally, we are evaluating ideas independently of who expressed them, so
> I'll pretend I did that on purpose :-)
>
> First: really people, it's all been said. I think we all (and I DO include
> myself in that) have fallen into the trap that "if folks don't agree with
> me, I must not have explained myself well enough" -- but in this case, we
> actually do disagree. And not really on the facts, just on the relative
> importance.
>
> But since, I apparently did not explain myself well enough in this case:
> > no -- but we could (and I think should) have a ternary flag, so that
>
>> > zip_longest becomes unnecessary. And we'd never get to eight
>> combinations:
>> > you can't have longest and shortest behavior at the same time!
>>
>> A ternary flag of strict = True, False or what?
>>
>
> ...
>
> a flag that takes three possible values: "shortest" | "longest" | "equal"
> (defaulting to shortest of course). Name to be bikeshed later :-)
> (and enum vs string also to be bikeshed later)
>
> This demonstrates why the "constant flag" is so often an antipattern. It
>> doesn't scale past two behaviours. Or you end up with a series of flags:
>>
>> zip(*iterators, strict=False, longest=False, fillvalue=None)
>>
>
> I don't think anyone proposed an API like that -- yes, that would be
> horrid.
>
> There are all sorts of reasons why a ternary flag would not be good, but I
> do think it should be mentioned in the PEP, even if only as a rejected idea.
>
> But I still like it, 'cause the "flag for two behaviors and another
> function for the third" seem sliek the worse of all options.
>
>
I'm totally agree with everything you said here. From my perspective,
comparing three main cases:
1. zip(*iters, strict= (False | True))
2. zip(*iters, mode = ('shortest' | 'equal' | 'longest'))
3. zip_equal(*iters)

The first case looks like pretty bad idea (maybe it is practical). But
every of the provided cases try to solve the same problem, so from
practical point of view they are all the same. So just as you said the
first case is merely "flag for two behaviors and another function for the
third" -  is solid -1 from my side.

I like how the second case looks and feels, but obviously the proposed
signature (solution) will not be enough. To plug in the existing
functionality from zip_longest you will also need to provide fill= kwarg,
like zip(*iters, mode = ('shortest' | 'equal' | 'longest'), fill=None).
This fill kwarg will be ignored for other to cases  'shortest' and 'equal'.
Heh - it is not perfect. I will give +0.1 for the second case.

The third case is rather usual solution for the real problem (just one more
function in stdlib) - so +0.5 for this case from my side.

-gdg
___
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/MW3S3HTQ43WDTNLVA3Z6GBLAOOUEOVZ4/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: zip(x, y, z, strict=True)

2020-04-25 Thread Kirill Balunov
But you also can always make such a switch with functools.partial.

-gdg

On Sat, Apr 25, 2020 at 8:59 PM Chris Angelico  wrote:

> On Sun, Apr 26, 2020 at 3:53 AM Kirill Balunov 
> wrote:
> >
> >
> >
> > On Sat, Apr 25, 2020 at 8:11 PM David Mertz  wrote:
> >>
> >> I have no objection to adding a zip_strict() or zip_exact() to
> itertools. I am used to the current behavior, and am apparently in minority
> in not usually assuming common length iterators. Say +0 on a new function.
> >>
> >> But I'm definitely -1 on adding a mode switch to the built-in. This is
> not the way Python is usually done. zip_longest() is a clear example, but
> so is the recent cut_suffix (or whatever final spelling was chosen). Some
> folks wanted a mode switch on .rstrip(), and that was appropriately
> rejected.
> >>
> >
> > Python uses such an approach (separate functions) because there are real
> flaws in the mode switching approach? Or just historically? As for me the
> mode switching approach in the current situation looks reasonable, because
> the question is how boundary conditions should be treated. I still prefer
> three cases switch like `zip(..., mode=('equal' | 'shortest' |
> 'longest'))`... but also ok with `strict=True` variant.
> >
>
> Separate functions mean you can easily and simply make a per-module
> decision:
>
> from itertools import zip_strict as zip
>
> Tada! Now this module treats zip as strict mode. To do that with a
> mode-switch parameter, you have to put the parameter on every single
> call to zip (and if you forget one, it's not obvious), or create a
> wrapper function.
>
> ChrisA
> ___
> Python-ideas mailing list -- python-ideas@python.org
> To unsubscribe send an email to python-ideas-le...@python.org
> https://mail.python.org/mailman3/lists/python-ideas.python.org/
> Message archived at
> https://mail.python.org/archives/list/python-ideas@python.org/message/A3TBZFJC27BXCFQWAD6DQU5ORWR42G7X/
> Code of Conduct: http://python.org/psf/codeofconduct/
>
___
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/OJTAU2VXCAVEZ7IK6CSDRIBRC4VPWWVA/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: zip(x, y, z, strict=True)

2020-04-25 Thread Kirill Balunov
On Sat, Apr 25, 2020 at 8:11 PM David Mertz  wrote:

> I have no objection to adding a zip_strict() or zip_exact() to itertools.
> I am used to the current behavior, and am apparently in minority in not
> usually assuming common length iterators. Say +0 on a new function.
>
> But I'm definitely -1 on adding a mode switch to the built-in. This is not
> the way Python is usually done. zip_longest() is a clear example, but so is
> the recent cut_suffix (or whatever final spelling was chosen). Some folks
> wanted a mode switch on .rstrip(), and that was appropriately rejected.
>
>
Python uses such an approach (separate functions) because there are real
flaws in the mode switching approach? Or just historically? As for me the
mode switching approach in the current situation looks reasonable, because
the question is how boundary conditions should be treated. I still prefer
three cases switch like `zip(..., mode=('equal' | 'shortest' | 'longest'))`...
but also ok with `strict=True` variant.

Also I don't think that comparison with .rstrip() discussion is fair -  because
in that case, it was proposed to switch two completely different approaches
(to treat as string vs to treat as set of chars) which is too much for just
a switch thorugh argument. While in zip case it is just how boundaries are
treated.


> If zip_strict() is genuinely what you want to do, an import from stdlib is
> not much effort to get it. My belief is that usually people who think they
> want this actually want zip_longest(), but that's up to them.
>
> ___
> Python-ideas mailing list -- python-ideas@python.org
> To unsubscribe send an email to python-ideas-le...@python.org
> https://mail.python.org/mailman3/lists/python-ideas.python.org/
> Message archived at
> https://mail.python.org/archives/list/python-ideas@python.org/message/DZZ7I3PEVYB2LW6Y2ECSQRUUTYEB3D7O/
> Code of Conduct: http://python.org/psf/codeofconduct/
>
___
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/3T3VZESKNUNJZBYXXGIQSXTWZBZ3MX2W/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Argumenting in favor of first()

2019-12-07 Thread Kirill Balunov
сб, 7 дек. 2019 г. в 03:45, Steven D'Aprano :

> This is how I would implement the function in Python:
>
> def first(iterable, default=None):
> return next(iter(iterable), default)
>

A somewhat related discussion was somewhere inside November 2017

thread "How assignment should work with generators?". The main idea was to
extend assignment syntax to something like `first, second, ... = gen` which
should be equivalent to `first, second, ... = next(gen), next(gen)`.
Another idea was (but nobody liked it) to change the behavior of `x, y,
*tail = iter` to not to consume starred part and to make a generator
instead of list. I understand that the topic discussed here is slightly
different, but in my understanding it is all the eggs of one chicken.

I still like the idea of partial assignment syntax `x, y, ... = iter` but as
well as then, I understand that I don’t have enough English knowledge and
time to write a proposal on that topic and especially to follow thread and
to defend an idea :( The main objection was that this all is easy
achievable with `islice` from `itertools`.

Back to the topic - maybe `first` is a good citizen for `itertools` module.
Because this idea (about first ) is discussed constantly every two years.

with kind regards,
-gdg
___
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/D7ALA5XP43IWLMMGYSD43FLUSRA3OTAL/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Allow kwargs in __{get|set|del|}item__

2019-10-07 Thread Kirill Balunov
Are you aware of PEP 472 https://www.python.org/dev/peps/pep-0472 ? Maybe
you have something different in mind, but for me your idea looks pretty the
same. While the PEP 472 is in Rejected, Abandoned section, I do not
remember any serious criticism of this idea. It’s just that the authors of
that proposal lost interest and it did not receive further progress. And in
this regard, over time, it was abandoned.

with kind regards,
-gdg

пт, 4 окт. 2019 г. в 23:01, Caleb Donovick :

> While there is no restriction on passing dicts to getitem.  Doing so tends
> to be a bit ugly.  I have two main use cases in mind for this syntax.
>
> The first  and perhaps the most obvious, is doing relational queries.
> ```
> where_x_1 = db[x=1]
> ```
> is more beautiful than
> ```
> where_x_1 = db[dict(x=1)]
> where_x_1 = db[{'x': 1}]
> # or by abusing slices
> where_x_1 = db['x':1]
> # or in the style of Pandas
> where_x_1 = db[db['x'] == 1]
> ```
>
> Beyond relational queries my own personal use case is a shorthand for
> dataclasses / protocols.
> ```
> foo: ProtoRecord[x=int, y=int] = DataRecord[x=int, y=int](0, 1)
> ```
> where `DataRecord[field0=T0, ..., fieldk=Tk]` generates
> ```
> @dataclass
> class Record:
>   field0: T0
>   ...
>   fieldk: Tk
> ```
> and `ProtoRecord[field0=T0, ..., fieldk=Tk]` generates a similar protocol.
>
> Allowing key value pairs in geitem need not change the interface of
> getitem.   All the key value pairs could be collected as a dict and passed
> to getitem as the index. Similar to how the all the positional arguments
> are gather into a single tuple.
> ```
> class Foo:
>   def __getitem__(self, idx):
>  print(idx)
>
> f = Foo()
> f[x=1, y=2] # {'x': 1, 'y': 2}
> ```
> This would make any legacy code using normal dicts as keys (I don't know
> how prevalent that is) automatically work with  the new syntax.
>
> There doesn't necessarily need to be support for mixing of tuple based
> indexing and keyword indexing. i.e.
> ```
> obj[0, x=1] # SyntaxError
> ```
>
> I don't really know anything about parsers but I think the grammar could
> be extended without issue with the following rule:
> ```
> subscriptlist: ... | kwargsubscript (','  kwargsubscript )* [',']
> kwargsubscript: NAME '=' test
> ```
> if `NAME '=' test` would result in ambiguity similar to argument it could
> be `test '=' test` with a block in ast.c
>
>
>-  Caleb Donovick
> ___
> Python-ideas mailing list -- python-ideas@python.org
> To unsubscribe send an email to python-ideas-le...@python.org
> https://mail.python.org/mailman3/lists/python-ideas.python.org/
> Message archived at
> https://mail.python.org/archives/list/python-ideas@python.org/message/EUGDRTRFIY36K4RM3QRR52CKCI7MIR2M/
> Code of Conduct: http://python.org/psf/codeofconduct/
>
___
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/XPQC6AIX2REI5W6EKCRRI7UEGJWVEOC6/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: [Python-Dev] strip behavior provides inconsistent results with certain strings

2019-07-01 Thread Kirill Balunov
>
> This was quite extensively discussed on python-ideas recently:
>
>
> https://mail.python.org/archives/list/python-ideas@python.org/thread/RJARZSUKCXRJIP42Z2YBBAEN5XA7KEC3/#WIRID57ESUFUAQQQ6ZUY2RK5PKQQYSJ3
>
> (I'm finding it hard to find a good thread view in the new interface --
> but that will get you started)
>
> My memory of that thread is that there was a lot of bike shedding, and
> quite a lot of resistance to adding a couple new methods, which I
> personally never understood (Not why we don't want to add methods
> willy-nilly, but why there was this much resistance to what seems like an
> low-disruption, low maintenance, and helpful addition)
>
> I think it just kind of petered out, rather than being rejected, so if
> someone wants to take up the mantle, that would be great -- and some
> support from a core dev or two would probably help.
>
> -CHB
>
>
>
>
> On Fri, Jun 28, 2019 at 10:44 AM Brett Cannon  wrote:
>
>> Glenn Linderman wrote:
>> > On 6/27/2019 3:09 PM, Brett Cannon wrote:
>> > > My guess is that without Guido to just ask this will
>> > > have to go to a PEP as it changes a built-in.
>> > > How does adding two new methods change a built-in?
>> > > Now if an extra parameter were added to modify lstrip, rstrip, and
>> strip
>> > to make them do something different, yes.
>> > But adding new methods doesn't change anything, unless someone is
>> > checking for their existence.
>>
>> Sure, but the built-ins are so widely used that we don't want to blindly
>> add every method idea that someone comes up with either. We all very much
>> share ownership of the built-ins, so we should all agree to changes to
>> them, and getting agreement means either clear consensus and/or a PEP.
>>
>> -Brett
>>
>> > My preferred color is  pstrip and sstrip (prefix and suffix strip)
>> since
>> > lstrip and rstrip mean left and right.
>> > And maybe there should be a psstrip, that takes two parameters, the
>> > prefix and the suffix to strip.
>> > Such functions would certainly reduce code in a lot of places where I do
>> > if  string.startswith('foo'):
>> >  string = string[ 3: ];
>> > as well as making it more robust, because the string and its length
>> have
>> > to stay synchronized when changes are made.
>>
>
I think this type of discussion better fits here.  Quickly looking through
the aforementioned branch - I want to say that that branch died due to
bike-shedding :)

I'm sure this has already been proposed, but it seems to me that the most
natural would be to expand the functionality of existing `.lstrip`,
`.rstrip` and maybe `.strip` methods. Probably many do not like what
_names_ were given to these methods. But nothing can be done about it, they
are what they are and will not go anywhere.  Adding two more methods with
similar functionality will only confuse.  Moreover since we already have a
precedent with other string methods like `.startswith` and `.endswith`  that
accepts as an argument both a string and a tuple of strings.

On the other hand, this suggests that this functionality makes sense only
for `.lstrip` and `.rstrip` variants. Is such a discrepancy acceptable?

If it is, I will suggest to allow `.lstrip` and `.rstrip` to accept tuple
of strings. The _stripping_ will be carried out in accordance with the
linear probing and only one stripping at a time.

>>> s = 'paparazzi'
>>> s.lstrip(('pa', 'ra'))
'parazzi'

Which also deviates from the existing semantics of strinst.split(strinst). Is
this also permissible?

Perhaps all these discrepancies lead to the idea of having new names for
these methods. But for me personally, all these deviations are an
inevitable price for practicality and, of course, echoes of past decisions.

I would like to have such a functionality and find it usedul. Just today, I
needed to remove the “model_” substring from  beginnings of the set of file
filenames, but this does not work because some of the files have names,
like "model_ma...", "model_me...",  "model_or..." and so on.

with kind regards,
-gdg
___
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/XYFQMFPUV6FR2N5BGYWPBVMZ5BE5PJ6C/
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] More alternate constructors for builtin type

2019-05-06 Thread Kirill Balunov
пн, 6 мая 2019 г. в 19:48, Antoine Pitrou :

> On Mon, 6 May 2019 19:39:39 +0300
> Serge Matveenko  wrote:
> > On Mon, May 6, 2019 at 7:29 PM Guido van Rossum 
> wrote:
> > >
> > > On Mon, May 6, 2019 at 11:14 AM Serhiy Storchaka 
> wrote:
> > >> I do not propose to change the current behavior. I propose to add new
> > >> named constructors. In most cases default constructors can be used,
> but
> > >> in cases when we use type check or different tricks to limit the type
> of
> > >> the argument, we could use named constructors.
> > >>
> > >> Current named constructors:
> > >>
> > >> * dict.fromkeys()
> > >> * int.from_bytes()
> > >> * float.fromhex()
> > >> * bytes.fromhex()
> > >> * bytearray.fromhex()
> > >
> > >
> > > Understood. My point is that we won't be able to remove the original
> behavior, so we'd end up with two ways to do it. :-(
> >
> > With all respect, I disagree. There are ways to evolve Python such as
> > deprecation policies which proven to be effective. There are ways to
> > monitor current features adoption on PyPI to see whether it is safe to
> > remove deprecated things.
>
> The main constructors for built-in types are used so pervasively that
> there is no hope of actually removing such deprecated behavior.
>
>
Especially `bytes` constructor: `bytes(int)`, it is so convenient and
obvious that in the entire Python standard library it is used only in tests
of its own existence:

'cpython-master/Lib/test/test_bytes.py' on line: 1023'

'cpython-master/Lib/test/test_bytes.py' on line: 1234'.


Currently, `bytes` is the most ambiguous resident in Python 3. It
seems that in the final version (which is very different from the
initial idea), it was created to surprise:

1. Those wishing to take it as a string in Python 2
2. Those who wish to perceive it as an array of integers from 0 to 255.
3. And those who want to see `bytes` as something else...


with kind regards,

-gdg
___
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] Sorted lists

2019-04-08 Thread Kirill Balunov
Basically, I like this idea and of course theoretically it has use cases. But
in the proposed form, it feels strongly curtailed. In practice, what does
it mean to be sorted?

[('a', 1),('b', 2),('bb', 4),('aaa', 3)]  # Is this list sorted?
[('a', 1),('aaa', 3),('b', 2),('bb', 4)]  # or this?
[('a', 1),('b', 2),('aaa', 3),('bb', 4)]  # or that?

The right answer is that they are all sorted by some means. So, if you
offer this __is_sorted__ attribute only for a very special case 1d list of
numbers - this makes no sense.  (Just re-read the recent thread, why .join
is the string method and not the *list *method). On the other hand If you
offer *some sort of a general protocol* storing a sort key or some other
useful information, then this is awesome! But is this achievable in
practice?

with kind regards,
-gdg

пн, 8 апр. 2019 г. в 05:38, Steven D'Aprano :

> There are quite a few important algorithms which require lists to be
> sorted. For example, the bisect module, and for statistics median and
> other quantiles.
>
> Sorting a list is potentially expensive: while Timsort is very
> efficient, it is still ultimately an O(N log N) algorithm which limits
> how efficient it can be. Checking whether a list is sorted is O(N).
>
> What if we could check that lists were sorted in constant time?
>
> Proposal: let's give lists a dunder flag, __issorted__, that tracks
> whether the list is definitely sorted or not:
>
> - Empty lists, or lists with a single item, are created with
>   __issorted__ = True; lists with two or more items are created
>   with the flag set to False.
>
> - Appending or inserting items sets the flag to False.
>
> - Deleting or popping items doesn't change the flag.
>
> - Reversing the list doesn't change the flag.
>
> - Sorting it sets the flag to True. (The sort method should NOT
>   assume the list is sorted just because the flag is set.)
>
> Functions that require the list to be sorted can use the flag as a
> quick check:
>
> if not alist.__issorted__:
> alist.sort()
> ...
>
> The flag will be writable, so that functions such as those in
> bisect can mark that they have kept the sorted invariant:
>
>
> bisect.insort(alist, x)
> assert alist.__issorted__
>
>
> Being writable, the flag is advisory, not a guarantee, and "consenting
> adults" applies. People can misuse the flag:
>
> alist = [1, 4, 2, 0, 5]
> alist.__issorted__ = True
>
> but then they have nobody to blame but themselves if they shoot
> themselves in the foot. That's no worse than the situation we have now,
> were you might pass an unsorted list to bisect.
>
> The flag doesn't guarantee that the list is sorted the way you want
> (e.g. biggest to smallest, by some key, etc) only that it has been
> sorted. Its up to the user to ensure they sort it the right way:
>
> # Don't do this and expect it to work!
> alist.sort(key=random.random)
> bisect.insort(alist, 1)
>
>
> If you really want to be sure about the state of the list, you have to
> make a copy and sort it. But that's no different from the situation
> right now. But for those willing to assume "consenting adults", you
> might trust the flag and avoid sorting.
>
> Downsides:
>
> - Every list grows an extra attribute; however, given that lists are
>   already quite big data structures and are often over-allocated, I
>   don't think this will matter much.
>
> - insert(), append(), extend(), __setitem__() will be a tiny bit
>   slower due to the need to set the flag.
>
>
>
> Thoughts?
>
>
>
>
> --
> Steven
> ___
> 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] New explicit methods to trim strings

2019-03-31 Thread Kirill Balunov
Sorry one more time (it is early morning and I should drink a cup of coffee
first before posting here). Of course it should be `tuple(sorted(('al',
'ical'), key=len, reverse=True))`, I hope it was obvious to everyone from
the very beginning.

with kind regards,
-gdg

вс, 31 мар. 2019 г. в 11:53, Kirill Balunov :

>
>
> вс, 31 мар. 2019 г. в 11:45, Kirill Balunov :
>
>>
>>
>> вс, 31 мар. 2019 г. в 11:36, Steven D'Aprano :
>>
>>> There's a slight problem with that: what happens if more than one suffix
>>> matches? E.g. given:
>>>
>>> "musical".lcut(('al', 'ical'))
>>>
>>> should the suffix "al" be removed, leaving "music"? (First match wins.)
>>>
>>> Or should the suffix "ical" be removed, leaving "mus"? (Longest match
>>> wins.)
>>>
>>>
>> I think you should choose  "First match wins", because in this case you
>> can make "Longest match wins" as `"musical".lcut(tuple(sorted(('al,
>> 'ical'`. But if you choose "Longest match wins" there is no chance
>> to achieve "First match wins" behaviour.
>>
>> with kind regards,
>> -gfg
>>
>
> Sorry it should be `.rcut` instead of `.lcut`  in 
> `"musical".*rcut*(tuple(sorted(('al,
> 'ical'` at the first place. I will prefer names `.lstrip` and `.rstrip`
> instead of *cut versions.
>
> with kind regards,
> -gdg
>
___
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] New explicit methods to trim strings

2019-03-31 Thread Kirill Balunov
вс, 31 мар. 2019 г. в 11:45, Kirill Balunov :

>
>
> вс, 31 мар. 2019 г. в 11:36, Steven D'Aprano :
>
>> There's a slight problem with that: what happens if more than one suffix
>> matches? E.g. given:
>>
>> "musical".lcut(('al', 'ical'))
>>
>> should the suffix "al" be removed, leaving "music"? (First match wins.)
>>
>> Or should the suffix "ical" be removed, leaving "mus"? (Longest match
>> wins.)
>>
>>
> I think you should choose  "First match wins", because in this case you
> can make "Longest match wins" as `"musical".lcut(tuple(sorted(('al,
> 'ical'`. But if you choose "Longest match wins" there is no chance to
> achieve "First match wins" behaviour.
>
> with kind regards,
> -gfg
>

Sorry it should be `.rcut` instead of `.lcut`  in
`"musical".*rcut*(tuple(sorted(('al,
'ical'` at the first place. I will prefer names `.lstrip` and `.rstrip`
instead of *cut versions.

with kind regards,
-gdg
___
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] New explicit methods to trim strings

2019-03-31 Thread Kirill Balunov
вс, 31 мар. 2019 г. в 11:36, Steven D'Aprano :

> There's a slight problem with that: what happens if more than one suffix
> matches? E.g. given:
>
> "musical".lcut(('al', 'ical'))
>
> should the suffix "al" be removed, leaving "music"? (First match wins.)
>
> Or should the suffix "ical" be removed, leaving "mus"? (Longest match
> wins.)
>
>
I think you should choose  "First match wins", because in this case you can
make "Longest match wins" as `"musical".lcut(tuple(sorted(('al,
'ical'`. But if you choose "Longest match wins" there is no chance to
achieve "First match wins" behaviour.

with kind regards,
-gfg
___
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] Why operators are useful

2019-03-16 Thread Kirill Balunov
сб, 16 мар. 2019 г. в 16:02, Kirill Balunov :

> Thank you for this very thoughtful message! It reminded me of my first
> experience with the old Fortran code. You probably know that earlier in
> Fortran there were no cryptic shortcuts for writing relational operators:
> instead of `A >= B`, you had to write `A .GE. B`, or as many often wrote
> this without spaces `A.GE.B`. Even after a decent time, I still mentally
> stop and linger on these places. It's amazing that, before your message, I
> never thought about the difference in perception between `>=` and `.GE.`.
> It seems to me that, from the perception point of view, the main difference
> is that `A .GE. B` consists of readable characters and therefore we try
> to read them, while `A >= B` is perceived as a single structure (picture)
> due to unreadable `>=`. And our brain is much more better at pattern
> matching than when reading. The same is true in Python in the difference
> between the operator and method forms: `a >= b` and `a.__ge__(b)`. If we
> draw an analogy for dictionaries between:
>
> a | b   # (my preference) over `a + b`   (1)
>
> and
>
> d = d1.copy()(2)
> d = d.update(d2)
>
>
of course

d = d1.copy()(2)
d.update(d2)

just copy-pasted your example without any thought:)


> The (1) is perceived as a picture, while (2) is perceived as a short
> story. And you have to read it, and spend some extra time, and spend some
> extra energy. English is not my mother tongue, so I'm not sure that my
> words correctly convey the meaning of the analogy.
>
> Offtopic: To be honest, the idea of `+` operator overloading for
> something non numeric still does not fully fit in my numerically oriented
> mind. If I started from the beginning, I would introduce a special dunder
> for concatenation (__concat__) with the corresponding operator, something
> like seq1 .. seq2 or seq1 ~ seq2. But that ship has long sailed.
>
> With kind regards,
> -gdg
>
___
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] Why operators are useful

2019-03-16 Thread Kirill Balunov
Thank you for this very thoughtful message! It reminded me of my first
experience with the old Fortran code. You probably know that earlier in
Fortran there were no cryptic shortcuts for writing relational operators:
instead of `A >= B`, you had to write `A .GE. B`, or as many often wrote
this without spaces `A.GE.B`. Even after a decent time, I still mentally
stop and linger on these places. It's amazing that, before your message, I
never thought about the difference in perception between `>=` and `.GE.`.
It seems to me that, from the perception point of view, the main difference
is that `A .GE. B` consists of readable characters and therefore we try to
read them, while `A >= B` is perceived as a single structure (picture) due
to unreadable `>=`. And our brain is much more better at pattern matching
than when reading. The same is true in Python in the difference between the
operator and method forms: `a >= b` and `a.__ge__(b)`. If we draw an
analogy for dictionaries between:

a | b   # (my preference) over `a + b`   (1)

and

d = d1.copy()(2)
d = d.update(d2)

The (1) is perceived as a picture, while (2) is perceived as a short story.
And you have to read it, and spend some extra time, and spend some extra
energy. English is not my mother tongue, so I'm not sure that my words
correctly convey the meaning of the analogy.

Offtopic: To be honest, the idea of `+` operator overloading for something
non numeric still does not fully fit in my numerically oriented mind. If I
started from the beginning, I would introduce a special dunder for
concatenation (__concat__) with the corresponding operator, something like seq1
.. seq2 or seq1 ~ seq2. But that ship has long sailed.

With kind regards,
-gdg




пт, 15 мар. 2019 г. в 20:52, Guido van Rossum :

> There's been a lot of discussion about an operator to merge two dicts. I
> participated in the beginning but quickly felt overwhelmed by the endless
> repetition, so I muted most of the threads.
>
> But I have been thinking about the reason (some) people like operators,
> and a discussion I had with my mentor Lambert Meertens over 30 years ago
> came to mind.
>
> For mathematicians, operators are essential to how they think. Take a
> simple operation like adding two numbers, and try exploring some of its
> behavior.
>
> add(x, y) == add(y, x)(1)
>
> Equation (1) expresses the law that addition is commutative. It's usually
> written using an operator, which makes it more concise:
>
> x + y == y + x(1a)
>
> That feels like a minor gain.
>
> Now consider the associative law:
>
> add(x, add(y, z)) == add(add(x, y), z)(2)
>
> Equation (2) can be rewritten using operators:
>
> x + (y + z) == (x + y) + z(2a)
>
> This is much less confusing than (2), and leads to the observation that
> the parentheses are redundant, so now we can write
>
> x + y + z(3)
>
> without ambiguity (it doesn't matter whether the + operator binds tighter
> to the left or to the right).
>
> Many other laws are also written more easily using operators.  Here's one
> more example, about the identity element of addition:
>
> add(x, 0) == add(0, x) == x(4)
>
> compare to
>
> x + 0 == 0 + x == x(4a)
>
> The general idea here is that once you've learned this simple notation,
> equations written using them are easier to *manipulate* than equations
> written using functional notation -- it is as if our brains grasp the
> operators using different brain machinery, and this is more efficient.
>
> I think that the fact that formulas written using operators are more
> easily processed *visually* has something to do with it: they engage the
> brain's visual processing machinery, which operates largely subconsciously,
> and tells the conscious part what it sees (e.g. "chair" rather than "pieces
> of wood joined together"). The functional notation must take a different
> path through our brain, which is less subconscious (it's related to reading
> and understanding what you read, which is learned/trained at a much later
> age than visual processing).
>
> The power of visual processing really becomes apparent when you combine
> multiple operators. For example, consider the distributive law:
>
> mul(n, add(x, y)) == add(mul(n, x), mul(n, y))  (5)
>
> That was painful to write, and I believe that at first you won't see the
> pattern (or at least you wouldn't have immediately seen it if I hadn't
> mentioned this was the distributive law).
>
> Compare to:
>
> n * (x + y) == n * x + n * y(5a)
>
> Notice how this also uses relative operator priorities. Often
> mathematicians write this even more compact:
>
> n(x+y) == nx + ny(5b)
>
> but alas, that currently goes beyond the capacities of Python's parser.
>
> Another very powerful aspect of operator notation is that it is convenient
> to apply them to objects of different types. For example, laws (1) through
> (5) also work when n, x, y and z are same-size vectors 

Re: [Python-ideas] Vectorization [was Re: Add list.join() please]

2019-02-04 Thread Kirill Balunov
вс, 3 февр. 2019 г. в 21:23, David Mertz :

>
> I think the principled thing to do here is add the minimal number of
> methods to Vector itself, and have everything else pass through as
> vectorized calls.  Most of that minimal number are "magic method":
> __len__(), __contains__(), __str__(), __repr__(), __iter__(),
> __reversed__().  I might have forgotten a couple.  All of those should not
> be called directly, normally, but act as magic for operators or built-in
> functions.
>
> I think I should then create regular methods of the same name that perform
> the vectorized version.  So we would have:
>
> len(v)   # -> 12
>
> v.len()  # -> 
>
> list(v)  # -> ["Jan", "Feb", "Mar", "Apr", "May", "Jul" ...]
> v.list() # -> 
>
>
>
Hi David! Thank you for taking the time to implement this idea. Sorry, I'm
on a trip now and can't try it. From what I've read in this thread, I think
I mostly agree with your perception how the vector should work: that `len(v)
 # -> 12` and that `.some_method()` call must apply to elements (although
pedants may argue that in this case there is not much difference). The only
moment that I don’t like is `v.len(), v.list() and ...`, for the same
reasons -  in general this will not work. I also don't like the option with
`.apply` - what if `.apply` method is already defined for elements in a
vector?


> I can't implement every single constructor that users might
> conceivably want, of course, but I can do it for the basic types in
> builtins and common standard library.  E.g. I might do:
>
> v.deque() # ->  ... >
>
>
> But I certainly won't manually add:
>
> v.custom_linked_list()  # From my_inhouse_module.py
>
>
> Hmm... maybe even I could look at names of maybe-constructors in the
> current namespace and try them.  That starts to feel too magic.  Falling
> back to this feels better:
>
> map(custom_linked_list, v)  # From my_inhouse_module.py
>
>
>
Actually my thoughts on this. At first I thought that for these purposes it
is possible to use __call__:

len(v)   # -> 12

v(len)   # -> 


But it somehow this idea did not fit in my head. Then I found the next way
and I think I even like it - to reuse the `__getitem__`, when its argument
is a function it means that you apply this function to every element in the
vector.

len(v)   # -> 12

v[len]   # -> 


In this case you can apply any function, even custom_linked_list from
my_inhouse_module.py. From this stream I did not understand what desired
behavior for unary operations like `vector + 1` and  the others. Also what
is the desired behaviour for `vector[1:5]`? Considering the above, I would
like to take this operation on the contrary:

>>> v

>>> v[1:]

>>> v[i[1:]] # some helper class `i`


With kind regards,
-gdg
___
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] Vectorization [was Re: Add list.join() please]

2019-02-02 Thread Kirill Balunov
сб, 2 февр. 2019 г. в 07:33, Steven D'Aprano :

>
> I didn't say anything about a vector type.
>
>
I agree  you did not say. But since you started a new thread from the one
where the vector type was a little discussed, it seemed to me  that it is
appropriate to mention it here. Sorry about that.


> > Therefore, it allows you to ensure that the method is present for each
> > element in the vector. The first given example is what numpy is all about
> > and without some guarantee that L consists of homogeneous data it hardly
> > make sense.
>
> Of course it makes sense. Even numpy supports inhomogeneous data:
>
> py> a = np.array([1, 'spam'])
> py> a
> array(['1', 'spam'],
>   dtype='|S4')
>
>
Yes, numpy, at some degree, supports heterogeneous arrays. But not in the
way you brought it. Your example just shows homogeneous array of type
`'|S4'`. In the same way as `np.array([1, 1.234])` will be homogeneous. Of
course you can say -  np.array([1, 'spam'], dtype='object'), but in this
case it will also be homogeneous array, but of type `object`.


> Inhomogeneous data may rule out some optimizations, but that hardly
> means that it "doesn't make sense" to use it.
>

I did not say that it  "doesn't make sense". I only said that you should be
lucky to call `..method()` on collections of heterogeneous data. And
therefore, usually this kind of operations imply that you are working with
a "homogeneous data". Unfortunately, built-in containers cannot provide
such a guarantee without self-checking. Therefore, in my opinion that at
the moment such an operator is not needed.

With kind regards,
-gdg
___
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] Vectorization [was Re: Add list.join() please]

2019-02-01 Thread Kirill Balunov
пт, 1 февр. 2019 г. в 02:24, Steven D'Aprano :

> On Thu, Jan 31, 2019 at 09:51:20AM -0800, Chris Barker via Python-ideas
> wrote:
>
> > I do a lot of numerical programming, and used to use MATLAB and now
> numpy a
> > lot. So I am very used to "vectorization" -- i.e. having operations that
> > work on a whole collection of items at once.
> [...]
> > You can imagine that for more complex expressions the "vectorized"
> approach
> > can make for much clearer and easier to parse code. Also much faster,
> which
> > is what is usually talked about, but I think the readability is the
> bigger
> > deal.
>
> Julia has special "dot" vectorize operator that looks like this:
>
>  L .+ 1   # adds 1 to each item in L
>
>  func.(L)   # calls f on each item in L
>
> https://julialang.org/blog/2017/01/moredots
>
> The beauty of this is that you can apply it to any function or operator
> and the compiler will automatically vectorize it. The function doesn't
> have to be written to specifically support vectorization.
>
>
IMO, the beauty of vector type is that it contains homogeneous data.
Therefore, it allows you to ensure that the method is present for each
element in the vector. The first given example is what numpy is all about
and without some guarantee that L consists of homogeneous data it hardly
make sense. The second one is just `map`. So I can't catch what you are
proposing:

1. To make an operator form of `map`.
2. To pull numpy into stdlib.
3. Or something else, which is not obvious to me from the examples given.

With kind regards,
-gdg


>
> > So what does this have to do with the topic at hand?
> >
> > I know that when I'm used to working with numpy and then need to do some
> > string processing or some such, I find myself missing this
> "vectorization"
> > -- if I want to do the same operation on a whole bunch of strings, why
> do I
> > need to write a loop or comprehension or map? that is:
> >
> > [s.lower() for s in a_list_of_strings]
> >
> > rather than:
> >
> > a_list_of_strings.lower()
>
> Using Julia syntax, that might become a_list_of_strings..lower(). If you
> don't like the double dot, perhaps str.lower.(a_list_of_strings) would
> be less ugly.
>
>
>
> --
> Steven
> ___
> 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] Add .= as a method return value assignment operator

2018-09-27 Thread Kirill Balunov
As I see it, you are mixing very different things. Augmented operators in
Python work on objects, generally trying to mutate them in-place. So
usually after these operations you have the same object (with the same
type, with the same name and etc.) as before these operations. Of course
there are exceptions, for example all immutable types or some promotions
between numbers.

In your examples some cases imply that you are working on names, others
that you are working on objects. And as for me this ambiguity is not
solvable.

With kind regards,
-gdg

ср, 26 сент. 2018 г. в 14:14, Jasper Rebane :

> Hi,
>
> When using Python, I find myself often using assignment operators, like 'a
> += 1' instead of 'a = a + 1', which saves me a lot of time and hassle
>
> Unfortunately, this doesn't apply to methods, thus we have to write code
> like this:
> text = "foo"
> text = text.replace("foo","bar")
> # "bar"
>
> I propose that we should add '.=' as a method return value assignment
> operator so we could write the code like this instead:
> text = "foo"
> text .= replace("foo","bar")
> # "bar"
> This looks cleaner, saves time and makes debugging easier
>
> Here are a few more examples:
> text = " foo "
> text .= strip()
> # "foo"
>
> text = "foo bar"
> text .= split(" ")
> # ['foo', 'bar']
>
> text = b'foo'
> text .= decode("UTF-8")
> # "foo"
>
> foo =  {1,2,3}
> bar = {2,3,4}
> foo .= difference(bar)
> # {1}
>
>
> Rebane
> ___
> 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] "while:" for the loop

2018-09-26 Thread Kirill Balunov
On Wed, Sep 26, 2018, 19:30 David Mertz  wrote:

> We also have:
>
> from itertools import count
> for i in count():
> ...
>
> If you want to keep track of how close to infinity you are. :-)
>

We also have:

from itertools import repeat
for i in repeat(...):
...

with kind regards,
-gdg
___
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] Unpacking iterables for augmented assignment

2018-08-26 Thread Kirill Balunov
вс, 26 авг. 2018 г. в 14:53, Stephen J. Turnbull <
turnbull.stephen...@u.tsukuba.ac.jp>:

> [...]
>
> This isn't consistent with the normal behavior of Python sequences:
>
> $ python3.6
> >>> (1,2) + (3,4)
> (1, 2, 3, 4)
>
> That is, "+" means something different for sequences.  Furthermore,
> the thing on the LHS is tuple syntax.  There's only one reasonable
> meaning to give to an ordinary assignment from a sequence on the RHS
> to a "tuple of variables".
>

What do you mean by "consistent with the normal behavior of Python
sequences"? Personally, I do not see any consistency. Currently, in Python
3.7:

>>> a = [ 1, 2, 3]
>>> b = ( 1, 2, 3)

>>> a + b
...
TypeError: can only concatenate list (not "tuple") to list


But:

>>> a += b
[1, 2, 3, 1, 2, 3]

As for me, Python has several historical artifacts (warts) which can not be
fixed by now. I'm sure that someone, on the contrary, finds them as
advantages (and I'm not interested that someone started to convince me in
the opposite). Among them are: reversed order of arguments in
`enumerate`, the absence of literals for `set` and `frozenset` types, all
`bytes` story in Python 3, `+` operator overload for sequences and others.

But for this particular case, `+` operator overload for concatenation, I
think Python can do better and have the opportunity. Especially, taking
into account the switch to generators for builtins in Python 3 and that in
30-40% times, rough estimation, `+` operator for sequences is used
for throw away concatenation with unnecessary usage of resources in some
cases. I like the way this problem was addressed and solved in Coconut
language  with `::` operator. Coconut uses the `
::` operator for iterator chaining. Since Coconut is just a transpiler, it
is the best they can do. I don't think that just wrapping sequences and
iterators with chain is the right solution for Python and also it is not
enough to introduce new operator into the language. I would like to see it
in a generalized form, for example with the possibility to access items
with slices and indices,.. .I understand that this is not so easy, but at
least I think that this is the right direction for several reasons: it give
a possibility for future pattern matching syntax/functionality in Python,
it can be done lazily and,  in my opinion, `+` operator overload for
builtin sequence types is a historical design mistake.

with kind regards,
-gdg
___
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] Jump to function as an an alternative to call function

2018-08-21 Thread Kirill Balunov
пн, 20 авг. 2018 г. в 17:23, Steven D'Aprano :

> On Sun, Aug 19, 2018 at 06:18:56PM +0300, Kirill Balunov wrote:
> [...]
> [Kirill]
> > Let me disagree with you. While CPython is only one of the
> implementations
> > of the Python language, it is the most common one and defacto is
> considered
> > as a standard.
>
> Not in this case. If CPython intended this to be the language behaviour,
> it should specify that limitation instead of merely giving a doc warning
> that changes "may not" affect the local variables.
>
> In fact, the warning in the docs is too strong. Modifying locals()
> inside a class or module scope is allowed, and works fine. It is only
> functions which is problematic.
>
>
I think I was pretty clear, that I only spoke about `locals` behavior
inside functions and all its derivatives. At least I tried :) Talking about
class and module, as for me, modifying `locals()`
inside a class or module scope is allowed but is far from the right way to
do.

The phrase `may not affect` is the worst phrase for deterministic system.
Your program may work or may not work correctly depending on the underlying
Python implementation, but you would not know about this because there will
be no error and no warning. Good luck fixing such bugs.


>
> > Therefore, all the others, to be compliant, try to replicate
> > all subtleties and features of the basic implementation - CPython.
>
> Implementations are expected to obey the documented behaviour (unless
> given special dispensation to break the rules, which I think has
> happened once or twice with MicroPython). For behaviour which isn't
> dpcumented, it is true that implementations *often* try to copy CPython,
> but that's not mandatory and there are exceptions.
>
>
I think you are talking about recent discussion of MicroPython's `dict`
implementation (that the order is not guaranteed?) It is a necessary trade
off for them given their niche (if I understand correctly the explanation
given by Paul Sokolovsky).


> [...]
>
> Users of CPython frequently rely on CPython implementation details. Why
> do you think Jython and IronPython users will be different?
>
>
Hmm, what do you mean? It seems to me that everything happens the other way
round. For example, recent attempts of numpy to make numpy more PyPy
friendly. In fact, I do not know anyone who specifically rely on CPython
implementation details in their production code.

with kind regards,
-gdg
___
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] Jump to function as an an alternative to call function

2018-08-19 Thread Kirill Balunov
вс, 19 авг. 2018 г. в 17:51, Chris Angelico :

> On Mon, Aug 20, 2018 at 12:43 AM, Kirill Balunov
>  wrote:
> >
> [...]
> > I have the same feeling and already have asked the same question before
> > https://mail.python.org/pipermail/python-list/2018-February/731241.html.
> The
> > main take away was that it is the CPython implementation detail and that
> > `MappingProxy` type was introduced only in 3.3. I still do not find these
> > arguments convincing. On the other hand with the current status quo -
> > `locals` returns `dict` inside a function, we have only advantages:
> >
> > a) `locals` always returns a dict and is consistent in all places. (To be
> > consistent is always good.)
> >
> > b) This type of question occurs every 6 months (there is always a topic
> to
> > talk about at ML).
> >
> > c) When someone encounters this behavior first time, he thinks that he
> found
> > a bug <- There was no error but nothing happened (gives an opportunity to
> > study the internal details of the CPython implementation, the average
> level
> > increases. Everyone also tries to find a way, something like "I believe,
> > there must be a way, because Python is so dynamic" which theoretically
> > allows you to make even more new discoveries.).
> >
> > d) This is considered by some as a way not to leak the CPython
> > implementation details. (Here I have no comments, let it be on the
> > conscience of others.)
> >
> > e) It leaves a room for a future changes (In fact, in some situations I
> > would like to have this possibility).
>
> Related to (e) is that there is room for other implementations to
> permit changes to locals(), and furthermore, a fully-compliant Python
> implementation may use an actual dictionary for locals, and simply
> return that. (That CPython doesn't is an implementation detail for the
> sake of performance.) Requiring that it be a proxy would impose
> unnecessary cost on the implementation, without benefiting any
> compliant use.
>
> 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/


Let me disagree with you. While CPython is only one of the implementations
of the Python language, it is the most common one and defacto is considered
as a standard. Therefore, all the others, to be compliant, try to replicate
all subtleties and features of the basic implementation - CPython. And even
more so, I do not believe that anyone will rely or use such a feature.

I'm not saying that this change should be a part of the Python language
specification. I just said that this is already implied by the
implementation of CPython3 and if you make it more clear with
`MappingProxy` type it will be a net win in my eyes.

With kind regards,
-gdg
___
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] Jump to function as an an alternative to call function

2018-08-19 Thread Kirill Balunov
чт, 16 авг. 2018 г. в 22:37, Chris Barker via Python-ideas <
python-ideas@python.org>:

>
> I wonder why locals doesn't return a Mapping Proxy, or other read-only
> mapping object?
>
> If it's not guaranteed to be THE locals dict, and changes *may* not affect
> the real one (but may), a read-only object seems like much safer idea.
>
> -CHB
>
>
I have the same feeling and already have asked the same question before
https://mail.python.org/pipermail/python-list/2018-February/731241.html.
The main take away was that it is the CPython implementation detail and
that `MappingProxy` type was introduced only in 3.3. I still do not find
these arguments convincing. On the other hand with the current status quo -
`locals` returns `dict` inside a function, we have only advantages:

a) `locals` always returns a dict and is consistent in all places. (To be
consistent is always good.)

b) This type of question occurs every 6 months (there is always a topic to
talk about at ML).

c) When someone encounters this behavior first time, he thinks that he
found a bug <- There was no error but nothing happened (gives an
opportunity to study the internal details of the CPython implementation,
the average level increases. Everyone also tries to find a way, something
like "I believe, there must be a way, because Python is so dynamic" which
theoretically allows you to make even more new discoveries.).

d) This is considered by some as a way not to leak the CPython
implementation details. (Here I have no comments, let it be on the
conscience of others.)

e) It leaves a room for a future changes (In fact, in some situations I
would like to have this possibility).

But if seriously, I think that the present situation is pretty weird
especially when there is already the `MappingProxy` type. When it's not
allowed and does not work  (I'm only talking about the functions), it's
better to raise early, instead of be silent until the last.

With kind regards,
-gdg
___
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] "Assignment expression" with function call-alike syntax

2018-05-26 Thread Kirill Balunov
2018-05-24 4:21 GMT+03:00 Steven D'Aprano <st...@pearwood.info>:

> On Wed, May 23, 2018 at 12:32:36AM +0300, Kirill Balunov wrote:
>
> > Just one more variation on "assignment exression" syntax to make the list
> > more complete :) Sorry, if something similar has already been suggested.
> > The idea is to use function's call-like syntax in the from: `this( name =
> > expr )`.
> [...]
> > In this way it is somewhat possible to make an assignment in `while` and
> `if
> > ` headers right now, which covers 90% cases, but it is damn slow. Maybe
> be
> > it is worth to make `this` magic call-alike object work fast...on the
> other
> > hand does anyone like `this`?
>
> Apart from needing extra typing, what does the function-call syntax gain
> us?


This will allow us to temporarily avoid the introduction of a new syntax.
Since this option does not require a new syntax, you can provide a
provisional module containing. This will allow to understand more clearly
the actual use cases and the attitude of users towards the general idea.


> It looks like a function you could call from anywhere, but you want
> to limit it to just "while" and "if", I expect that will just give us a
> flood of questions on Stackoverflow and other forums, "why can't I use
> this() outside of if and while loops?"
>

I do not know how you decided that I propose to limit this call-alike
variant only to `while` and `if`statements. I did not say that. I just said
that personally I'm interested and see the advantages of using it only in
`while` and `if` statements. Of course you are right that you can call it
from anywhere.


>
> A good question. Why shouldn't we use assignment outside of if and while?
>
> Since this is special syntax, not a function, the parens don't give us
> any benefit:
>
> this name = expression
>
> The word "this" seems inappropriate. Surely "let" or "set" would be
> better:
>
> let name = expression
>
> which at least has the benefit of matching syntax chosen in other
> languages. But if the only reason we include "let" is to avoid the
> equals/assignment error, that seems needlessly verbose. We can say the
> same thing more compactly:
>

I'm not much attached to `this`. Ok let it be `let`.


>
> name := expression
>
>
> The difference between "let name = expression" and "name := expression"
> is just spelling.


The main point is to collect more information, since the idea of assignment
expression will have a huge impact in all aspects of Python programming:
how you structure your programm, how you write code, how you read code, how
you parse code... Because at the moment the rule is simple that any name
binding must occur only in statements.

With kind regards,
-gdg
___
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] ternary without else

2018-05-25 Thread Kirill Balunov
2018-05-25 13:06 GMT+03:00 Jacco van Dorp :

> [...]
>
> I would very much like to write:
>
> >>> do_something if cond
>
> and be done with it. Like a ternary expression but without the else clause.
>
>
If it is an expression, what should `do_something if cond` return on
failure? If you don't care you can already use `cond and do_something`.

With kind regards,
-gdg
___
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] "Assignment expression" with function call-alike syntax

2018-05-23 Thread Kirill Balunov
2018-05-23 17:54 GMT+03:00 Mike Miller <python-id...@mgmiller.net>:

>
> On 2018-05-22 14:32, Kirill Balunov wrote:
>
>> # in global scope everything works ok since locals is globals
>>  >>> while len( this( val = dummy() ) ) >= 0:
>> ... print(val)
>> [0, 1]
>> [0, 1, 2]
>> [0, 1, 2, 3]
>>
>
> Interesting!  Although the example with a len() and mutable default
> arguments obscured the utility, I thought.  Also, why limit it to one
> assignment?
>
>
I just want some dummy example which can not be trivially handled with `for
name in iter(func, value)`. But the latter is also only partly true. You
can make something like:

class P:
__slots__ = ('func')
def __init__(self, func):
self.func = func
def __eq__(self, other):
return not self.func(other)

for val in iter(dummy, P(lambda x: len(x) < 5)):
print(val)

[0, 1]
[0, 1, 2]
[0, 1, 2, 3]

The only restriction is that you can not pass arguments to a `func`, but
this, to some extent, can also be handled with lambda. I limit it to _one
assignment_ firstly to make it simple, and secondly to get rid of some edge
cases.


> Liked Terry's suggestions for name.  The name that jumped into my brain as
> I read was a reuse of the locals() or globals() callable with key words,
> that would change their behavior to what you suggest.


I like `this` because it is easy to follow in my opinion: " While this name
assigned to an expression is  greater than zero do... " But of course I'm
open to any other spelling. I'm just wondering, if someone like this form
as an alternative for assignment expression (`:=`).

With kind regards,
-gdg
___
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] "Assignment expression" with function call-alike syntax

2018-05-23 Thread Kirill Balunov
2018-05-23 14:19 GMT+03:00 Masayuki YAMAMOTO :

> FYI, I found a package [*] which binds a value by function keyword (I'm
> not the author). Note that the package writes a value in the global (or
> raise an error if the name already exists in local) unlike your idea.
>
> [*] https://pypi.org/project/let3/
>
> --
> Masayuki
>

Thank you! Writing to a globals is an even more stripped-down version from
the inteded behaviour, for example it would not work in comprehensions at
all and would not work if function has the same local name. In fact
comprehension/generator cases are the least interesting for me. I just
wanted to minimize side-effects.

With kind regards,
-gdg
___
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] "Assignment expression" with function call-alike syntax

2018-05-23 Thread Kirill Balunov
2018-05-23 9:05 GMT+03:00 Terry Reedy <tjre...@udel.edu>:

> On 5/22/2018 5:32 PM, Kirill Balunov wrote:
>
>> Just one more variation on "assignment exression" syntax to make the list
>> more complete :) Sorry, if something similar has already been suggested.
>> The idea is to use function's call-like syntax in the from: `this( name =
>> expr )`.
>>
>
> Functions names should be verbs.  For this one, 'bind' or even better,
> 'let' as in 'let(name=expr)'


It only looks like a function call, but in fact it should be an _magic
object_ that can on the call bind a name to an expression in the current
local scope. I chose `this` because in my opinion it is easily
perceived: `while
this( name = expr ) > 0`  can be readed as  "While this name assigned to an
expression is  greater than zero do..." the same interpretation for `if`
statement.

With kind regards,
-gdg
___
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] "Assignment expression" with function call-alike syntax

2018-05-22 Thread Kirill Balunov
Just one more variation on "assignment exression" syntax to make the list
more complete :) Sorry, if something similar has already been suggested.
The idea is to use function's call-like syntax in the from: `this( name =
expr )`. I'm not sure that such idea will find its supporters and whether
it is possible to implement it in a general way, but nevertheless. Below is
a half- and slow-working prototype and some silly examples just for the
sake of feeling the idea:

import sys
import ctypes

def this(**assign):
assert len(assign) == 1
[(name, value)] = assign.items()
frame = sys._getframe(1)
frame.f_locals[name] = value
ctypes.pythonapi.PyFrame_LocalsToFast(ctypes.py_object(frame),
  ctypes.c_int(0))
return value

Loop-and-a-half example with `dummy` function[1]:

# in global scope everything works ok since locals is globals
>>> while len( this( val = dummy() ) ) >= 0:
... print(val)
[0, 1]
[0, 1, 2]
[0, 1, 2, 3]
...


# needs to set the same local name to work inside function
def func():
val = ...
while len( this( val = dummy() ) ) >= 0:
print(val)



>>> # relies on the implicit underlying function's local `x`
>>> [[this(x = (x+10)), x//10, x*10] for x in [100, 200, 300]]
[[110, 11, 1100], [210, 21, 2100], [310, 31, 3100]]


In this way it is somewhat possible to make an assignment in `while` and `if
` headers right now, which covers 90% cases, but it is damn slow. Maybe be
it is worth to make `this` magic call-alike object work fast...on the other
hand does anyone like `this`?


With kind regards,
-gdg

[1]:

def dummy(ls = [0]):
ls.append(ls[-1]+1)
return ls
___
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] Modern language design survey for "assign and compare" statements

2018-05-19 Thread Kirill Balunov
2018-05-19 3:54 GMT+03:00 Mike Miller :

> Background:
>
> While the previous discussions about assignment-expressions (PEP 572)
> (abbreviated AE below) have been raging one thing that was noticeable is
> that
> folks have been looking back to C for a solution.
>
> But how are newer languages solving the problem today?  Believe Ryan
> brought
> this up first on the list, but it had been in the back of my mind as well.
> Finally have compiled my research, corrections welcome.  In alphabetical
> order:
>
>
Thank you Mike this is a very useful analysis. It would be also great to
know when they introduced this feature - from the beginning or after a
while. Your results are completely consistent with all the examples from
the numerous threads - that this feature should be added only in `while`
and `if` statements.


[Chris]

The bit that you tag on as an afterthought is actually critically
> important here. You have two options:
> 1) The 'as' is part of the syntax of the 'if' and 'while' statements; or
> 2) The 'as' is part of the definition of an expression.
> The first case would be grammar like this:
> if_stmt: 'if' test ['as' NAME] ':' suite ('elif' test ':' suite)*
> ['else' ':' suite]
> The second is permitting 'as' name-bindings in arbitrary expressions,
> but then saying "except that they're only allowed in 'if' statements".
> As you've noted, the first one isn't sufficient. You can't use the
> restricted syntax for more than a small handful of conditions
> (including re.match(), but not including anything that might return
> None and might return other falsey values).
> So if this is valid:
> if (f(x) as y) is not None:
> then why isn't this valid:
> print(f(x) as y)
> or this:
> f(x) as y # identical to "y = f(x)"
> or even this:
> with (f(x) as y):


I think I have a very strong argument "why are not others valid" - Because
already three months have passed and among 1300+ messages there was not a
single real example where assignment expression would be convenient or
useful outside `while` and `if` statements. If you have a counterargument
(with an example), I would be glad to see.

This thread is about the design choices which were made in other modern
languages. And from Mike's analysis it is evident that other languages have
chosen to allow the assignment as an expression only where it is practical
- in `while` and `if` statements, or not to allow it at all.

I find this at least absolutely not constructive to push `print(f(x) as y)`
or `print(y:=f(x))` in every thread.  Is this really the only compelling
example outside `while` and `if`? Also if we consider only the usage in
`while` and `if` statements, what is the point of discussing differences
between `with (f(x) as y)` and `with f(x) as y`?  The first one will be a `
SyntaxError`, period. Can you also explain why the assignment  expression
should be valid outside `while` and `if` statements? - for dummy
consistency?  The `as` variant was _hammered_ only in the general case,
which in itself does not make sense (which is confirmed by 1300+ messages
without examples).

Some time ago Guido said that he is not _impressed_ with `as` variant. But
I think he does not like this form because it does not play well in general
case. There are several reasons why. The main one is if `as` will be
accepted it will prevent the use of this form in theoretically future
statements (for example match statement). Another point that it looks ugly
for general case. As it seems to me, the intersection with `with`, `except`
is also important but can be overcomed. The use of any system requires some
study and understanding. BUT I also think that Guido will not so strongly
object if only `while` and `if` statements were under consideration,
because there is no other choice.

Examples from other languages are very important and their choice should be
taken into account. Those languages are also designed by smart guys and I'm
sure that they were thinking about where the assignement expression should
be allowed and 1300+ messages only confirm their choice. Therefore, it may
be worthwhile to focus only on actual use cases - in `while` and `if`
statements??? and stop to flood every thread with dummy examples.


p.s.: I deliberately did not mention the pseudo _usefulness_ of assignment
expression in generators/comprehensions because the benefits are very
questionable. Therefore, to begin with, we should start with `while` and
`if` statements, and possibly in the future add it to
comprehensions/generators.

With kind regards,
-gdg
___
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] Inline assignments using "given" clauses

2018-05-11 Thread Kirill Balunov
2018-05-11 17:06 GMT+03:00 Clint Hepner :

>
>
> (This reminds that I wish ``iter`` could take a predicate instead of a
> sentinel as its second argument. Then
> you could just write
>
> for cmd in iter(get_command, lambda x: x.token == CMD_QUIT):
> cmd.do_something()
> )
>
>
But you can do it right now:

class P:
def __init__(self, key):
self.key = key
def __eq__(self, other):
return self.key(other)

for cmd in iter(get_command, P(lambda x: x.token == CMD_QUIT)):
cmd.do_something()

With kind regards,
-gdg
___
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] Inline assignments using "given" clauses

2018-05-10 Thread Kirill Balunov
2018-05-10 16:44 GMT+03:00 Guido van Rossum :

> I'm sorry, but unless there's a sudden landslide of support for 'given' in
> favor of ':=', I'm really not going to consider it.
>
> I'd pronounce "if (x := y) > 0" as either "if y (assigned to x) is greater
> than zero" or "if x (assigned from y) is greater than zero".
>


I think you do not quite objectively look at the current situation. Many
just lost interest in attempts to move the topic at least a little bit in
the other way, seeing how you and Tim so actively expresses
support/protects this `:=` syntax, while ignoring or pushing out
alternative opinions :-). Of course, the latter is partly due to the
incredible number of different threads and messages on this topic.

Briefly:

Initially, the main argument in favor of `:=` was that this form is similar
to the usual assignment statement, but can be used as an expression. Ok.

Then everyone agreed with the idea that it's necessary to limit assignment
target to name only. Although all this criticism was actually put forward
in the first 50-100 messages on the topic.

In the same first hundred it was actively discussed, that in fact, this
idea gives a win only in `while` and `if` statemetns that probably will
match 99%+ where it will be used for its intended purpose. At the same
time, most of the criticism concerned exactly the use in generators and
comprehenshions, they are already often overloaded for perception. And as
you once said - "Language Design Is Not Just Solving Puzzles".

There was also discussed the difference in perception between the `expr op
name` and `name op expr`. Here the expression is something that is
important, the name is only a convenient consequence.

At the moment with all the constraints of `:=`, the discuscation is more
like - trying to cram this syntax into the language. While for those who
are familiar with Pascal, Icon and other languages that use this syntax,
this - `:=` looks natural. For others and I believe such a majority among
users, this syntax is, to put it mildly, not natural and ugly producing a
line noise, the colon `:` symbol is already used in a lot of places.

With all the changes, the limitations and magic with scopes. Is it now
easier to explain all the differences between `=` and `:=`, than the
difference between `if expr as name ...: ...` and `with expr as name:`?

Therefore, I take Nick's insistent position as an attempt to at least
somehow make an alternative look at this topic.


With kind regards,
-gdg
___
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] A "local" pseudo-function

2018-04-29 Thread Kirill Balunov
2018-04-29 17:52 GMT+03:00 MRAB :
>
>
>> How about these:
>
> local m1, m2:
> m1 = regexp1.match(line)
> m2 = regexp2.match(line):
> if m1 and m2:
> ...
>

Is it possible to do the same thing, but with the help of `with` statement:

with local('m1', 'm2'):

m1 = regex1.match(line)
m2 = regex2.match(line)
if m1 and m2:

...


With kind regards,
-gdg
___
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] Spelling of Assignment Expressions PEP 572 (was post #4)

2018-04-16 Thread Kirill Balunov
 [Guido]
2018-04-15 20:19 GMT+03:00 Guido van Rossum <gu...@python.org>:

> On Sun, Apr 15, 2018 at 4:05 AM, Kirill Balunov <kirillbalu...@gmail.com>
> wrote:
>
>> [...] For me personally, `: =` looks and feels just like normal
>> assignment statement which can be used interchangeable but in many more
>> places in the code. And if the main goal of the PEP was to offer this
>> `assignment expression` as a future replacement for `assignment statement`
>> the `:=` syntax form would be the very reasonable proposal (of course in
>> this case there will be a lot more other questions).
>>
>
> I haven't kept up with what's in the PEP (or much of this thread), but
> this is the key reason I strongly prefer := as inline assignment operator.
>
>
>> But somehow this PEP does not mean it! And with the current rationale of
>> this PEP it's a huge CON for me that `=` and `:=` feel and look the same.
>>
>
> Then maybe the PEP needs to be updated.
>

[Chris]
2018-04-15 23:28 GMT+03:00 Chris Angelico <ros...@gmail.com>:

> On Mon, Apr 16, 2018 at 3:19 AM, Guido van Rossum <gu...@python.org>
> wrote:
> > On Sun, Apr 15, 2018 at 4:05 AM, Kirill Balunov <kirillbalu...@gmail.com
> >
> > wrote:
> >> But somehow this PEP does not mean it! And with the current rationale of
> >> this PEP it's a huge CON for me that `=` and `:=` feel and look the
> same.
> >
> > Then maybe the PEP needs to be updated.
>
> I can never be sure what people are reading when they say "current"
> with PEPs like this. The text gets updated fairly frequently. As of
> time of posting, here's the rationale:
>
> -
> Naming the result of an expression is an important part of programming,
> allowing a descriptive name to be used in place of a longer expression,
> and permitting reuse.  Currently, this feature is available only in
> statement form, making it unavailable in list comprehensions and other
> expression contexts.  Merely introducing a way to assign as an expression
> would create bizarre edge cases around comprehensions, though, and to avoid
> the worst of the confusions, we change the definition of comprehensions,
> causing some edge cases to be interpreted differently, but maintaining the
> existing behaviour in the majority of situations.
> -
>
> Kirill, is this what you read, and if so, how does that make ':=' a
> negative? The rationale says "hey, see this really good thing you can
> do as a statement? Let's do it as an expression too", so the parallel
> should be a good thing.
>
>
Yes, this is what I read. I understand why you have such a question so I'll
try to explain my position in more detail. Also I want to add that I did
not fully understand about which part Guido said - "Then maybe the PEP
needs to be updated." Therefore, I allow myself to assume that he had in
mind the following - "The assignment expression should be semantically
equivalent to assignment statement and perceived as a theoretically
possible future replacement (usage) of assignment statement." If this is
really the case and I understood correctly - I will repeat that for me the
current state of the PEP does not fully imply this.

1.  Part - "Then maybe the PEP needs to be updated."

If you really see it as a theoretical substitute for assignment statement
in future Python. I will update the rationale with  maybe the following (I
immediately warn you that I do not pretend to have a good English style):

-
Naming the result of an expression is an important part of programming,
allowing a descriptive name to be used in place of a longer expression,
and permitting reuse.  Currently, in Python this feature is available only
in
statement form, making it unavailable in list comprehensions and other
expression contexts.  This restriction, of making it as a statement, was
done
primarily to avoid the usual trap of `=` vs `==` in C/C++ language.  Despite
this, it is evident that the ability to assign a name within an expression
is convenient, allows to avoid redundant recalculations of the same
expression
and is a familiar feature from other programming languages.  Thus the main
aim
of this PEP is to provide a syntax which will allow to assign as an
expression
and be semantically and visually interchangeable with the assignment
statement.
...
-

In this case, I do not see any reason to discuss the alternative syntax -
there is really only one choice `:=`. And then for me the list of open
questions would look like (for example):
1. ...Is it worth accepting?
2. ...Should the other forms (+=, *=, basically all) that can not be
confused with `==` be changed to expressions?
...


2.  Part - How do I understand the current state of the PEP

I perceive the current rationale as "h

Re: [Python-ideas] Spelling of Assignment Expressions PEP 572 (was post #4)

2018-04-16 Thread Kirill Balunov
2018-04-15 23:22 GMT+03:00 Chris Angelico :

>
> > 0.
> >
> > while (items[i := i+1] := read_next_item()) is not None:
> > print(r'%d/%d' % (i, len(items)), end='\r')
> >
> > 1.
> >
> > while (read_next_item() -> items[(i+1) -> i]) is not None:
> > print(r'%d/%d' % (i, len(items)), end='\r')
>
> These two are matching what I wrote, and are thus the two forms under
> consideration. I notice that you added parentheses to the second one;
> is there a clarity problem here and you're unsure whether "i + 1 -> i"
> would capture "i + 1" or "1"? If so, that's a downside to the
> proposal.
>
>
Yes parentheses were used only for clarity. I agree that I misunderstood
the purpose of your question. I have no problem if the right part is a
complex target, but maybe my perception is biased.

With kind regards,
-gdg
___
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] Spelling of Assignment Expressions PEP 572 (was post #4)

2018-04-15 Thread Kirill Balunov
2018-04-15 18:58 GMT+03:00 Steven D'Aprano :

>
> [...]
>
> But this time we don't care about the name. Its the value we care about:
>
> result = some_func(don't care,
>don't care -> don't care
>don't care -> don't care
>don't care(don't care),
>HERE IT IS  ,
>...)
>

This made my day! :) The programming style when you absolutely don't care
:))) I understand that this is a typo but it turned out to be very funny.

In general, I agree with everything you've said. And I think you found a
very correct way to explain why expression should go first in assignment
expression.

With kind regards,
-gdg
___
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] Spelling of Assignment Expressions PEP 572 (was post #4)

2018-04-15 Thread Kirill Balunov
2018-04-15 15:21 GMT+03:00 Chris Angelico <ros...@gmail.com>:

> On Sun, Apr 15, 2018 at 7:19 PM, Kirill Balunov <kirillbalu...@gmail.com>
> wrote:
> >> === Expression first, 'as' keyword ===
> >>
> >> while (read_next_item() as value) is not None:
> >> ...
> >>
> >> Pros:
> >>
> >>   * typically reads nicely as pseudocode
> >>   * "as" is already associated with namebinding operations
> >>
> >
> > I understand that this list is subjective. But as for me it will be huge
> PRO
> > that the expression comes first.
>
> I don't think we're ever going to unify everyone on an arbitrary
> question of "expression first" or "name first". But to all the
> "expression first" people, a question: what if the target is not just
> a simple name?
>
> while (read_next_item() -> items[i + 1 -> i]) is not None:
> print("%d/%d..." % (i, len(items)), end="\r")
>
> [...]
>
> Not a rhetorical question. I'm genuinely curious as to whether people
> are expecting "expression -> NAME" or "expression -> TARGET", where
> TARGET can be any valid assignment target.
>
>
I completely agree with you that it is impossible to unify everyone opinion
- we all have different background. But this example is more likely to play
against this PEP. This is an extra complexity within one line and it can
fail hard in at least three obvious places :) And I am against this usage
no matter `name first` or `expression first`. But i will reask this with
following snippets. What do you choose from this examples:

0.

while (items[i := i+1] := read_next_item()) is not None:
print(r'%d/%d' % (i, len(items)), end='\r')

1.

while (read_next_item() -> items[(i+1) -> i]) is not None:
print(r'%d/%d' % (i, len(items)), end='\r')

2.

while (item := read_next_item()) is not None:
items[i := (i+1)] = item
print(r'%d/%d' % (i, len(items)), end='\r')

3.

while (read_next_item() -> item) is not None:
items[(i+1) -> i] = item
print(r'%d/%d' % (i, len(items)), end='\r')

4.

while (item := read_next_item()) is not None:
i = i+1
items[i] = item
print(r'%d/%d' % (i, len(items)), end='\r')

5.

while (read_next_item() -> item) is not None:
i = i+1
items[i] = item
print(r'%d/%d' % (i, len(items)), end='\r')

I am definitely Ok with both 2 and 3 here. But as it was noted `:=`
produces additional noise in other places and I am also an `expression
first` guy :) So I still prefer variant 3 to 2. But to be completely
honest, I would write it in the following way:

for item in iter(read_next_item, None):
items.append(item)
print(r'%d/%d' % (i, len(items)), end='\r')


With kind regards,
-gdg
___
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] Spelling of Assignment Expressions PEP 572 (was post #4)

2018-04-15 Thread Kirill Balunov
2018-04-15 12:41 GMT+03:00 Mikhail V :

>
> Exactly, all forms invites this and other questions.
>
> First of all, coming back to original spelling choice arguments
> [Sorry in advance if I've missed some points in this huge thread]
>
> citation from PEP:
>   "Differences from regular assignment statements" [...]
>   "Otherwise, the semantics of assignment are unchanged by this proposal."
>
> So basically it's the same Python assignment?
> Then obvious solution seems just to propose "=".
> But I see Chris have put this in FAQ section:
> "The syntactic similarity between ``if (x == y)`` and ``if (x = y)`` "
>

[OT] To be honest I never liked the fact that `=` was used in various
programming languages as assignment. But it became so common that and I got
used to it and even stopped taking a sedative :)

So IIUC, the *only* reason is to avoid '==' ad '=' similarity?
> If so, then it does not sound convincing at all.
> Of course Python does me a favor showing an error,
> when I make a typo like this:
> if (x = y)
>
> But still, if this is the only real reason, it is not convincing.
> Syntactically seen, I feel strong that normal '=' would be the way to go.
>
> Just look at this:
> y = ((eggs := spam()), (cheese := eggs.method())
> y = ((eggs = spam()), (cheese = eggs.method())
>
> The latter is so much cleaner, and already so common to any
> old or new Python user. And does not raise a
> question what this ":=" should really mean.
> (Or probably it should raise such question?)
>
> Given the fact that the PEP gives quite edge-case
> usage examples only, this should be really more convincing.
> And as a side note: I personally find the look of ":=" a bit 'noisy'.
>

You are not alone. On the other hand it is one of the strengths of Python -
not allow to do so common and complex to finding bugs. For me personally,
`: =` looks and feels just like normal assignment statement which can be
used interchangeable but in many more places in the code. And if the main
goal of the PEP was to offer this `assignment expression` as a future
replacement for `assignment statement` the `:=` syntax form would be the
very reasonable proposal (of course in this case there will be a lot more
other questions). But somehow this PEP does not mean it! And with the
current rationale of this PEP it's a huge CON for me that `=` and `:=` feel
and look the same.


>
> Another point:
>
> *Target first  vs  Expression first*
> ===
>
> Well, this is nice indeed. Don't you find that first of all it must be
> decided what should be the *overall tendency for Python*?
> Now we have common "x = a + b" everywhere. Then there
> are comprehensions (somewhat mixed direction) and
> "foo as bar" things.
> But wait, is the tendency to "give the freedom"? Then you should
> introduce something like "<--" in the first place so that we can
> write normal assignment in both directions.
>

As it was noted previously `<-` would not work because of unary minus on
the right:

>>> x = 10
>>> x <- 5
False



> Or is the tendency to convert Python to the "expression first" generally?
>
> So if this question can be answered first, then I think it will be
> more constructive to discuss the choice of particular spellings.
>

If the idea of the whole PEP was to replace `assignment statement` with
`assignment expression` I would choose name first. If the idea was to offer
an expression with the name-binding side effect, which can be used in the
appropriate places I would choose expression first.

With kind regards,
-gdg
___
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] Spelling of Assignment Expressions PEP 572 (was post #4)

2018-04-15 Thread Kirill Balunov
2018-04-15 6:08 GMT+03:00 Nick Coghlan :

>
> It's not completely off topic. as it's due to the fact we use "," to
> separate both context managers and items in a tuple, so "with (cm1,
> cm2, cm3):" is currently legal syntax that means something quite
> different from "with cm1, cm2, cm3:". While using the parenthesised
> form is *pointless* (since it will blow up at runtime due to tuples
> not being context managers), the fact it's syntactically valid makes
> us more hesitant to add the special case around parentheses handling
> than we were for import statements. The relevance to PEP 572 is as a
> reminder that since we *really* don't like to add yet more different
> cases to "What do parentheses indicate in Python?"


Despite the fact that "with (cm1,cm2, cm3):"  currently is the legal
syntax, but as you said and as it was also noted before in this thread - it
is "pointless" in 99% cases (in context of with statement) and will fail at
runtime. Therefore, regardless of this PEP, maybe it is fair to make it at
least to be a `SyntaxWarning` (or `SyntaxError`)? Better fail sooner than
later.


we should probably
> show similar hesitation when it comes to giving ":" yet another
> meaning.
>
>
Yes, `:` is used (as a symbol) in a lot of places (in fact there is not
much in it), but in some places Python looks as a combination of words and
colons.


> P.S. The pros and cons of the current syntax proposals, as I see them:
>
> === Expression first, 'as' keyword ===
>
> while (read_next_item() as value) is not None:
> ...
>
> Pros:
>
>   * typically reads nicely as pseudocode
>   * "as" is already associated with namebinding operations
>
>
I understand that this list is subjective. But as for me it will be huge
PRO that the expression comes first.


> Cons:
>
>   * syntactic ambiguity in with statement headers (major concern)
>   * encourages a common misunderstanding of how with statements work
> (major concern)
>   * visual similarity between "as" and "and" makes name bindings easy to
> miss
>   * syntactic ambiguity in except clause headers theoretically exists,
> but is less of a concern due to the consistent type difference that
> makes the parenthesised form pointless
>
>
In reality, the first two points can be explained (if it will be required
at all). Misunderstanding is a consequence of a lack of experience. I don't
understand the the point about "visual similarity between "as" and "and"
can you elaborate on this point a little bit more?



> === Expression first, '->' symbol ===
>
> while (read_next_item() -> value) is not None:
> ...
>
> Pros:
>
>   * avoids the syntactic ambiguity of "as"
>   * "->" is used for name bindings in at least some other languages
> (but this is irrelevant to users for whom Python is their first, and
> perhaps only, programming language)
>
>
The same as previous,  the expression comes first is a huge PRO for me and
I'm sure for many others too. With the second point I agree that it is
somewhat irrelevant.


> Cons:
>
>   * doesn't read like pseudocode (you need to interpret an arbitrary
> non-arithmetic symbol)
>

Here I am a bit disagree with you. The most common for of assignment in
formal pseudo-code is `name <- expr`. The second most common form, to my
regret,  is - `:=`. The `<-` form is not possible in Python and that is why
`expr -> name` was suggested.


>   * invites the question "Why doesn't this use the 'as' keyword?"
>

All forms invites this question :)))


>   * symbols are typically harder to look up than keywords
>   * symbols don't lend themselves to easy mnemonics
>   * somewhat arbitrary repurposing of "->" compared to its use in
> function annotations
>
>  The last one is a major concern. I think that is why Guido is so
skeptical about this form.


> === Target first, ':=' symbol ===
>
> while (value := read_next_item()) is not None:
> ...
>
> Pros:
>
>   * avoids the syntactic ambiguity of "as"
>   * being target first provides an obvious distinction from the "as"
> keyword
>

For me it is a CON. Originally the rationale of this PEP was to reduce the
number of unnecessary calculations and to provide a useful syntax to make a
name binding in appropriate places. It should not, in any way, replace the
existing `=` usual way to make a name binding. Therefore, as I see it, it
is one of design goals to make the syntax forms of `assignment statement`
and `assignment expression` to be distinct and `:=` does not help with
this. This does not mean that this new syntax form should not be
convenient, but it should be different from the usual `=` form.


>   * ":=" is used for name bindings in at least some other languages
> (but this is irrelevant to users for whom Python is their first, and
> perhaps only, language)
>
> Cons:
>
>   * symbols are typically harder to look up than keywords
>   * symbols don't lend themselves to easy mnemonics
>   * subject to a visual "line noise" phenomenon when combined with
> 

Re: [Python-ideas] PEP 572: Assignment Expressions (post #4)

2018-04-12 Thread Kirill Balunov
2018-04-12 12:48 GMT+03:00 Jacco van Dorp :

> Wouldn't these local name bindings make the current "as" clause of
> "with f(x) as y" completely obsolete ?
>
> It's probably good to know my background, and my background is that I
> know completely nothing of the implementation, im only junior software
> engineer, and python was my first programming experience, and still
> the one I have by far the most experience with.
>
> To me, the entire proposal sounds mostly like an expansion of the as
> syntax as we know it from "with". There will be no difference between:
>
> with open(filename) as f:
> // code
>
> and
>
> with f  := open(filename):
> // code
>
> or at least as far as I can see. (that is, if := will be allowed in
> the with statement, and it sounds like it will ?)
>
>
Thank you Jacob! I do not know if I understood correctly how you understand
what is happening here. But you are just demonstrating my fears about this
proposal...

with f  := open(filename):

This will be only valid if the returned object of (f := open(filename)) defines
__enter__ and __exit__ methods ( Nevertheless, in this situation it is so).
But in other cases it will raise an error. Generally  `with name  := expr` is
not equivalent to `with expr as name:`. In another places, for example,
`except` clause `f := something` is valid only if the returned type is an
object, which inherit from BaseException. So in this two situations, in my
opinion, it will not be used too much.

Yours example under current proposal should look like  `with open(
full_file_path := os.path.join(path, filename) ) as f:`.

With kind regards,
-gdg
___
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] PEP 572: Assignment Expressions (post #4)

2018-04-11 Thread Kirill Balunov
2018-04-11 18:01 GMT+03:00 Kirill Balunov <kirillbalu...@gmail.com>:

>
>
> 2018-04-11 16:50 GMT+03:00 Chris Angelico <ros...@gmail.com>:
>
>>
>> Can you give an example of how your syntax is superior to the more
>> general option of simply allowing "as" bindings in any location?
>>
>>
> This is not my syntax :) And not even my idea. I just do not understand,
> and even a little skeptical about allowing "as" bindings in **any
> location** with global scoping. All the examples in this thread and the
> previous ones, as well as almost all PEP's examples show how this feature
> will be useful in `if`, `while` statements and comprehension/generator
> expressions. And it excellently solves this problem.  This feature
> increases the capabilities of these statements and also positively affects
> the readability of the code and it seems to me that everyone understands
> what this means in this context without ambiguity in their meaning in
> `while` or `with` statements.
>
> The remaining examples (general ones) are far-fetched, and I do not have
> much desire to discuss them :)  These include:
>
> lambda: x := lambda y: z := a := 0
> y = ((eggs := spam()), (cheese := eggs.method()), cheese[eggs])
> and others of these kind...
>
> Thus, I do not understand why to solve such a general and complex problem,
> when this syntax is convenient only in specific cases.  In addition,
> previously the concept of a Statement-Local Name Bindings was discussed, which
> I basically like (and it fits the above idea).  In this version, it was
> abandoned completely, but it is unclear for what reasons.
>
> p.s.: Maybe someone has use-cases outside `if`, `while` and
> comprehensions, but so far no one has demonstrated them.
>
>
I find that I wrote very vague, so I'll try in response to my answer to add
some specifics. In general, I find this idea missed in the language and
thank you for trying to fix this! In my opinion it has only a meaning in
certain constructions such as `while`, `if`, `elif` and maybe
comprehensions\generators. As a general form "anywhere" it can be _useful_,
but makes the code unreadable and difficult to perceive while giving not so
much benefit. What I find nice to have:

Extend while statement syntax:

 while (input("> ") as command) != "quit":
 print("You entered:", command)


Extend if statement syntax:



if re.search(pat, text) as match:
print("Found:", match.group(0))

if (re.search(pat, text) as match) is not None:
print("Found:", match.group(0))

also `elif` clauses should be extended to support.

Extend comprehensions syntax:

# Since comprehensions have an if clause
[y for x in data if (f(x) as y) is not None]

# Also this form without `if` clause

[(y, x/y) with f(x) as y for x in range(5)]

Extend ternary expression syntax:

data = y/x if (f(x) as y) > 0 else 0

I think that is all. And it seems to me that it covers 99% of all the
use-cases of this feature. In my own world I would like them to make a
local _statement_ binding (but this is certainly a very controversial
point). I even like that this syntax matches the `with` an `except`
statements syntax, although it has a different semantic. But I do not think
that anyone will have problems with perception of this.

With kind regards,
-gdg
___
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] PEP 572: Assignment Expressions (post #4)

2018-04-11 Thread Kirill Balunov
2018-04-11 16:50 GMT+03:00 Chris Angelico :

>
> Can you give an example of how your syntax is superior to the more
> general option of simply allowing "as" bindings in any location?
>
>
This is not my syntax :) And not even my idea. I just do not understand,
and even a little skeptical about allowing "as" bindings in **any
location** with global scoping. All the examples in this thread and the
previous ones, as well as almost all PEP's examples show how this feature
will be useful in `if`, `while` statements and comprehension/generator
expressions. And it excellently solves this problem.  This feature
increases the capabilities of these statements and also positively affects
the readability of the code and it seems to me that everyone understands
what this means in this context without ambiguity in their meaning in
`while` or `with` statements.

The remaining examples (general ones) are far-fetched, and I do not have
much desire to discuss them :)  These include:

lambda: x := lambda y: z := a := 0
y = ((eggs := spam()), (cheese := eggs.method()), cheese[eggs])
and others of these kind...

Thus, I do not understand why to solve such a general and complex problem,
when this syntax is convenient only in specific cases.  In addition,
previously the concept of a Statement-Local Name Bindings was discussed, which
I basically like (and it fits the above idea).  In this version, it was
abandoned completely, but it is unclear for what reasons.

p.s.: Maybe someone has use-cases outside `if`, `while` and comprehensions,
but so far no one has demonstrated them.

With kind regards,
-gdg
___
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] PEP 572: Assignment Expressions (post #4)

2018-04-11 Thread Kirill Balunov
Great work Chris! Thank you!

I do not know whether this is good or bad, but this PEP considers so many
different topics, although closely interrelated with each other.

2018-04-11 8:32 GMT+03:00 Chris Angelico :

>
> Alterations to comprehensions
> -
>
> The current behaviour of list/set/dict comprehensions and generator
> expressions has some edge cases that would behave strangely if an
> assignment
> expression were to be used. Therefore the proposed semantics are changed,
> removing the current edge cases, and instead altering their behaviour
> *only*
> in a class scope.
>
> As of Python 3.7, the outermost iterable of any comprehension is evaluated
> in the surrounding context, and then passed as an argument to the implicit
> function that evaluates the comprehension.
>
> Under this proposal, the entire body of the comprehension is evaluated in
> its implicit function. Names not assigned to within the comprehension are
> located in the surrounding scopes, as with normal lookups. As one special
> case, a comprehension at class scope will **eagerly bind** any name which
> is already defined in the class scope.
>
>
I think this change is important one no matter what will be the future of
the current PEP. And since it breaks backward compatibility it deserves a
separate PEP.


> Open questions
> ==
>
> Can the outermost iterable still be evaluated early?
> 
>
> As of Python 3.7, the outermost iterable in a genexp is evaluated early,
> and
> the result passed to the implicit function as an argument.  With PEP 572,
> this
> would no longer be the case. Can we still, somehow, evaluate it before
> moving
> on? One possible implementation would be::
>
> gen = (x for x in rage(10))
> # translates to
> def ():
> iterable = iter(rage(10))
> yield None
> for x in iterable:
> yield x
> gen = ()
> next(gen)
>
> This would pump the iterable up to just before the loop starts, evaluating
> exactly as much as is evaluated outside the generator function in Py3.7.
> This would result in it being possible to call ``gen.send()`` immediately,
> unlike with most generators, and may incur unnecessary overhead in the
> common case where the iterable is pumped immediately (perhaps as part of a
> larger expression).
>
>
Previously, there was an alternative _operator form_  `->`  proposed by
Steven D'Aprano. This option is no longer considered? I see several
advantages with this variant:
1. It does not use `:` symbol which is very visually overloaded in Python.
2. It is clearly distinguishable from the usual assignment statement and
it's `+=` friends
There are others but they are minor.


> Frequently Raised Objections
> 
>
> Why not just turn existing assignment into an expression?
> -
>
> C and its derivatives define the ``=`` operator as an expression, rather
> than
> a statement as is Python's way.  This allows assignments in more contexts,
> including contexts where comparisons are more common.  The syntactic
> similarity
> between ``if (x == y)`` and ``if (x = y)`` belies their drastically
> different
> semantics.  Thus this proposal uses ``:=`` to clarify the distinction.
>
>
> This could be used to create ugly code!
> ---
>
> So can anything else.  This is a tool, and it is up to the programmer to
> use it
> where it makes sense, and not use it where superior constructs can be used.
>
>
But the ugly code matters, especially when it comes to Python. For me, the
ideal option would be the combination of two rejected parts:

Special-casing conditional statements
> -
>
> One of the most popular use-cases is ``if`` and ``while`` statements.
> Instead
> of a more general solution, this proposal enhances the syntax of these two
> statements to add a means of capturing the compared value::
>
> if re.search(pat, text) as match:
> print("Found:", match.group(0))
>
> This works beautifully if and ONLY if the desired condition is based on the
> truthiness of the captured value.  It is thus effective for specific
> use-cases (regex matches, socket reads that return `''` when done), and
> completely useless in more complicated cases (eg where the condition is
> ``f(x) < 0`` and you want to capture the value of ``f(x)``).  It also has
> no benefit to list comprehensions.
>
> Advantages: No syntactic ambiguities. Disadvantages: Answers only a
> fraction
> of possible use-cases, even in ``if``/``while`` statements.
>


(+ in `while`) combined with this part:


3. ``with EXPR as NAME``::
>
>stuff = [(y, x/y) with f(x) as y for x in range(5)]
>
>As per option 2, but using ``as`` rather than an equals sign. Aligns
>syntactically with other uses of ``as`` for name binding, but a simple
>

Re: [Python-ideas] Start argument for itertools.accumulate() [Was: Proposal: A Reduce-Map Comprehension and a "last" builtin]

2018-04-08 Thread Kirill Balunov
2018-04-08 8:19 GMT+03:00 Nick Coghlan :

> A name like "first_result" would also make it clearer to readers that
> passing that parameter has an impact on the length of the output
> series (since you're injecting an extra result), and also that the
> production of the first result skips calling func completely (as can
> be seen in Tim's str coercion example).
>
> So where I'd be -1 on:
>
> >>> list(accumulate(1, 2, 3))
> [1, 3, 6]
> >>> list(accumulate(1, 2, 3, start=0))
> [0, 1, 3, 6]
> >>> list(accumulate(1, 2, 3, start=1))
> [1, 2, 4, 7]
>
> I'd be +1 on:
>
> >>> list(accumulate(1, 2, 3))
> [1, 3, 6]
> >>> list(accumulate(1, 2, 3, first_result=0))
> [0, 1, 3, 6]
> >>> list(accumulate(1, 2, 3, first_result=1))
> [1, 2, 4, 7]
>
>
It is a fair point! But the usual way to understand how to use an
additional argument, is to try it or to look examples in the documentation.

Concerning the topic of relationship between `sum` and `accumulate` I have
another point of view. If `start` means something to the `sum`, there are
no grounds for believing that it should mean the same for
`accumulate`, these functions are not really comparable and fundamentally
different. The closest `sum`s friend is `functools.reduce` which uses
`initial` instead of `start`. ( the documentation uses `initializer` and
the docstring uses `initial`, as for me I prefer the `initial`) and so
there is already a discrepancy.

Having said this I think that it is no matter how it will be named `start`
or `initial` or `first_result` or `first`, which is more suitable. I would
prefer `initial` to be the same as in `itertoolz` package. Regarding the
second point, should it yield one more element if provided - I think
everyone here agrees that yes.

With kind regards,
-gdg
___
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] PEP 572: Statement-Local Name Bindings, take three!

2018-03-26 Thread Kirill Balunov
2018-03-26 14:18 GMT+03:00 Steven D'Aprano :

> That was probably my response to Nick:
>
> https://mail.python.org/pipermail/python-ideas/2018-March/049472.html
>
> I compared four possible choices:
>
> target = default if (expression as name) is None else name
> target = default if (name := expression) is None else name
> target = default if (expression -> name) is None else name
> target = default if (name <- expression) is None else name
>

Yes, most likely :)


>
> The two arrow assignment operators <- and -> are both taken from R.
>
>
I was also thinking about `<-` variant (but with a Haskell in mind), but
with the current Python rules, it seems that it does not fit:

>>> x = 10
>>> (x <- 5)
False

With kind regards,
-gdg
___
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] PEP 572: Statement-Local Name Bindings, take three!

2018-03-26 Thread Kirill Balunov
Hi Chris, would you mind to add this syntactic form `(expr -> var)` to
alternative syntax section, with the same semantics as `(expr as var)`. It
seems to me that I've seen this form previously in some thread (can't find
where), but it does not appear in alt. syntax section. As for me this form
has several benefits:
1. Currently it is a SyntaxError
Really there exist some intersection with syntax to annotate function
return type, but it has much smaller impact than `as` variant.
2. This form looks It looks as readable (also the expression comes
first, which appeals to me) as the 'as' variant.
3. It is clearly distinguishable from the usual assignment statement
(which also appeals to me)
Suppose someday someone will want to have a type hint on a local variable
(I think sublocal are safer on this part), then:
```
while (x: int := counter):
do_some_stuff
```
vs
```
while (counter -> x: int):
do_some_stuff
```
Maybe it is too subjective, but the second form looks better for me. taking
in all the аdvantages of the `as` form. Also this '->' form can be extended
to some sort of tuple unpacking. I don't think that tuple unpacking is a
good example, but nevertheless:) And will make further attempts to
introduce ` +:=` impossible.

With kind regards,
-gdg
___
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] PEP 572 version 2: Statement-Local Name Bindings

2018-03-24 Thread Kirill Balunov
2018-03-24 17:14 GMT+03:00 Nick Coghlan :
>
>
> They can be distinguished, just not at module or function scope. To give a
> concrete example:
>
> ==
> >>> class C:
> ... sequence = range(10)
> ... listcomp = [x for x in sequence]
> ... def works(data):
> ... return list(data)
> ... from_works = works(sequence)
> ... def fails():
> ... return list(sequence)
> ...
> >>> C.listcomp
> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
> >>> C.from_works
> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
> >>> C.fails()
> Traceback (most recent call last):
>   File "", line 1, in 
>   File "", line 8, in fails
> NameError: name 'sequence' is not defined
> ==
>
> I think I did have an implementation that didn't do the "outermost
> iterator is evaluated in the outer scope" dance early on (back when I was
> still working on the initial version of the iteration variable hiding,
> before it was merged to the Py3k branch), but quickly changed it because
> relying solely on closures broke too much code (in addition to the class
> namespace case, you can create a situation with similar constraints by
> passing a separate locals namespace to exec).
>
> Cheers,
> Nick.
>

But is the example with the class appropriate in this context, it seems
that it is well understood why this example will fail, and  `C.fails()`
should at least be a `@classmethod`:) From the docs:

> Class definition blocks and arguments to exec()
>  and eval()
>  are special in
> the context of name resolution. A class definition is an executable
> statement that may use and define names. These references follow the normal
> rules for name resolution with an exception that unbound local variables
> are looked up in the global namespace. The namespace of the class
> definition becomes the attribute dictionary of the class. The scope of
> names defined in a class block is limited to the class block; it does not
> extend to the code blocks of methods – this includes comprehensions and
> generator expressions since they are implemented using a function scope.

And if we cross out class, exec and eval cases - they don't work now, they
will not be affected in future. Are not these examples equivalent?

With kind regards,
-gdg
___
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] PEP 572: Statement-Local Name Bindings

2018-02-28 Thread Kirill Balunov
The PEP says:


> Omitting the parentheses from this PEP's proposed syntax introduces many
> syntactic ambiguities.
>

and:

As the name's scope extends to the full current statement, even a block
> statement, this can be used to good effect in the header of an if or while
>  statement



Will the `from ... import ... as ... statement be a special case, because
currently the following form is valid:

from math import (tau as two_pi)

With kind regards,
-gdg
___
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] PEP 572: Statement-Local Name Bindings

2018-02-28 Thread Kirill Balunov
 2018-02-28 16:49 GMT+03:00 Serhiy Storchaka :

> 28.02.18 00:27, Chris Angelico пише:
>
>> Example usage
>> =
>>
>> These list comprehensions are all approximately equivalent::
>>
>>  # Calling the function twice
>>  stuff = [[f(x), f(x)] for x in range(5)]
>>
>
> Other options:
>
> stuff = [[y, y] for y in (f(x) for x in range(5))]
>

Why not `stuff = [[y, y] for y in map(f, range(5))]`?  It is currently the
fastest and most readable version IMHO.

With kind regards,
-gdg
___
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] Coming up with an alternative to PEP 505's None-aware operators

2018-02-16 Thread Kirill Balunov
What about (| val = get_value(x) |) assignment expression which will be True
if success, and None if not?

So it will be value = f() if (| f = calculate |) else default…The idea is
inspired from C’s assignment, but needs some special treatment for anything
which is False in boolean context.

With kind regards,

-gdg
​

2018-02-16 10:55 GMT+03:00 Nick Coghlan :

> On 16 February 2018 at 12:19, rym...@gmail.com  wrote:
> > I don't know...to me this looks downright ugly and an awkward special
> case.
> > It feels like it combines reading difficulty of inline assignment with
> the
> > awkwardness of a magic word and the ugliness of using ?. Basically, every
> > con of the other proposals combined...
>
> Yeah, it's tricky to find a spelling that looks nice without being
> readily confusable with other existing constructs (most notably
> keyword arguments).
>
> The cleanest *looking* idea I've come up with would be to allow
> arbitrary embedded assignments to ordinary frame local variables using
> the "(expr as name)" construct:
>
> value = tmp.strip()[4:].upper() if (var1 as tmp) is not None else None
>
> value = tmp[4:].upper() if (var1 as tmp) is not None else None
>
> value = tmp if (var1 as tmp) is not None else tmp if (var2 as tmp)
> is not None else var3
>
> value = tmp if not math.isnan((var1 as tmp)) else tmp if not
> math.isnan((var2 as tmp)) else var3
>
> value = f() if (calculate as f) is not None else default
>
> filtered_values = [val for x in keys if (get_value(x) as val) is not
> None]
>
> range((calculate_start() as start), start+10)
> data[(calculate_start() as start):start+10]
>
> value if (lower_bound() as min_val) <= value < min_val+tolerance else 0
>
> print(f"{(get_value() as tmp)!r} is printed in pure ASCII as
> {tmp!a} and in Unicode as {tmp}")
>
> However, while I think that looks nicer in general, we'd still have to
> choose between two surprising behaviours:
>
> * implicitly delete the statement locals after the statement where
> they're set (which still overwrites any values previously bound to
> those names, similar to what happens with exception clauses)
> * skip deleting, which means references to subexpressions may last
> longer than expected (and we'd have the problem where embedded
> assignments could overwrite existing local variables)
>
> The interaction with compound statements would also be tricky to
> figure out (especially if we went with the "delete after the
> statement" behaviour).
>
> Cheers,
> Nick.
>
> --
> Nick Coghlan   |   ncogh...@gmail.com   |   Brisbane, Australia
> ___
> 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/


[Python-ideas] Decorator for creating enumeration?

2017-12-10 Thread Kirill Balunov
Since PEP 557 "Data Classes"[1] and PEP 526 "Syntax for Variable
Annotations"[2] are accepted and become part of the language. Is it worth
writing a proposal about decorator-version for creating an enumeration?
Something like:

from enum import enum

@enum(unique=True, int_=False, flag=False, ...):
class Color:
RED : auto
GREEN: auto
BLUE: auto

Despite the fact that Functional API to create enums already exists, it
seems to me that decorator-version will allow to unify these two relatively
young residents of the standard library. In addition, the idea of "Not
having to specify values for enums"[3], which at the time seemed to involve
much magic in the implementation, becomes part of the language. Of course,
PEP 526 unequivocally says that it does not allow one to annotate the types
of variables when tuple unpacking is used. But in any case, I find the
variant with the decorator to be an interersting idea.

With kind regards, -gdg

[1]  PEP 557 "Data Classes" 
[2]  PEP 526 "Syntax for Variable Annotations"

[3]  Not having to specify values for enums.

___
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] How assignment should work with generators?

2017-12-01 Thread Kirill Balunov
2017-11-29 22:33 GMT+03:00 Steve Barnes :

>
> Just a thought but what about a syntax something along the lines of:
>
> a, b, *remainder = iterable
>
> Where remainder becomes the iterable with the first two values consumed
> by assigning to a & b. If the iterator has less than 2 values, (in the
> above case), remaining it should error, if it has exactly 2 then
> remainder would become an exhausted iterable. Of course the user could
> also use:
>
> a, b, *iterable = iterable
>
> Others may differ but this syntax has a lot of similarity to the f(a, b,
> *args) syntax, possibly enough that most users could understand it.
>


Before I started this thread, not so long ago, I have already asked a
question about this semantics [1
].

But it appears to be very ambiguous in practice for the various rhs:

...
x, *y, z = some_iter
*x , y, z = some_iter
x, y, *z = some_iter

And only for the last case it will mean something special. In addition, it
is a huge backward compatibility break.

Probably, some time ago it was necessary to split this thread into two
questions:
1. Philosophical question regarding sequences and iterators. In particular,
should they behave differently depending on the context,
or, in other words, whether to emphasize their different nature as
fixed-size containers and those that are lazily produce values on demand.
2. Additional syntax in the assignment statement for partial extraction of
values from the iterable.

2017-11-30 22:19 GMT+03:00 Paul Moore :

>
> Mostly corner cases, and I don't believe there have been any non-artificial
> examples posted in this thread.

Certainly no-one has offered a real-life code example that is made
> significantly worse by
> the current semantics, and/or which couldn't be easily worked around
> without needing a language change.


Yes, in fact, this is a good question, is whether that is sufficiently
useful to justify extending the syntax. But it is not about corner cases,
it is rather usual situation.
Nevertheless, this is the most difficult moment for Rationale. By now, this
feature does not give you new opportunities for solving problems. It's more
about expressiveness and convenience. You can write:

x, y, ... = iterable

or,

it = iter(iterable)
x, y = next(it), next(it)

or,

from itertools import isclice
x, y = islice(iterable, 2)

or,
x, y = iterable[:2]

and others, also in some cases when you have infinite generator or
iterator, you should use 2nd or 3rd. In fact, this has already been said
and probably I will not explain it better:

2017-11-28 1:40 GMT+03:00 Greg Ewing :

> Guido van Rossum wrote:
>
>> Is this problem really important enough that it requires dedicated
>> syntax? Isn't the itertools-based solution good enough?
>>
>
> Well, it works, but it feels very clumsy. It's annoying to
> have to specify the number of items in two places.
>
> Also, it seems perverse to have to tell Python to do *more*
> stuff to mitigate the effects of stuff it does that you
> didn't want it to do in the first place.
>
> Like I said, I'm actually surprised that this doesn't already
> work. To me it feels more like filling in a piece of
> functionality that was overlooked, rather than adding a
> new feature. Filling in a pothole in the road rather than
> bulding a new piece of road.
>
> (Pushing the road analogy maybe a bit too far, the current
> itertools solution is like digging *more* potholes to make
> the road bumpy enough that you don't notice the first
> pothole.)
>
> (Or failing that, couldn't we add something to itertools to make it more
>> readable rather than going straight to new syntax?)
>>
>
> I'm not sure how we would do that. Even if we could, it
> would still feel clumsy having to use anything from itertools
> at all.


 With kind regards, -gdg
___
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] [Python-Dev] What's the status of PEP 505: None-aware operators?

2017-11-29 Thread Kirill Balunov
2017-11-29 11:14 GMT+03:00 Nick Coghlan :


> It's OK to say "the use case exists, but I still
> don't want that particular syntax for it in Python" (I'm personally
> inclined to agree with you on that front). It's not OK to try to claim
> there are no use cases where the status quo is awkward enough to
> become irritating (since it's an empirically false statement that you
> don't need to be making).
>

If the problem with the proposed syntax, but there are cases for use, it
may be worth to bikeshed one more time?

2017-11-29 9:08 GMT+03:00 Steven D'Aprano :

I'd much prefer to read, write and teach the version with ?? over the
> status quo.


Since the proposed semantics is more similar to the idea of "or", may be it
is better to consider something like:

timeout then local_timeout then global_timeout

I do not know how much this is a frequent case to be worthy of a keyword.

With kind regards, -gdg

2017-11-29 11:14 GMT+03:00 Nick Coghlan :

> On 29 November 2017 at 16:13, David Mertz  wrote:
> > Strong -1 still from me. Too special case for syntax. Just write a
> function
> > 'first_non_none()' that can perfectly will handle the need.
>
> That's the equivalent of SQL's COALESCE, and it's insufficient for the
> same reason "and" and "or" are syntax rather than builtins: the
> function form doesn't provide short-circuiting behaviour.
>
> As far as utility goes, I put it in a similar category to matrix
> multiplication: if you don't need it, you don't need it, but when you
> do need it, you need it a *lot*.
>
> The use case where these operations come up is when you're working
> with partially structured hierarchical data (*cough*JSON*cough*). In
> those kinds of structures, None is frequently used as a marker to say
> "this entire subtree is missing", and you either want to propagate
> that None, or else replace it with something else (and the "something
> else" may be a network call to a different service, so you definitely
> don't want to do it if you don't need to).
>
> So I'd remind folks to try to avoid the "I don't need this, so nobody
> needs this" mistake. It's OK to say "the use case exists, but I still
> don't want that particular syntax for it in Python" (I'm personally
> inclined to agree with you on that front). It's not OK to try to claim
> there are no use cases where the status quo is awkward enough to
> become irritating (since it's an empirically false statement that you
> don't need to be making).
>
> Cheers,
> Nick.
>
> --
> Nick Coghlan   |   ncogh...@gmail.com   |   Brisbane, Australia
> ___
> 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] How assignment should work with generators?

2017-11-28 Thread Kirill Balunov
2017-11-28 22:50 GMT+03:00 Guido van Rossum <gu...@python.org>:

> On Tue, Nov 28, 2017 at 11:44 AM, Kirill Balunov <kirillbalu...@gmail.com>
> wrote:
>
>> Although I have never used Python 2, the idea to distinguish fixed-sized
>> and something lazy, even for Python 4, reminds me of the transition from
>> str-unicode to the present state of affairs, but with much higher impact.To
>> be honest, I do not like some aspects of how Python 2 issue has been
>> resolved (especially bytes part) but it is another topic.
>>
>
> Since Python 4 came up, I'd like to make something clear. Python 4 is
> *not* going to be a release where we break compatibility with a whole bunch
> of things at once. Basically if you think you'll need to wait for Python 4
> to get your favorite change to the language, you can forget it. You need to
> come up with a plan to introduce the change without breaking existing code
> or at least a clear deprecation schedule.
>
> --
> --Guido van Rossum (python.org/~guido)
>

Oh no, I was misunderstood. I think that we have already come to
some consensus which syntax can be discussed. In any case, I did not want
to produce unnecessary noise, I apologize.

With kind regards, -gdg
___
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] How assignment should work with generators?

2017-11-28 Thread Kirill Balunov
2017-11-28 10:06 GMT+03:00 C Anthony Risinger :

>
> If not already considered, what if the RHS had to be explicitly unpacked?
>
> Something like:
>
> a, b, c = *iterator
>
> Which would essentially be:
>
> a, b, c = (*iterator,)
>
> This enables lazy assignment by default but `*` can force complete
> expansion (and exact matching) of the RHS.
>

While I find your suggestions very close to my vision and the initial
proposal, which I still like. I saw enough of the discussion to realize
that by now it is already impossible.


> It's a breaking change, but it does have a straightforward fix (simply
> wrap and unpack any relevant RHS
>

Although I have never used Python 2, the idea to distinguish fixed-sized
and something lazy, even for Python 4, reminds me of the transition from
str-unicode to the present state of affairs, but with much higher impact.To
be honest, I do not like some aspects of how Python 2 issue has been
resolved (especially bytes part) but it is another topic.

With kind regards, -gdg
___
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] How assignment should work with generators?

2017-11-27 Thread Kirill Balunov
2017-11-28 0:52 GMT+03:00 Chris Angelico :

> On Tue, Nov 28, 2017 at 8:49 AM, Guido van Rossum 
> wrote:
> > My PEP queue for Python 3.7 is full though, so I would like to put this
> off
> > until 3.8.
> >
>
> Yeah, I don't think this could reasonably be raced into 3.7 even if it
> were critically important, and it's not. 3.8 will be fine.
>
> Kirill, do you want to spearhead the discussion? I'm happy to help out.
>

Yes of course!

With kind regards, -gdg
___
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] How assignment should work with generators?

2017-11-27 Thread Kirill Balunov
2017-11-27 19:23 GMT+03:00 Paul Moore :


> It should be reasonably easy
> to do a code search for something like "=.*islice", to find code
> that's a candidate for using the proposed syntax. I suspect there's
> very little code like that.


While isclice is something  equivalent, it can be used in places like:

x, y = seq[:2]
x, y, z = seq[:3]

With kind regards, -gdg
___
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] How assignment should work with generators?

2017-11-27 Thread Kirill Balunov
While I was more optimistic when I proposed this idea, moving on I
gradually become less and less optimistic. I did not underestimate how much
this would change the semantics. At present, if the lhs is comma-separated
list of targets, the rhs is evaluated, and only then if they match the
assignment happens. Here it depends on the number of targets in lhs, and
should be evaluated lazily. So someone too perlish clever can assume that
with the proposed syntax:

>>> def gen():
>>> for i in ['a', 'b', 'c', 'd']:
>>> v = x if 'x' in globals() else 'var '
>>> yield v + i

>>> x, y = gen()
>>> x
var a
>>> y
var ab

This is bad and I do not like it, but I do not see any serious reasons why
it should not be allowed. In case of Ellipsis they also should trigger
special behavior.

 While I like this feature of lazy assignment, may be it becomes more
special than it deserves.

With kind regards, -gdg
___
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] How assignment should work with generators?

2017-11-27 Thread Kirill Balunov
2017-11-27 17:14 GMT+03:00 Chris Angelico :
>
>
> Nah, far easier:
>
> x, y = iter(it)
>

Yes, you are right.

>> 2. Readable and not so verbose code
> >> 3. Optimized case for x,y,*z = iterator
> >
> > The semantics of that are already set: the first two items are assigned
> > to x and y, with all subsequent items assigned to z as a list. How will
> > this change optimize this case? It still needs to run through the
> > iterator to generate the list.
>
> Maybe 'optimized case for "x, y, *_ = iterator" where you then never
> use _ and it has no side effects'? But that could be worded better.
>

Yes, you did not need to consume and then to throw out _, and in other
cases not to hang in an endless loop.


> I do think islice is verbose, but the main problem is that you have to
> match the second argument to the number of assignment targets. Slice
> notation is an improvement, but it still has that same problem.
>
> But perhaps this should be added to the list of options for the PEP.
>

 Inconvenience is that in both cases: islice and iter[:2], you should
specify the exact number of assignment targets.


> That's one of the options that I mentioned, as it's been proposed in
> the past. The problem is that it depends on internal whitespace to
> distinguish it from augmented assignment; granted, there's no way to
> use "*=" with multiple targets (or even in the single-target case, you
> can't do "x,*=it" with the comma in it), but that's still a
> readability problem.
>

Your suggestion using Ellipsis at the moment seems to me the most readable,
like:

x, ... = iterable
x, y, ... = iterable

But I have not summed up yet what pitfalls can be on this path.

I really do not like to use "starred" targets in any way:

x, y, * = iterable
x, y, *...

Because any "starred" target implies consuming or collecting, and
contradicts with the proposed behavior.

With kind regards, -gdg
___
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] How assignment should work with generators?

2017-11-27 Thread Kirill Balunov
2017-11-27 15:39 GMT+03:00 Paul Moore <p.f.mo...@gmail.com>:

> On 27 November 2017 at 12:31, Kirill Balunov <kirillbalu...@gmail.com>
> wrote:
> > As I can see at the moment, these cases should behave differently:
> >
> >>>> x, y = [1,2,3,4] # must raise ValueError
> >>>> x, y = iter([1,2,3,4])  # should work
> >
> > But at the same time, it violates current situation. So maybe, as you
> have
> > said we need special syntax. I will think about it.
>
> I would find this confusing. Consider where you don't have literals:
>
> def f(vals):
> x, y = vals
>
> data = [1,2,3,4]
>
> f(data)
> data = iter(data)
> f(data)
>
> Having the two calls behave differently would be a recipe for errors
> as someone refactors the calling code.
>

I can not completely disagree with you, but we all adults here. My first
proposal was about generators only, but they are very similar to iterators
in their behavior. Whatever it was with this syntax, there will be no
difference:

def f(vals):
x, y = vals

data = [1,2,3,4]

f(data)
data = (i for i in data)
f(data)

With kind regards, -gdg
___
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] How assignment should work with generators?

2017-11-27 Thread Kirill Balunov
> In terms of language proposals, you can't just say "don't need values
> for"; the semantics have to be EITHER "consume and discard" OR "don't
> consume". We already have a perfectly good way of spelling "consume
> and discard":
>
> x, y, _ = iter
>

You mean ( x, y, *_ = iter ) ?

Since this has to be about non-consumption of the generator/iterator,
> Ellipsis cannot be a zero-length deque. Thus this syntax would have to
> be restricted to the *last* entry, and it then means "don't check for
> more elements".
>

Yes, you are right to the *last* entry. (*last* depends on proposed syntax
(spelling)).


> The proposed semantics, if I understand you correctly, are:
>
> try:
> _iter = iter(it)
> x = next(_iter)
> y = next(_iter)
> except StopIteration:
> raise ValueError
> # no "else" clause, we're done here
>

Yes, "roughly" this semantics is proposed, with some assumptions on _iter =
iter(it).
As I can see at the moment, these cases should behave differently:

>>> x, y = [1,2,3,4] # must raise ValueError
>>> x, y = iter([1,2,3,4])  # should work

But at the same time, it violates current situation. So maybe, as you have
said we need special syntax. I will think about it.


> Start by perusing PEP 1, and the template in PEP 12:
>
> https://www.python.org/dev/peps/pep-0001/
> https://www.python.org/dev/peps/pep-0012/
>
> The PEP editors (myself included) are here to help you; don't hesitate
> to reach out with questions.
>

Thank you!

With kind regards, -gdg
___
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] Make bytes __repr__ and __str__ representation different?

2017-11-21 Thread Kirill Balunov
2017-11-21 20:22 GMT+03:00 Chris Barker  wrote:

> But the way you did your example indicates that:
>

> bytes((42, 43, 44, 45, 46))
>
> would be an even better __repr__, if the goal is to make it clear and easy
> that it is a "container of integers from 0 to 255"
>
> I've been programming since quite some time ago, and hex has NEVER come
> naturally to me :-)
>

Yes, it is better, but it seemed too radical to me:)



2017-11-21 18:16 GMT+03:00 Steven D'Aprano  wrote:

>  I'd rather give bytes a
> hexdump() method that returns a string:
>
> '2a 2b 2d 2e 2f'
>
> (possibly with optional arguments to specify the formatting).


Since Python 3.5 bytes has a .hex() method, the same as yours .hexdump()
but without spaces. But still it is a string.


2017-11-21 18:38 GMT+03:00 Victor Stinner :

>
> While it may shock you, using bytes for "text" makes sense in some
> areas. Please read the Motivation of the PEP 461:
> https://www.python.org/dev/peps/pep-0461/#motivation


It does not, because it is really useful feature. But rather, ascii was
made so that it would fit into a byte, and not vice versa.

Nevertheless, bytes are the strangest object in Python. It looks like a
string (which contains only ascii), but it is not a string,
because if you index, it does not return a byte -> bytes (b'123 '[0])! =
Bytes (b'1'). May be it is closer to tuple, it is also immutable,
but bytes(3) creates a sequence b '\ x00 \ x00 \ x00', but tuple not (and
what the hell is b'\x00\x00\x00'?).
Maybe it has some relationship to integers but int(b'1') == 1 when
bytes([int(49)]) == b'1', i.e with integers it is not a friend either.

It is bytes...

With kind regards, -gdg
___
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] Make bytes __repr__ and __str__ representation different?

2017-11-21 Thread Kirill Balunov
Currently, __repr__ and __str__ representation of bytes is the same.
Perhaps it is worth making them different, this will make it easier to
visually perceive them as a container of integers from 0 to 255,
instead of a mixture of printable and non-printable ascii characters. It is
proposed:

a) __str__ - leave unchanged
b) __repr__ - represent as sequence of escaped hex

>>> a = bytes([42,43,44,45,46])
>>> a# Current
b'*+-./'
>>> a# Proposed
b'\x2a\x2b\x2d\x2e\x2f'

As you can see, the second example is more easily perceived as a sequence,
in which '\' is also perceived as ',' in list or tuple. In addition, 2020
is close, it allows the new Pythonistas not to take them as an ascii
mixture strings.

With kind regards, -gdg
___
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] Should Python have user-defined constants?

2017-11-21 Thread Kirill Balunov
>
> It is not set in stone, but it looks like most people like Final (although
> the initial proposal was Const, see https://github.com/python/
> mypy/issues/1214)
>

Ivan, you mean this thread "Can't index named tuple by defined constant"
?

With kind regards, -gdg
___
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] Star assignment in iterator way?

2017-11-21 Thread Kirill Balunov
May be the first thing which I should do is to improve my English:) My main
point was that in many cases
(in my experience) it is a waste of memory to store entire list for star
variable (*b) instead of some kind
of iterator or deferred evaluation.

How do you defer evaluating the second and subsequent items if you
> evaluate the final two? Given:
>
> def gen():
> yield 999
> for i in range(100):
> yield random.random()
> yield 999
> yield 999
>
> then
>
> a, ?*b, c, d = gen()


If I can not copy at Python level, I can 'tee' when 'star_pos' is reached.

In my usual practice, the main use that I encounter when see an assignment
to a star variable is as a storage
which is used only if the other vars match some criterion.

With kind regards, -gdg
___
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] Star assignment in iterator way?

2017-11-21 Thread Kirill Balunov
> Your implementation iterates seq multiple times. But iterable unpacking
> syntax works with an arbitrary iterable, and iterates it only once.
>

Oh sorry, I know that my implementation iterates seq multiple times, I only
provide this to show the idea. It can be much optimized at C level. I just
want to understand if it's worth the time and effort.


> Changing the result of iterable unpacking will break existing code that
> depends on the result been a list.
>

Backward compatibility is an important issue, but at the same time it is
the main brake on progress.


> And you already have mentioned a question about mutable sequence.
>
> If these conditions and restrictions suit you, you can use your
> good_star_exp() in your code or share it with others. But the semantic of
> iterable unpacking can't be changed.
>

And how do you look at something like this (deferred star evaluation)?:

a, ?*b, c, d = something_iterable

With kind regards, -gdg
___
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] Star assignment in iterator way?

2017-11-21 Thread Kirill Balunov
Hello. Currently during star assignement the new list is created.
What was the idea to produce new list instead of returning an iterator?
It seems to me that returning an iterator more suited to the spirit of
Python 3.
There are three cases:

1. a,b,c,*d = something_iterable
2. *a,b,c,d = something_iterable
3. a,*b,c,d = something_iterable

The first one is obvious. For the rest two we always need to iterate
through
entire iterable to achieve values for b,c,d (or c,d) binding. But this can
be done
more memory effiecient than currently (may be I'm wrong). And we can
iterate in
space of last three (or two) variables. Some rough (simplified) Python code:

from itertools import islice, chain
from collections import deque

def good_star_exp(signature, seq):

if signature.count('*') > 1:
raise SyntaxError('two starred expressions in assignment')

vrs = signature.split(',')
idx_max = len(vrs) - 1
star_pos, = (i for i,v in enumerate(vrs) if '*' in v)

#First case
if star_pos == idx_max:
head = islice(seq, idx_max)
tail = islice(seq, idx_max, None)
return chain(head, (tail,))

#Second case
elif star_pos == 0:
tail = deque(maxlen=idx_max)
for seq_idx_max, v in enumerate(seq):
tail.append(v)
head = islice(seq, 0, seq_idx_max-(idx_max-1))
return chain([head], tail)

#Third case
else:
head = islice(seq, star_pos)
tail = deque(maxlen=(idx_max-star_pos))
for seq_idx_max, v in enumerate(seq):
tail.append(v)
mid = islice(seq, star_pos, seq_idx_max-(idx_max-2))
return chain(head, [mid], tail)

ls = range(10)
a,b,c,d = good_star_exp('a,b,c,*d', ls)
a,b,c,d = good_star_exp('*a,b,c,d', ls)
a,b,c,d = good_star_exp('a,*b,c,d', ls)

Of course this version has drawbacks (the first that come to mind):
1. Will *b see change if rhs is some muttable sequence?
2. Will *b one way iterator or somethong like range?

But still it seems to me that the "iterator way" has more useful
applications.

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