Re: [Python-ideas] Alternative to PEP 532: delayed evaluation of expressions

2016-11-07 Thread Nick Coghlan
On 6 November 2016 at 23:06, Eric V. Smith  wrote:
> Creating a new thread, instead of hijacking the PEP 532 discussion.
>
> From PEP 532:
>
>> Abstract
>> 
>>
>> Inspired by PEP 335, PEP 505, PEP 531, and the related discussions, this
>> PEP
>> proposes the addition of a new protocol-driven circuit breaking operator
>> to
>> Python that allows the left operand to decide whether or not the
>> expression
>> should short circuit and return a result immediately, or else continue
>> on with evaluation of the right operand::
>>
>> exists(foo) else bar
>> missing(foo) else foo.bar()
>
> Instead of new syntax that only works in this one specific case, I'd prefer
> a more general solution. I accept being "more general" probably seals the
> deal in killing any proposal!

Being more general isn't the goal here: just as with decorators,
context managers, and coroutines, the goal is pattern extraction based
on idioms that people *already use* (both in Python and in other
languages) to make them shorter (and hence easier to recognise), as
well as to give them names (and hence make them easier to learn, teach
and find on the internet).

Consider the conditional expression usage examples in the PEP:

value1 = expr1.field.of.interest if expr1 is not None else None
value2 = expr2["field"]["of"]["interest"] if expr2 is not None else None
value3 = expr3 if expr3 is not None else expr4 if expr4 is not
None else expr5

Which would become the following in the basic form of the PEP:

value1 = missing(expr1) else expr1.field.of.interest
value2 = missing(expr2) else expr2.["field"]["of"]["interest"]
value3 = exists(expr3) else exists(expr4) else expr5

or else the following in the more comprehensive variant that also
allows short-circuiting "if" expressions (and would hence mainly
include "missing()" as the answer to "What does 'not exists()'
return?"):

value1 = expr1.field.of.interest if exists(expr1)
value2 = expr2.["field"]["of"]["interest"] if exists(expr2)
value3 = exists(expr3) else exists(expr4) else expr5

Now, how would those look with a lambda based solution instead?

value1 = eval_if_exists(expr, lambda: expr1.field.of.interest)
value2 = eval_if_exists(expr, lambda: expr2["field"]["of"]["interest"])
value3 = first_existing(expr3, lambda: expr4, lambda: expr5)

This is not an idiom people typically use, and that's not solely due
to them finding the "lambda:" keyword unattractive or function calls
being much slower than inline expressions. We can swap in a Java
inspired "()->" operator to help illustrate that (where "()" indicates
an empty parameter list, and the "->" indicates the LHS is a parameter
list and the RHS is a lambda expression):

value1 = eval_if_exists(expr, ()->expr1.field.of.interest)
value2 = eval_if_exists(expr, ()->expr2["field"]["of"]["interest"])
value3 = first_existing(expr3, ()->expr4, ()->expr5)

Without even getting into the subtle differences between inline
evaluation and nested scopes in Python, the fundamental challenge with
this approach is that it takes something that was previously about
imperative conditional control flow and turns it into a use case for
callback based programming, which requires an understanding of custom
first class functions at the point of *use*, which is conceptually a
much more difficult concept than conditional evaluation.

By contrast, while as with any other protocol you would need to
understand object-oriented programming in order to define your own
circuit breakers, *using* circuit breakers would only require
knowledge of imperative condition control flow, as well as how the
specific circuit breaker being used affects the "if" and "else"
branches.

Regards,
Nick.

-- 
Nick Coghlan   |   [email protected]   |   Brisbane, Australia
___
Python-ideas mailing list
[email protected]
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Alternative to PEP 532: delayed evaluation of expressions

2016-11-07 Thread Nick Coghlan
On 7 November 2016 at 16:19, Nathaniel Smith  wrote:
> On Sun, Nov 6, 2016 at 9:08 PM, C Anthony Risinger  wrote:
>> On Nov 6, 2016 7:32 PM, "Nathaniel Smith"  wrote:
>>>
>>> [...]
>>>
>>> Some other use cases:
>>>
>>> Log some complicated object, but only pay the cost of stringifying the
>>> object if debugging is enabled:
>>>
>>> log.debug!(f"Message: {message_object!r}")
>>
>> Would the log.debug implementation need to fetch the context to evaluate the
>> delayed expression (say by using sys._getframe) or would that be bound? Is a
>> frame necessary or just a (bound?) symbol table? Could a substitute be
>> provided by on evaluation?
>
> There are a lot of ways one could go about it -- I'll leave the
> details to whoever decides to actually write the PEP :-) -- but one
> sufficient solution would be to just pass AST objects. Those are
> convenient (the compiler has just parsed the code anyway), they allow
> the code to be read or modified before use (in case you want to inject
> variables, or convert to SQL as in the PonyORM case, etc.), and if you
> want to evaluate the thunks then you can look up the appropriate
> environment using sys._getframe and friends. Maybe one can do even
> better, but simple ASTs are a reasonable starting point.

PEP 501 suggested taking the machinery that was added to support
f-string interpolation and making it possible to separate the
expression evaluation and string rendering steps:
https://www.python.org/dev/peps/pep-0501/

Cheers,
Nick.

-- 
Nick Coghlan   |   [email protected]   |   Brisbane, Australia
___
Python-ideas mailing list
[email protected]
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Python Documentation

2016-11-07 Thread Steven D'Aprano
Hello Adil, and welcome!

But...

you've converted the ENTIRE Python tutorial AND documentation into PDF 
files, stuck them into zip files with a non-standard file extension 
(.okular) that most people won't be able to deal with, and expect us to 
read the whole thing -- over 200 pages -- looking for your notes?

I applaud your enthusiasm, that is wonderful, but this is not a very 
practical way to communicate. Can't you just tell us your ideas, in an 
email, rather than expect us to unzip two mystery .okular files and read 
through 200+ pages of PDF files?

Thank you for wanting to help.



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


Re: [Python-ideas] Python Documentation

2016-11-07 Thread Todd
On Nov 7, 2016 7:33 AM, "adil gourinda"  wrote:

> Hi
>
>
> I am an amateur of computer programming and my ambition push me to choose
> a good programming language to begin with and I chose "Python" because it
> is an easy language and the documentation is free and complete.
>
>
> For my learning I was based on your "Python Documentation" and one "Python
> Shell" to exercise what i learned.
>
>
> I want to send you my notes ( and the way by which are noted ) and I wish
> you to use them to enhance the documentation. Because I am an amateur I
> don't have a strong base in programming so what is noted I found it easy to
> learn (I think everyone can do the same ) and what is not noted I had
> difficulty in learning it ( with ideas from other peoples we can make it
> easy to learn )
>
>
> Thank you for accepting my offer and I wish I was helpful
>
>
Okular is a great document viewer, but also not a very common one.  Most
people don't have access to it.  So if you want people to be able to read
your notes you are going to need a more universal approach.  Everyone
reading this, by definition, has email, so that is probably the best way.
___
Python-ideas mailing list
[email protected]
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/

Re: [Python-ideas] Civility on this mailing list

2016-11-07 Thread Brett Cannon
I wanted to give people an update on civility on this mailing list. First,
one person has received a Code of Conduct violation warning and another has
received a general warning that their conduct has worn out any leniency
about future conduct that we generally try to give people (think of it as a
pre-warning warning). On this list you get one warning for your first CoC
violation, and on the second you receive a one year banishment. The admins
do take into consideration people's behaviour after a warning and how long
it has been since the warning so a single warning won't hover over you
until the end of time (i.e. there's a decay factor on warnings, but it's at
the discretion of the admins). IOW I want everyone to realize we do take
how people act on this list seriously (and for people who don't know or
remember, we do already have one permanent banishment on this list).

Two, taking something off-list does not get you out from underneath the
CoC. If you decide to only reply to someone who posts to this list while
leaving the list out of it you are still expected to act as if you posted
publicly. We don't care if the discussion was private because you chose to
stem your bad behaviour based on something you read on this list. If you
can't abide by the CoC when dealing with content on this list then you will
simply lose your privileges to be on this list and access its content
directly.

Three, we have seen at least one instance where someone claimed that what
they said was not their fault because they were quoting someone. That's
patently false and anything you say is your responsibility. If you don't
quote someone then the list would never had known, and thus you reiterating
what someone said for this list makes you responsible for it. In philosophy
it's called *intentionality:* since you intended for that information to
reach the list then you are held responsible for it no matter who
originally said it (we are not journalists so there's no real need to quote
someone just to report it). If you really need to report what someone said
that is going to be hurtful you can summarize it and leave the hurtful part
out.

Otherwise I just wanted to thank the people who came forward after this
initial email saying that they have found the mailing list in general
pleasant to be on (notwithstanding the incidents leading to the warnings).
I also want to thank the people who did step forward to file their
complaints as I know that's a very difficult thing to do.

On Mon, 17 Oct 2016 at 11:29 Brett Cannon  wrote:

>
> Based on some emails I read in the " unpacking generalisations for list
> comprehension", I feel like I need to address this entire list about its
> general behaviour.
>
> If you don't follow me on Twitter you may not be aware that I am taking
> the entire month of October off from volunteering any personal time on
> Python for my personal well-being (this reply is being done on work time
> for instance). This stems from my wife pointing out that I had been rather
> stressed in July and August outside of work in relation to my Python
> volunteering (having your weekends ruined is never fun). That stress
> stemmed primarily from two rather bad interactions I had to contend with on
> the issue track in July and August ... and this mailing list.
>
> When I have talked to people about this mailing list it's often referred
> to by others as the "wild west" of Python development discussions (if
> you're not familiar with US culture, that turn of phrase basically means
> "anything goes"). To me that is not a compliment. When I created this list
> with Titus the goal was to provide a safe place where people could bring up
> ideas for Python where people could quickly provide basic feedback so
> people could know whether there was any chance that python-dev would
> consider the proposal. This was meant to be a win for proposers by not
> feeling like they were wasting python-dev's time and a win for python-dev
> by keeping that list focused on the development of Python and not fielding
> every idea that people want to propose.
>
> And while this list has definitely helped with the cognitive load on
> python-dev, it has not always provided a safe place for people to express
> ideas. I have seen people completely dismiss people's expertise and
> opinion. There has been name calling and yelling at people (which is always
> unnecessary). There have been threads that have completely derailed itself
> and gone entirely off-topic. IOW I would not hold this mailing list up as
> an example of the general discourse that I experience elsewhere within the
> community.
>
> Now I realize that we are all human beings coming from different cultural
> backgrounds and lives. We all have bad days and may not take the time to
> stop and think about what we are typing before sending it, leading to
> emails that are worded in a way that can be hurtful to others. It's also
> easy to forget that various cultures views things differently an

Re: [Python-ideas] Method signature syntactic sugar (especially for dunder methods)

2016-11-07 Thread Nathan Dunn
> * __add__ is only part of the addition protocol, there is also
> __radd__ and __iadd__

__iadd__ could be represented as def self += value:.

Reflected binary operators do pose a problem. A possible solution would be
to give self special meaning in this context, so def self + other: would
correspond to __add__ and def other + self: to __radd__. But of course,
this would be a more fundamental change to the language than just syntactic
sugar.


> * likewise, there is not a one-to-one correspondence between the
> bool() builtin and the __bool__() special method (there are other ways
> to support bool(), like defining __len__() on a container)

That is a fair point, but I think this would be only a slight point of
confusion. I believe for the most part other builtins such as __abs__,
__len__, etc. do have a one-to-one correspondence so this syntax would make
sense in almost all situations.

But while were on the topic, I will take this opportunity to note that all
the methods to support builtins suffer from the same ambiguity I alluded to
earlier with bool(self). One solution could be to use a @builtin decorator
or something to that effect, but that would more or less defeat the purpose
of cleaner, more intuitive syntax. It may be that there is no viable
alternative for the builtin function dunder methods.


> * the mapping protocol covers more than just __getitem__

__setitem__(self, key, value)   could bedef self[key] = value
likewise
__delitem__(self, key)  def del self[key]:
__iter__(self)  iter(self)
__len__(self)   len(self)


> (and you also
> need to decide if you're implementing a mapping, sequence, or
> multi-dimensional array)

Could you speak more about this? It doesn't seem to me that this would
affect the method signatures since it is up to the implementer to interpret
the semantic meaning of the keys.


> it would break the current symmetry between between name binding
> in def statements and target binding in assignment statements

> With the proposed change, we'd face the
> problem that the following would both be legal, but meant very
> different things:
>
> cls.mymethod = lambda self: print(self)
> def cls.mymethod(self): print(self)
>
> The former is already legal and assigns the given lambda function as a
> method on the existing class, `cls`
>
> The latter currently throws SyntaxError.
>
> With the proposed change, rather than throwing SyntaxError as it does
> now, the latter would instead be equivalent to:
>
> def mymethod(cls, self): print(self)
>
> which would be a very surprising difference in behaviour.

I will admit that there is potential for confusion here as this

class Formatter(object):
def Formatter.displayDefault(obj):
print('[{}]'.format(obj))

is rather suggestive of a static method, but I don't think the confusion
arises because the syntax breaks the symmetry you reference. The self-dot
syntax *is* meant to elicit target binding in assignment statements. Just
as self.mymethod = lambda p1, p2: p1+p2 indicates that an instance of the
class has a callable with two parameters bound to its mymethod attribute,
so too does the statement def self.mymethod(p1, p2):. So I don't think this
inherently breaks any symmetry.

It is specifically in the case that the identifier is the same as the class
name that this leads to surprising behavior, but there is already a similar
risk of confusion any time the name of a class is used as an identifier
within the class body. Perhaps my proposed syntax does increase this risk
since the identifier doesn't look like a parameter or a variable, but
hopefully the self form of this syntax would be so commonplace that seeing
anything else before the dot would throw up a red flag.


Thanks,
-Nate
___
Python-ideas mailing list
[email protected]
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/

Re: [Python-ideas] Method signature syntactic sugar (especially for dunder methods)

2016-11-07 Thread Stephen J. Turnbull
Nathan Dunn writes:

 > > * the mapping protocol covers more than just __getitem__
 > 
 > __setitem__(self, key, value)   could bedef self[key] = value
 > likewise
 > __delitem__(self, key)  def del self[key]:
 > __iter__(self)  iter(self)
 > __len__(self)   len(self)

The template used by last two (BTW, shouldn't they be "def iter(self)"
and "def len(self)"?) seems like a really bad idea to me.  This would
imply that any class that defines such methods in some arbitrary
fashion will appear to participate in the corresponding protocol
although it doesn't.  That seems likely to result in bugs, that might
be hard to diagnose (haven't thought about how hard that might be,
though).  It would require the programmer to know about all such
protocols when designing a public API, while with the dunder
convention, you only need to find out whether the dunders you want to
use for your new protocol are already in use somewhere, and
programmers who aren't designing protocols don't need to know about
them at all.  It would also require a modification to the compiler for
every new protocol.

I personally don't see that the other syntaxes are helpful, either,
but that's a matter of opinion and I'd be interested to hear about
experience with teaching languages that implement such "method
definitions look like invocation syntax".

Regards,

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