[Python-ideas] Re: @classproperty, @abc.abstractclasspropery, etc.

2020-12-15 Thread Paolo Lammens
Old thread, pity it didn't get any traction. I second this. 

Except perhaps the @staticproperty: since a static (method|property) is bound 
to neither the instance nor the class, it doesn't seem 
straightforward/intuitive as to where the value set in the setter should go. 
E.g. if it sets an attribute in the class that defined the @staticproperty, 
then that class' attribute could be modified through a subclass or a subclass' 
instance by doing `obj.prop = value` which seems like too much of "spooky 
action at a distance` (since a static attribute is by definition bound to the 
class and only the identical class, not any subclasses or instances).
___
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/CAXGNUCHCNBLCZM4IVTMCDU6DFYZFDCW/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Using explicit parenthesization to convey aspects of semantic meaning?

2020-12-15 Thread Marco Sulla
On Tue, 15 Dec 2020 at 17:41, Chris Angelico  wrote:
> I learned BOMDAS - Brackets, O (varies in expansion but always minor
> things you don't often see), Multiplication, Division, Addition,
> Subtraction. For some reason it's also written BODMAS, which has the
> exact same meaning (since multiplication and division have the same
> precedence) but is harder to pronounce. PEMDAS uses "parentheses"
> instead of "brackets" (so it's probably an American English vs British
> English thing), and "exponentiation" in place of the first vowel.

This is the most interesting thing in the whole discussion, IMHO.
___
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/EBTHAXKGD3VZ3VSZIBOULATR23CKUXGI/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Using explicit parenthesization to convey aspects of semantic meaning?

2020-12-15 Thread Steven D'Aprano
On Tue, Dec 15, 2020 at 04:15:52PM +, David Mertz wrote:

> It feels like a chimp trying to pantomime a philosopher, really.  As
> someone with a doctorate in philosophy, I feel triggered :-).

Quoting "A Fish Called Wanda":

Otto: Apes don't read philosophy.
Wanda: Yes they do, Otto, they just don't understand it.

Although I don't think that Paul is a Nietzsche-quoting ex-CIA hired 
killer. At least I hope not.

In fairness, Paul has a lot of interesting ideas, even if they don't 
always pan out. But this thread is an excellent example of how *not* to 
engage and persuade an audience:


- long and rambling, slow to get to the point;

- expecting the readers to make the same "Aha!" moment you did when
  you could just explicitly state your observation;

- patronising statements that your readers are just a step away from 
  getting the right answer, but will they make it?

- repeated hints that you have seen the correct answer and reached 
  enlightenment, without telling the reader what the answer is;

- comparisons and analogies that don't work;
  (under Python semantics, the closest analogy to `(obj.method)()`
  is not `a+(b+c)` but `(a+b)+c`)


Paul, if you are reading this, you are coming across as neuro-atypical. 
If that is the case, trust me on this, the strategy you are taking in 
this thread is very unsuccessful as a persuasive and/or teaching tool.

Under existing Python semantics, round brackets (parentheses) have a few 
different meanings, but the relevant one as far as I can tell is 
grouping, which changes the order that operations are performed.

In expressions, I don't think that there are any cases where brackets 
change the semantics of operations: `(b + c)` remains the plus operator 
even with the brackets, it just changes the order of operation relative 
to any surrounding expression.

The only counter-example I can think of where brackets changed the 
semantics of a statement was the old Python 2 `except ...` statement:

except A, B, C, D:
block

except (A, B, C, D):
block

If I recall correctly, the first catches exceptions A, B and C, and 
binds the exception to D; the second catches exceptions A, B, C and D 
and doesn't bind to anything.

As you can imagine, this was an extremely error-prone and surprising 
"Gotcha".

In principle, we could give `(obj.method)()` a distinct meaning to the 
unbracketed form. But such a distinction would be surprising, it would 
clash with grouping:

(obj.method or fallback_function)()

and I have no idea what distinct meaning you want to give it, or why. If 
you are serious about continuing this thread, please get to the point of 
*what* change in semantics you want to give the bracketed form and *why* 
you think it would be useful.



-- 
Steve
___
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/B7FFM2NZO6IERCNXOER5ULVKI7BERXLR/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Function for fetching what months between two dates

2020-12-15 Thread Marco Sulla
On Tue, 15 Dec 2020 at 15:32, Steven D'Aprano  wrote:
>
> On Tue, Dec 15, 2020 at 03:08:51AM -, qaidjoharbarbh...@gmail.com wrote:
> > Hello,
> >
> > Greetings!
> >
> > I have the following idea of adding a function in Lib/datetime.py
> > which when called with the datetime.date object returns the months
> > between the object datetime.date and the object datetime.date passed
> > as the date_to argument in function.
>
> What is this function used for?
>
> I see it returns a list of (year, month_number) tuples. Once I have
> collected those (year, month) tuples, what do I do with them?

It will be more useful if the returned values are datetime.date
objects. The library arrow has arrow.Arrow.range("month", startdate,
enddate)
___
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/X55X3DWMYPV6NQYOBI6PL7PRSSNSLWV2/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Using explicit parenthesization to convey aspects of semantic meaning?

2020-12-15 Thread Christopher Barker
I'm going to answer the original question, even though I don't quite
understand it:

> Using explicit parenthesization to convey aspects of semantic meaning?

Absolutely not -- for no other reason that it would break potentially a LOT
of code. If there IS some new useful semantics that could be conveyed with
a set of brackets, we're going to need to use another character.

I still don't get what meaning might be called for, but even commonly used
brackets, like [] or {} would be better because I don't think they can be
currently used anywhere in which they have literally no meaning, like ()
does.

-CHB


On Tue, Dec 15, 2020 at 8:38 AM Chris Angelico  wrote:

> On Wed, Dec 16, 2020 at 3:16 AM David Mertz  wrote:
> >
> > On Tue, Dec 15, 2020 at 11:22 AM Chris Angelico 
> wrote:
> >> I'm pretty sure most of us learned *in grade school* about BOMDAS or
> >> BODMAS or PEMDAS or whatever mnemonic you pick.
> >
> > I don't think I ever learned such acronyms! I mean, yes I learned about
> order of operations in grade school.  But never with a mnemonic.
>
> I learned BOMDAS - Brackets, O (varies in expansion but always minor
> things you don't often see), Multiplication, Division, Addition,
> Subtraction. For some reason it's also written BODMAS, which has the
> exact same meaning (since multiplication and division have the same
> precedence) but is harder to pronounce. PEMDAS uses "parentheses"
> instead of "brackets" (so it's probably an American English vs British
> English thing), and "exponentiation" in place of the first vowel.
>
> Whichever way you learned it, though, you probably learned a few
> quirks of algebraic notation that don't really apply to programming
> (such as the fraction bar), but for the most part, you'd have learned
> the exact model that most expression evaluators use.
>
> ("Most" because, as always, there are exceptions, but it's a good
> default to start with.)
>
> 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/7YMTCRDYK5KX3UA26AIQFC6Z5A4CIUIL/
> Code of Conduct: http://python.org/psf/codeofconduct/
>


-- 
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/EDAMT7QD4LXWNH3TTRDXLI7SUSSW6SHS/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Using explicit parenthesization to convey aspects of semantic meaning?

2020-12-15 Thread Chris Angelico
On Wed, Dec 16, 2020 at 3:16 AM David Mertz  wrote:
>
> On Tue, Dec 15, 2020 at 11:22 AM Chris Angelico  wrote:
>> I'm pretty sure most of us learned *in grade school* about BOMDAS or
>> BODMAS or PEMDAS or whatever mnemonic you pick.
>
> I don't think I ever learned such acronyms! I mean, yes I learned about order 
> of operations in grade school.  But never with a mnemonic.

I learned BOMDAS - Brackets, O (varies in expansion but always minor
things you don't often see), Multiplication, Division, Addition,
Subtraction. For some reason it's also written BODMAS, which has the
exact same meaning (since multiplication and division have the same
precedence) but is harder to pronounce. PEMDAS uses "parentheses"
instead of "brackets" (so it's probably an American English vs British
English thing), and "exponentiation" in place of the first vowel.

Whichever way you learned it, though, you probably learned a few
quirks of algebraic notation that don't really apply to programming
(such as the fraction bar), but for the most part, you'd have learned
the exact model that most expression evaluators use.

("Most" because, as always, there are exceptions, but it's a good
default to start with.)

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/7YMTCRDYK5KX3UA26AIQFC6Z5A4CIUIL/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Using explicit parenthesization to convey aspects of semantic meaning?

2020-12-15 Thread David Mertz
On Tue, Dec 15, 2020 at 11:22 AM Chris Angelico  wrote:

> Seriously, are you actually unaware of this fundamental, or are you
> playing dumb to try to make a point? I'm still trying to figure out
> your point here.


I've already put him in my killfile, but probably unwisely, I still see the
follow-ups by you and other people I respect and enjoy reading discussion
from.

It feels like a chimp trying to pantomime a philosopher, really.  As
someone with a doctorate in philosophy, I feel triggered :-).


> I'm pretty sure most of us learned *in grade school* about BOMDAS or
> BODMAS or PEMDAS or whatever mnemonic you pick.


I don't think I ever learned such acronyms! I mean, yes I learned about
order of operations in grade school.  But never with a mnemonic.

-- 
The dead increasingly dominate and strangle both the living and the
not-yet born.  Vampiric capital and undead corporate persons abuse
the lives and control the thoughts of homo faber. Ideas, once born,
become abortifacients against new conceptions.
___
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/BG46FIBVAQWE22N4FTOOYFKG6LE4DMCA/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Conditional with statements

2020-12-15 Thread Jonathan Crall
Thanks for the link, the rationale for rejection seems reasonable.

On Fri, Dec 11, 2020 at 8:19 PM Chris Angelico  wrote:

> On Sat, Dec 12, 2020 at 11:42 AM Jonathan Crall 
> wrote:
> >
> > I'm not sure if this has been asked / suggested before.
> >
> > I'm wondering if there is any interest in conditional or loop-based
> `with` statements. I think it could be done without a syntax change.
> >
> > ### Napkin proposal
> >
> > Context managers could define `__if__` or `__for__`, and if those dunder
> methods were defined, then the `with` statement would either behave like a
> conditional or a loop.
> >
> > If `__if__` was defined then
> >
> > ```
> > with Ctx():
> > print('hi')
> > ```
> >
> > would only print `hi` if `__if__` returned True. This doesn't require a
> syntax change.
>
> This part has been proposed before:
> https://www.python.org/dev/peps/pep-0377/
>
>
> > The `__for__` variant would likely need a minor syntax change.
> >
> > ```
> > with item in Ctx():
> > print(item)
> > ```
> >
> > The `__for__` method is a generator that generates arguments of a loop.
> The item will be printed as many times as there are items generated by
> `__for__`.
> >
>
> Not sure that this one has, but it's basically just a context manager
> and a for loop, so I'm not really sure how much you'd gain over just
> using the two constructs independently, given that there'd then be
> massive confusion over "when should I use 'with item in thing' and
> when should I use 'for item in thing'?".
>
> For many use cases, it may be best to write the body as a function,
> which can then be called more than once. You can decorate a function
> in order to do whatever you like, and the return value from the
> decorator could be whatever stats you want to provide (there's no rule
> says that a function decorator has to return a 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/Q7WZ7FY3ZSINGMHPI6ULQA6L5MJZ6HL3/
> Code of Conduct: http://python.org/psf/codeofconduct/
>


-- 
-Dr. Jon Crall (him)
___
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/3SGCC2KR6CL2IUON7BENQBTNK5MWDJYO/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Function for fetching what months between two dates

2020-12-15 Thread Steven D'Aprano
On Tue, Dec 15, 2020 at 03:08:51AM -, qaidjoharbarbh...@gmail.com wrote:
> Hello,
> 
> Greetings!
> 
> I have the following idea of adding a function in Lib/datetime.py 
> which when called with the datetime.date object returns the months 
> between the object datetime.date and the object datetime.date passed 
> as the date_to argument in function.

What is this function used for?

I see it returns a list of (year, month_number) tuples. Once I have 
collected those (year, month) tuples, what do I do with them?

-- 
Steve
___
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/66M3XKO2AQFIKFYKYTDYWMIVNYVSOEDH/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Using explicit parenthesization to convey aspects of semantic meaning?

2020-12-15 Thread Steven D'Aprano
On Tue, Dec 15, 2020 at 02:24:48PM +0300, Paul Sokolovsky wrote:

> As I showed right in my first mail, in "a.b()",
> "a.b" doesn't get evaluated at all (since CPython3.7).

`a.b` still has to be looked up, even with the new fast LOAD_METHOD 
byte-code. The difference is that it may be able to avoid instantiating 
a MethodType object, since that would be immediately garbage-collected
once the function object it wraps is called.

The lookup still has to take place:


```
>>> class Demo:
... def __getattribute__(self, name):
... if name == 'method':
... print("looked up method")
... return super().__getattribute__(name)
... def method(self):
... print("called method")
... 
>>> obj = Demo()
>>> obj.method()
looked up method
called method
```


If the above example doesn't convince you that you are mistaken, how 
about this?


```
>>> class Demo2:
... def __getattr__(self, name):
... print("evaluating obj.%s" % name)
... return lambda: print("calling method")
... 
>>> obj = Demo2()
>>> obj.method()
evaluating obj.method
calling method
```


In this second demonstration, obj.method *doesn't even exist* ahead of 
time and has to be created dynamically on attribute lookup, before it 
can be called.


-- 
Steve
___
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/O4SKHDK67XZGSW7CPBOXH5UH4H4XFIU2/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Function for fetching what months between two dates

2020-12-15 Thread Valentin Berlier
Hi. Bundling this into the standard library doesn't seem to provide any real 
advantage over defining it as a free-standing utility function in your own 
code. 

And if it's in your own code you can easily tweak it if you need to :)
___
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/26U3IAZ4IBNL7KKKCV7O5Q6KOSEJZLXQ/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Function for fetching what months between two dates

2020-12-15 Thread qaidjoharbarbhaya
Hello,

Greetings!

I have the following idea of adding a function in Lib/datetime.py which when 
called with the datetime.date object returns the months between the object 
datetime.date and the object datetime.date passed as the date_to argument in 
function. Herewith is the attached link to the commit:

https://github.com/python/cpython/pull/23713/commits/2941fe88bd9c0c1a5c8ddd4f0458d52d27d7ec57

Kind regards,
___
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/62J4ZA4ZSHDYX2FT2SOXL5FXF4A2QSKV/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Using explicit parenthesization to convey aspects of semantic meaning?

2020-12-15 Thread Steven D'Aprano
On Tue, Dec 15, 2020 at 01:16:21PM +0300, Paul Sokolovsky wrote:

> You're now just a step away from the "right answer". Will you make it?
> I did.

Sorry Paul, but you didn't.

You fooled yourself by comparing chalk and cheese, and imagining that 
because you can eat cheese (change the order of operation by using 
parens, which is a semantic difference), you can also eat chalk (imagine 
a semantic difference between `obj.method` and `(obj.method)`).

Your mistake was comparing `(obj.method)()` with `a + (b + c)` when you 
should have compared it to `(a + b) + c`. Not every source code 
difference has a semantic difference:

x = 1
x=1
x  =  1
x = 1 or None
x = (1)

all mean the same thing. Putting parens around the final (1) changes 
nothing.

Let's get away from using round brackets for function call, because it 
clashes with the use of round brackets for grouping. All we really need 
is a *postfix unary operator*.

x()  # the brackets are "postfix unary zero-argument function call"

Let's use the factorial operator, "bang" `!` instead.

obj.attr!

has to be evaluated from left to right under Python's rules. You can't 
apply the factorial operator until you have looked up attr on obj, and 
you cannot lookup attr until you have looked up obj.

So the only possible order of operations is left to right. This is not 
meaningful:

# attr factorial first, then lookup obj, then the dot lookup
obj.(attr!)  

but while this is meaningful, the order of operations is unchanged:

# lookup obj first, then dot lookup attr, then factorial
(obj.attr)!  

Replace the factorial postfix operator with the `()` call operator, and 
the logic remains the same.


-- 
Steve
___
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/MYH6ZCW3RJYEUSTHYXHTLTBX3M72OROV/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Using explicit parenthesization to convey aspects of semantic meaning?

2020-12-15 Thread Steven D'Aprano
On Tue, Dec 15, 2020 at 12:49:26PM +0300, Paul Sokolovsky wrote:

> > Are you asking for a semantic difference (the two statements do 
> > something different) or an implementation difference (the two
> > statements do the same thing in slightly different ways)?
> 
> I'm asking for semantic difference, it's even in the post title.

So far all you have talked about is implementation differences such as 
whether intermediate results are put on a stack or not, and differences 
in byte-code from one version of Python to another.


> But
> the semantic difference in not in "what two statements do", but in
> "what two statements mean".

Right, so why are you wasting time talking about what they *do*, i.e. 
whether they put intermediate results on the stack, or in a register?


> Difference in "doing" is entailed by
> difference in "meaning". And there may be no difference in "doing",
> but still difference in "meaning", as the original "1+2+3" vs
> "1+(2+3)" example was intended to show. 

In the case of ints, there is no difference in meaning. For integers, 
addition is associative, and the order does not matter.

So here you *say* you are talking about semantics, but you are actually 
talking about implementation. With integers, the semantics of all of 
these are precisely the same:

1 + 2 + 3
(1 + 2) + 3
1 + (2 + 3)
3 + (2 + 1)

etc. The order in which you *do* the additions makes no difference to 
the semantics.



> > Implementation differences are fairly boring (to me): 
> 
> Right. How implementation points are brought into the discussion is to
> show the issue. As mentioned above, the actual progression is the
> opposite: first there's semantic meaning, then it's implemented. So,
> what's the semantic meaning of "a.b()" that it gets compiled with
> LOAD_METHOD bytecode?


- Look up the name "a" in the local namespace;

- look up the attribute name "b" according to a's MRO, including
  the use of the descriptor protocol, slots, etc;

- call whatever object gets returned.


[...]
> > For what it is worth, Python 1.5 generates the exact same byte code
> > for both expressions; so does Python 3.9. However the byte code for
> > 1.5 and for 3.9 are different.
> 
> Right, and the question is what semantic (not implementational!) shift
> happened in 3.7 (that's the point when it started to be compiled
> differently).

Absolutely none.

There was a semantic shift, but it was back in Python 2.2 when new style 
classes and the descriptor protocol were introduced.



> > However, the semantics of the two expressions are more or less
> > identical in all versions of Python, regardless of the byte-code used.
> 
> That's what I'd like to put under scrutiny.


Okay, the major semantic differences include:

- in Python 1.5, attribute name look-ups call `__getattr__` if the
  name is not found in the object's MRO;

- in Python 3.9, attribute name look-ups first call `__getattribute__`
  before checking the MRO and `__getattr__`;

- the MRO is calculated differently between 1.5 and 3.9;

- in 3.9, the descriptor protocol may be invoked;

- descriptors and the descriptor protocol did not exist in 1.5;

- there are a few differences in the possible types of `obj.meth`
  between the versions, e.g. Python 1.5 had both bound and unbound
  instance methods, while Python 3.9 does not.

There may be other differences, but those are the most important 
ones I can remember.


> > (I say "more or less" because there may be subtle differences between 
> > versions, relating to the descriptor protocol, or lack there of, old
> > and new style classes, attribute lookup, and handling of unbound
> > methods.)
> 
> Right, and exactly those "subtle differences" is what I'd like to
> discuss.

See above.


> The level of abstraction I'm talking about is where you look not just
> at "`(expression)` vs `expression`" but at:
> 
> expression  expression   vs   expression  (expression)

That is an extremely straight-forward change in execution order. Whether 
that makes any semantic difference depends on whether the operations 
involved are associative or not.


> Where  is an arbitrary operator. As we already concluded, those do
> have difference, even considering such a simple operator as "+".
> 
> So... what can we say about the difference between a.b() and (a.b)()
> then?

There isn't one.

Even though the `.` (dot) and `x()` (call) are not actual operators, we 
can treat them as pseudo-operators. According to Python's precedence 
rules, the first expression `a.b()` is the same as:

- lookup name a
- lookup attribute b
- call

and the second `(a.b)()` is:

- lookup name a
- lookup attribute b
- call

which is precisely the same. The parens make no semantic difference.


Paul, I think you have fooled yourself by comparing two *different* 
situations. You compare a use of parens where they change the order of 
operations:

a + b + c
a + (b + c)

but you should be looking at this:

(a + b) + c  # parens are redundant a

[Python-ideas] Re: Using explicit parenthesization to convey aspects of semantic meaning?

2020-12-15 Thread Greg Ewing

On 16/12/20 12:24 am, Paul Sokolovsky wrote:


That's good answer, thanks. But... it doesn't correspond to the
implementation reality.


Why are we talking about implementation? You said you wanted
to keep to the conceptual level. At that level, there is NO
difference at all.

--
Greg
___
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/E6LTQGEKPDOLSSMEQBGUTYNEOECFCG3M/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Using explicit parenthesization to convey aspects of semantic meaning?

2020-12-15 Thread Greg Ewing

On 15/12/20 11:28 pm, Paul Sokolovsky wrote:

that table is not complete. For example, "," (comma) is a
(context-dependent) operator in Python, yet that table doesn't have
explicit entry for it. Unary "*" and "**" are other context-dependent
operators. (Unary "@" too.)


Those things aren't considered to be operators. The term
"operator" has a fairly specific meaning in Python -- it's
not just "any punctuation mark".

It's true that the operator precedence table won't tell
you the precedence of everything in Python -- you need to
consult the grammar for the rest.

--
Greg
___
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/GW3UFBDK6FBOKESIZ4KWJDUXUXCEMKH7/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Using explicit parenthesization to convey aspects of semantic meaning?

2020-12-15 Thread Greg Ewing

On 15/12/20 11:16 pm, Paul Sokolovsky wrote:

I would suggest us rising up in abstraction level a bit, and
think not in terms of "intermediate variables" but in terms of
"intermediate storage locations".


The fact that it's a *named* intermediate storage location is
important, because it means the programmer can see it, and will
expect it to hold a bound method. So the compiler can't optimise
away the bound method creation in that case.

Well, it could if it could prove that the intermediate value isn't
used for anything else subsequently, but that seems like a very
rare thing for anyone to do. Why bother naming it if you're
only going to call it once and then throw it away? So the
compiler only bothers with the most common case.


You're now just a step away from the "right answer". Will you make it?


I'll be interested to find out what you think the "right" answer
is. Or what the actual question is, for that matter -- that's still
not entirely clear.

--
Greg
___
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/DEZ5SY2JP2LS6KIYGHB2YN4L26XNRSHR/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Using explicit parenthesization to convey aspects of semantic meaning?

2020-12-15 Thread Paul Sokolovsky
Hello,

On Tue, 15 Dec 2020 23:37:59 +1300
Greg Ewing  wrote:

> On 15/12/20 10:04 pm, Paul Sokolovsky wrote:
> > Example 1:
> > 
> > a + b + c   vs   a + (b + c)
> > 
> > Question 1:
> > Do you agree that there's a clear difference between left and right
> > expression?  
> 
> Yes, because the default order of operations in Python is defined
> so that a + b + c is the same as (a + b) + c.
> 
> > Example 2:
> > 
> > a.b()   vs   (a.b)()
> > 
> > Question 2:
> > Do you agree that there's a *similar* difference here as in Example
> > 1?  
> 
> No, because the default order of operations here already has
> a.b evaluated before making the call, so adding the parentheses
> changes nothing.

That's good answer, thanks. But... it doesn't correspond to the
implementation reality. As I showed right in my first mail, in "a.b()",
"a.b" doesn't get evaluated at all (since CPython3.7). Instead,
something completely different gets evaluated. Ok, not "completely", but
"sufficiently" different. We can continue to beat on the side of "it's
only a bytecode optimization, there's total disconnection between what
happens in the compiled bytecode and the language syntax". But what if
not?


> -- 
> Greg


-- 
Best regards,
 Paul  mailto:pmis...@gmail.com
___
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/CJIZHSV35NIYYOM74VWXK35NUE6ELKUV/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Using explicit parenthesization to convey aspects of semantic meaning?

2020-12-15 Thread Chris Angelico
On Tue, Dec 15, 2020 at 9:22 PM Paul Sokolovsky  wrote:
> On Tue, 15 Dec 2020 20:17:37 +1100
> Chris Angelico  wrote:
>
> > On Tue, Dec 15, 2020 at 8:04 PM Paul Sokolovsky 
> > wrote:
> > > So, let's try simple yes/no questions:
> > >
> > > Example 1:
> > >
> > > a + b + c   vs   a + (b + c)
> > >
> > > Question 1:
> > > Do you agree that there's a clear difference between left and right
> > > expression? Yes/no.
> >
> > Yes, there is a difference.
> >
> > > Example 2:
> > >
> > > a.b()   vs   (a.b)()
> > >
> > > Question 2:
> > > Do you agree that there's a *similar* difference here as in Example
> > > 1? Yes/no.
> >
> > No, there is no difference.
> >
> > >
> > > Then of course depending on the outcome of the last question, there
> > > would be further questions. Specifically:
> > >
> > > If yes: How to put a solid formal basis behind the difference in
> > > Example 2 (because so far we're just riding on the similarity with
> > > Example 1). And how to explain it to wider audience?
> > >
> >
> > Uhh, it's called precedence and associativity? You know that (a + b +
> > c) is equivalent to ((a + b) + c), not to (a + (b + c)). Is that
> > formal enough?
>
> Yes. But you answered "no" to the Example 2. What makes you think that
> (a + b + c) is not equivalent to (a + (b + c)), but (a.b()) is
> equivalent to ((a.b)()), that's what I'm asking.
>

Precedence and associativity? Since the two operators have the same
precedence (in this case it's the same operator twice), order of
evaluation is defined by its left-to-right associativity.

Seriously, are you actually unaware of this fundamental, or are you
playing dumb to try to make a point? I'm still trying to figure out
your point here. The parentheses in one example are changing order of
evaluation. In the other, they're not. I do not understand why this is
even a question.

I'm pretty sure most of us learned *in grade school* about BOMDAS or
BODMAS or PEMDAS or whatever mnemonic you pick. Or maybe you have to
wait till high school to learn that exponentiation is right-to-left
associative. Either way, it's not new knowledge to most programmers.

I'm done arguing, unless you actually come up with a real argument.

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/TIYWNVD2ZKQIZTDYPVAMGNLK4TXV5HX3/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Using explicit parenthesization to convey aspects of semantic meaning?

2020-12-15 Thread Greg Ewing

On 15/12/20 10:49 pm, Paul Sokolovsky wrote:

the question is what semantic (not implementational!) shift
happened in 3.7 (that's the point when it started to be compiled
differently).


There was no semantic shift. The change had *nothing* to do
with semantics. It was *purely* an optimisation.

I'm not sure what we can say to make this any clearer.


I'm suggesting that there's difference between:

expression  expression   vs   expression  (expression)

Which is hopefully hard to disagree with.


There is *sometimes* a difference, depending on exactly
what the two expressions are, and what  is.


Then I'm asking, how consistent are we with understanding and
appreciating that difference, taking the example of:

a.b()   vs   (a.b)()


There is no inconsistency. Note also that:

1 + 2 * 3   is the same as   1 + (2 * 3)

because the default order of operations already has *
evaluated before +. The same kind of thing is happening
with a.b() vs (a.b)().

--
Greg
___
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/6GH7T3JJXMYT6QFW26IE4UFQTY5Z6XWV/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Using explicit parenthesization to convey aspects of semantic meaning?

2020-12-15 Thread Greg Ewing

On 15/12/20 10:04 pm, Paul Sokolovsky wrote:

Example 1:

a + b + c   vs   a + (b + c)

Question 1:
Do you agree that there's a clear difference between left and right
expression?


Yes, because the default order of operations in Python is defined
so that a + b + c is the same as (a + b) + c.


Example 2:

a.b()   vs   (a.b)()

Question 2:
Do you agree that there's a *similar* difference here as in Example 1?


No, because the default order of operations here already has
a.b evaluated before making the call, so adding the parentheses
changes nothing.

--
Greg
___
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/BLVN4Y464MZKICZDWFY4MX7BVMATWKJN/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Using explicit parenthesization to convey aspects of semantic meaning?

2020-12-15 Thread Jeff Allen

On 13/12/2020 22:09, Paul Sokolovsky wrote:

Thanks for hanging with me so far, we're getting to the crux of the
question:

Do you think there can be difference between the following two
expressions:

obj.meth()
(obj.meth)()

?


No. The value of an expression in parentheses is the value of the 
expression inside the parentheses, and in this case does not affect the 
order of evaluation.



python3.6 -m dis meth_call.py
python3.7 -m dis meth_call.py

Then, to try to explain the difference at the suitable level of
abstraction. If that doesn't provide enough differentiation, it might
be helpful to add the 3rd line:

t = obj.meth; t()

And run all 3 lines thru CPython3.7, and see if the pattern is now
visible, and a distortion in the pattern too.

What would be the explanation for all that?


The explanation is an optimisation introduced in 3.7 that the use of an 
intermediate variable prevents. The compiler applies it when it can see 
the only use of the attribute is an immediately following call. Having 
burrowed into the implementation, I'm certain it tries hard to be 
indistinguishable from the unoptimised implementation (and succeeds I 
think), even to the point of failing in the same way when that is the 
programmed outcome.


LOAD_METHOD goes far enough down the execution of LOAD_ATTR to be sure 
the bound object would be a types.MethodType containing a pair of 
pointers that CALL_FUNCTION would have to unpack, and pushes the 
pointers on the stack instead of creating the new object. Otherwise it 
completes LOAD_ATTR and pushes a bound object and a NULL, which is what 
CALL_METHOD uses to decide which case it is dealing with.


The meaning of the code is what it does detectably in Python, not what 
it compiles to (for some definition of "detectably" that doesn't include 
disassembly).


Jeff Allen

___
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/GUMGCGGBUR73DKEWOOOYLMLO7QBQVLQZ/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Using explicit parenthesization to convey aspects of semantic meaning?

2020-12-15 Thread Paul Sokolovsky
Hello,

On Tue, 15 Dec 2020 20:18:11 +1100
Chris Angelico  wrote:

> On Tue, Dec 15, 2020 at 8:08 PM Paul Sokolovsky 
> wrote:
> >
> > Hello,
> >
> > On Mon, 14 Dec 2020 02:17:52 -0500
> > David Mertz  wrote:
> >  
> > > On Sun, Dec 13, 2020, 5:11 PM Paul Sokolovsky d
> > >  
> > > > a + b + c   vs   a + (b + c)
> > > >
> > > > Here, there's even no guarantee of the same result, if we have
> > > > user objects with weirdly overloaded __add__().
> > > >  
> > >
> > > 0.1 + 0.2 + 0.3 != 0.1 + (0.2 + 0.3)  
> >
> >
> > Right, thanks. But the original question was about somewhat
> > different matter: if you agree that there's difference between "a +
> > b + c" vs "a + (b + c)", do you agree that there's a similar in
> > nature difference with "a.b()" vs "(a.b)()"? If no, then why? If
> > yes, then how to explain it better? (e.g. to Python novices).
> >  
> 
> https://docs.python.org/3/reference/expressions.html#operator-precedence

No worries, that table is not complete. For example, "," (comma) is a
(context-dependent) operator in Python, yet that table doesn't have
explicit entry for it. Unary "*" and "**" are other context-dependent
operators. (Unary "@" too.)

> 
> ChrisA



-- 
Best regards,
 Paul  mailto:pmis...@gmail.com
___
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/344LG23UBZWOQMQTDEHXEZSUNGSO3ETO/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Using explicit parenthesization to convey aspects of semantic meaning?

2020-12-15 Thread Paul Sokolovsky
Hello,

On Tue, 15 Dec 2020 20:17:37 +1100
Chris Angelico  wrote:

> On Tue, Dec 15, 2020 at 8:04 PM Paul Sokolovsky 
> wrote:
> > So, let's try simple yes/no questions:
> >
> > Example 1:
> >
> > a + b + c   vs   a + (b + c)
> >
> > Question 1:
> > Do you agree that there's a clear difference between left and right
> > expression? Yes/no.  
> 
> Yes, there is a difference.
> 
> > Example 2:
> >
> > a.b()   vs   (a.b)()
> >
> > Question 2:
> > Do you agree that there's a *similar* difference here as in Example
> > 1? Yes/no.  
> 
> No, there is no difference.
> 
> >
> > Then of course depending on the outcome of the last question, there
> > would be further questions. Specifically:
> >
> > If yes: How to put a solid formal basis behind the difference in
> > Example 2 (because so far we're just riding on the similarity with
> > Example 1). And how to explain it to wider audience?
> >  
> 
> Uhh, it's called precedence and associativity? You know that (a + b +
> c) is equivalent to ((a + b) + c), not to (a + (b + c)). Is that
> formal enough?

Yes. But you answered "no" to the Example 2. What makes you think that  
(a + b + c) is not equivalent to (a + (b + c)), but (a.b()) is
equivalent to ((a.b)()), that's what I'm asking.


> 
> ChrisA
>


-- 
Best regards,
 Paul  mailto:pmis...@gmail.com
___
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/XXTXKADGXRDEEUSOHLQQ5SDWMOBIWN3P/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Using explicit parenthesization to convey aspects of semantic meaning?

2020-12-15 Thread Paul Sokolovsky
Hello,

On Tue, 15 Dec 2020 08:25:25 +
Jeff Allen  wrote:

> On 13/12/2020 22:09, Paul Sokolovsky wrote:
> > Thanks for hanging with me so far, we're getting to the crux of the
> > question:
> >
> > Do you think there can be difference between the following two
> > expressions:
> >
> > obj.meth()
> > (obj.meth)()
> >
> > ?  
> 
> No. The value of an expression in parentheses is the value of the 
> expression inside the parentheses, and in this case does not affect
> the order of evaluation.

You're on the right track. (Well, I mean you're on the same track as
me.) So, what's the order of evaluation and what's being evaluated at
all?

> > python3.6 -m dis meth_call.py
> > python3.7 -m dis meth_call.py
> >
> > Then, to try to explain the difference at the suitable level of
> > abstraction. If that doesn't provide enough differentiation, it
> > might be helpful to add the 3rd line:
> >
> > t = obj.meth; t()
> >
> > And run all 3 lines thru CPython3.7, and see if the pattern is now
> > visible, and a distortion in the pattern too.
> >
> > What would be the explanation for all that?  
> 
> The explanation is an optimisation introduced in 3.7 that the use of
> an intermediate variable prevents.

Right. But I would suggest us rising up in abstraction level a bit, and
think not in terms of "intermediate variables" but in terms of
"intermediate storage locations". More details in my today's reply to
Chris Angelico.

> The compiler applies it when it
> can see the only use of the attribute is an immediately following
> call. 

You're now just a step away from the "right answer". Will you make it?
I did. And sorry, the whole point of the discussion if to see if the
whole path, each step on it, and the final answer is as unavoidable as
I now imagine them to be, so I can't push you towards it ;-).

> Having burrowed into the implementation, 

Great! As I mentioned in the other replies, I brought implementation
matters (disassembly) to represent the matter better. But the proper way
is to start with semantics, and then consider how to implement it
(and those considerations can have feedback effect on desired semantics
too of course). So, regardless of whether it was done like that or not
in that case (when LOAD_METHOD was introduced), let's think what
semantics [could have] lead to LOAD_METHOD vs LOAD_ATTR implementation?

[]

> 
> Jeff Allen
> 



-- 
Best regards,
 Paul  mailto:pmis...@gmail.com
___
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/GHPXATZX5NHYH6EATP45BO7CFLLOSMBT/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Using explicit parenthesization to convey aspects of semantic meaning?

2020-12-15 Thread Chris Angelico
On Tue, Dec 15, 2020 at 8:49 PM Paul Sokolovsky  wrote:
> Right, and the question is what semantic (not implementational!) shift
> happened in 3.7 (that's the point when it started to be compiled
> differently).

Have you read the release notes?

https://docs.python.org/3/whatsnew/3.7.html#optimizations

Method calls are now up to 20% faster due to the bytecode changes
which avoid creating bound method instances. (Contributed by Yury
Selivanov and INADA Naoki in bpo-26110.)

It is an *optimization*. There are NO semantic differences, other than
the ones you're artificially creating in order to probe this. (I don't
consider "the output of dis.dis()" to be a semantic difference.)

Why do you keep bringing up irrelevant questions that involve order of
operations? The opcode you're asking about is *just* an optimization
for "look up this method, then immediately call it" that avoids the
construction of a temporary bound method object. The parentheses are a
COMPLETE red herring here.

What is your point?

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/FA34CSD4R3R77GRBUFMHCQE4KBO7GY3M/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Using explicit parenthesization to convey aspects of semantic meaning?

2020-12-15 Thread Steven D'Aprano
On Tue, Dec 15, 2020 at 12:04:44PM +0300, Paul Sokolovsky wrote:

> I certainly agree. But the level at which I'm trying to discuss this
> matter is more "abstract interpretation"'ish. For example, "+" is a
> binary operator, you can't calculate "a + b + c" in one step. There're
> 2 "+", and thus 2 steps. And an intermediate result should be "stored
> somewhere". In different computation models that "somewhere" would be
> different, e.g. in the stack machine model, intermediate result would be
> stored in a location on the value stack, and in the register machine
> model - in ("temporary") register. But from abstract interpretation
> PoV, all those means of storage are equivalent: a named user variable,
> a stack location, a temporary variable. (They have differences beyond
> the "storage" aspect, sure.)

But they aren't equivalent: by definition, a named user variable has a 
user-visible side-effect, while other forms of storage may not: in 
high-level languages, stack locations, registers, and temporary 
variables (in a non-user visible namespace) have no visible side- 
effects.

So this is a critical distinction that you are not making:

- there are computations where such intermediate results are 
  visible to the user;

- and there are other computations where such intermediate
  results are not visible to the user.

Those two classes are not equivalent, except approximately.


> So, let's try simple yes/no questions:
> 
> Example 1:
> 
> a + b + c   vs   a + (b + c)
> 
> Question 1:
> Do you agree that there's a clear difference between left and right
> expression? Yes/no.

Are we talking about Python? Then yes, there is a clear difference.

In the first example, `a + b + c`, execution proceeds left to right: `a 
+ b` first, then the result of that has c added on the right.

The second example changes the order of operations: `b + c` is computed 
first, then a is added on the left.


> Example 2:
> 
> a.b()   vs   (a.b)()
> 
> Question 2:
> Do you agree that there's a *similar* difference here as in Example 1?
> Yes/no.

If we are still talking about Python, then no, there is no difference 
between the two.

In the first example, the name "a" is looked up, then the attribute "b", 
and then the result of that is called.

In the second example, the brackets have no effect: first the name "a" 
is looked up, then the attribute "b", then the result of that is called.

In this case, the brackets do not change the order of operation. It is 
like comparing `a + b + c` versus `(a + b) + c`.

Or for that matter:

a + b + c

versus

(((a) + (b + (((c))

You can add all the redundant parentheses you like without changing the 
order of operation.


Does this conversation have a point? You keep dropping hints that you 
want to introduce a semantic difference between `obj.meth` and 
`(obj.meth)`. Care to tell us what that difference is supposed to be?



-- 
Steve
___
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/632ZWF5Y3ZONF55NCIT6WDE66TR6HETH/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Using explicit parenthesization to convey aspects of semantic meaning?

2020-12-15 Thread Paul Sokolovsky
Hello,

On Mon, 14 Dec 2020 19:39:27 +1100
Steven D'Aprano  wrote:

> On Mon, Dec 14, 2020 at 01:09:56AM +0300, Paul Sokolovsky wrote:
> 
> > Do you think there can be difference between the following two
> > expressions:
> > 
> > obj.meth()
> > (obj.meth)()
> > 
> > ?  
> 
> Okay, I'll bite.
> 
> Of course there is a difference: the first statement is ten
> characters long, the second is 12 characters long.

Fair enough.

> Are you asking for a semantic difference (the two statements do 
> something different) or an implementation difference (the two
> statements do the same thing in slightly different ways)?

I'm asking for semantic difference, it's even in the post title. But
the semantic difference in not in "what two statements do", but in
"what two statements mean". Difference in "doing" is entailed by
difference in "meaning". And there may be no difference in "doing",
but still difference in "meaning", as the original "1+2+3" vs
"1+(2+3)" example was intended to show. 

> Implementation differences are fairly boring (to me): 

Right. How implementation points are brought into the discussion is to
show the issue. As mentioned above, the actual progression is the
opposite: first there's semantic meaning, then it's implemented. So,
what's the semantic meaning of "a.b()" that it gets compiled with
LOAD_METHOD bytecode?

> it might happen
> to be that some Python interpreters happen to compile the first
> statement into a slightly different set of byte codes to the second.
> I don't care too much about that, unless there are large performance
> (speed or memory) differences.
> 
> For what it is worth, Python 1.5 generates the exact same byte code
> for both expressions; so does Python 3.9. However the byte code for
> 1.5 and for 3.9 are different.

Right, and the question is what semantic (not implementational!) shift
happened in 3.7 (that's the point when it started to be compiled
differently).

> However, the semantics of the two expressions are more or less
> identical in all versions of Python, regardless of the byte-code used.

That's what I'd like to put under scrutiny.

> (I say "more or less" because there may be subtle differences between 
> versions, relating to the descriptor protocol, or lack there of, old
> and new style classes, attribute lookup, and handling of unbound
> methods.)

Right, and exactly those "subtle differences" is what I'd like to
discuss. I'd like to start however with more of abstract model of
difference meaning, but afterwards, if the common ground is found, it
would be interesting to check specific not-exactly-on-surface Python
features which you list.

[]

> > python3.6 -m dis meth_call.py
> > python3.7 -m dis meth_call.py
> > 
> > Then, to try to explain the difference at the suitable level of
> > abstraction.  
> 
> At a suitable level of abstraction, there is no difference. The
> suitable level of abstraction is at the level of the Python execution
> model, where `(expression)` and `expression` mean the same, where the
> brackets are used for grouping.

The level of abstraction I'm talking about is where you look not just
at "`(expression)` vs `expression`" but at:

expression  expression   vs   expression  (expression)

Where  is an arbitrary operator. As we already concluded, those do
have difference, even considering such a simple operator as "+".

So... what can we say about the difference between a.b() and (a.b)()
then?

> > it might
> > be helpful to add the 3rd line:
> > 
> > t = obj.meth; t()  
> 
> That clearly has different semantics from the first two: it has the 
> side-effect of binding a value to the name t.

But that's yet another good argument to introduce block-level scoping
to Python (in addition to already stated great arguments), because then,

(a.b)()

will be *exactly* equivalent to (inside a function):

if 1:
const t = a.b
t()

This neither gets affected by the surrounding environment (all variables
introduced are new, regardless of their names), nor affects it (all
variables are block-local, and not visible outside the block).

> I'm not sure where you think this question is going to lead us. 
> Wherever it is, I wish you would get to the point.

I'm sorry if this looks like a quiz, that's not the intention. But I
really would like to see if other people can spot in this stuff what I
spotted (after pondering about it), and I don't want to bias you in any
way by jumping to my "conclusions". I do believe we'll get there, but
then I don't want to be biased myself either. That's why it's
step-by-step process, and I appreciate the people here are willing to
walk it.

> Are you suggesting that we give a *semantic* difference to:
> 
> ( expression )
> 
> compared to the unbracketed `expression`?

Hopefully, that was answered above. To end the post with the summary,
I'm suggesting that there's difference between:

expression  expression   vs   expression  (expression)

Which is hopefully hard to disagree with.

Then I'm asking, how consis

[Python-ideas] Re: Using explicit parenthesization to convey aspects of semantic meaning?

2020-12-15 Thread Chris Angelico
On Tue, Dec 15, 2020 at 8:08 PM Paul Sokolovsky  wrote:
>
> Hello,
>
> On Mon, 14 Dec 2020 02:17:52 -0500
> David Mertz  wrote:
>
> > On Sun, Dec 13, 2020, 5:11 PM Paul Sokolovsky d
> >
> > > a + b + c   vs   a + (b + c)
> > >
> > > Here, there's even no guarantee of the same result, if we have user
> > > objects with weirdly overloaded __add__().
> > >
> >
> > 0.1 + 0.2 + 0.3 != 0.1 + (0.2 + 0.3)
>
>
> Right, thanks. But the original question was about somewhat different
> matter: if you agree that there's difference between "a + b + c" vs "a +
> (b + c)", do you agree that there's a similar in nature difference with
> "a.b()" vs "(a.b)()"? If no, then why? If yes, then how to explain it
> better? (e.g. to Python novices).
>

https://docs.python.org/3/reference/expressions.html#operator-precedence

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/FXGAW2QMQN6S46WV7522KOAXOLVU2G5D/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Using explicit parenthesization to convey aspects of semantic meaning?

2020-12-15 Thread Chris Angelico
On Tue, Dec 15, 2020 at 8:04 PM Paul Sokolovsky  wrote:
> So, let's try simple yes/no questions:
>
> Example 1:
>
> a + b + c   vs   a + (b + c)
>
> Question 1:
> Do you agree that there's a clear difference between left and right
> expression? Yes/no.

Yes, there is a difference.

> Example 2:
>
> a.b()   vs   (a.b)()
>
> Question 2:
> Do you agree that there's a *similar* difference here as in Example 1?
> Yes/no.

No, there is no difference.

>
> Then of course depending on the outcome of the last question, there
> would be further questions. Specifically:
>
> If yes: How to put a solid formal basis behind the difference in
> Example 2 (because so far we're just riding on the similarity with
> Example 1). And how to explain it to wider audience?
>

Uhh, it's called precedence and associativity? You know that (a + b +
c) is equivalent to ((a + b) + c), not to (a + (b + c)). Is that
formal enough?

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/D4C3A3AHHPASX4BWVYXJ4BQIKSU7K3YY/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Using explicit parenthesization to convey aspects of semantic meaning?

2020-12-15 Thread Paul Sokolovsky
Hello,

On Mon, 14 Dec 2020 02:17:52 -0500
David Mertz  wrote:

> On Sun, Dec 13, 2020, 5:11 PM Paul Sokolovsky d
> 
> > a + b + c   vs   a + (b + c)
> >
> > Here, there's even no guarantee of the same result, if we have user
> > objects with weirdly overloaded __add__().
> >  
> 
> 0.1 + 0.2 + 0.3 != 0.1 + (0.2 + 0.3)


Right, thanks. But the original question was about somewhat different
matter: if you agree that there's difference between "a + b + c" vs "a +
(b + c)", do you agree that there's a similar in nature difference with
"a.b()" vs "(a.b)()"? If no, then why? If yes, then how to explain it
better? (e.g. to Python novices).


-- 
Best regards,
 Paul  mailto:pmis...@gmail.com
___
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/7DUK4HN7ACH2W6FOUP3KQEINSNJBXELD/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Using explicit parenthesization to convey aspects of semantic meaning?

2020-12-15 Thread Paul Sokolovsky
Hello,

On Mon, 14 Dec 2020 18:05:07 +1100
Chris Angelico  wrote:

> On Mon, Dec 14, 2020 at 5:57 PM Paul Sokolovsky 
> wrote:
> >
> > But that's what the question was about, and why there was the intro!
> > Let's please go over it again. Do you agree with the following:
> >
> > a + (b + c)  <=>  t = b + c; a + t
> >
> > ?
> >
> > Where "<=>" is the equivalence operator. I do hope you agree,
> > because it's both basis for evaluation implementation and for
> > refactoring rules, and the latter is especially important for
> > line-oriented language like Python, where wrapping expression
> > across lines requires explicit syntactic markers, which some people
> > consider ugly, so there should be clear rules for splitting long
> > expressions which don't affect there semantic.  
> 
> It really depends on what you mean by "equivalent". For instance, I'm
> sure YOU will agree that they have the semantic difference of causing
> an assignment to the name 't'.

I certainly agree. But the level at which I'm trying to discuss this
matter is more "abstract interpretation"'ish. For example, "+" is a
binary operator, you can't calculate "a + b + c" in one step. There're
2 "+", and thus 2 steps. And an intermediate result should be "stored
somewhere". In different computation models that "somewhere" would be
different, e.g. in the stack machine model, intermediate result would be
stored in a location on the value stack, and in the register machine
model - in ("temporary") register. But from abstract interpretation
PoV, all those means of storage are equivalent: a named user variable,
a stack location, a temporary variable. (They have differences beyond
the "storage" aspect, sure.)

> Additionally, Python will evaluate a
> before b and c in the first example, but must evaluate b and c, add
> them together, and only after that evaluate a. So, no, they aren't
> entirely equivalent. Obviously, in many situations, the programmer
> will know what's functionally equivalent, but the interpreter can't.
> 
> Clarify what you mean by equivalence and I will be able to tell you
> whether I agree or not. (It's okay if your definition of equivalent
> can't actually be described in terms of actual Python code, just as
> long as you can explain which differences matter and which don't.)

So, let's try simple yes/no questions:

Example 1:

a + b + c   vs   a + (b + c)

Question 1:
Do you agree that there's a clear difference between left and right
expression? Yes/no.



Example 2:

a.b()   vs   (a.b)()

Question 2:
Do you agree that there's a *similar* difference here as in Example 1?
Yes/no.


Then of course depending on the outcome of the last question, there
would be further questions. Specifically:

If yes: How to put a solid formal basis behind the difference in
Example 2 (because so far we're just riding on the similarity with
Example 1). And how to explain it to wider audience?

If no: What is the explanation of such a striking distinction in
treatment of Example 1 vs Example 2?


> 
> ChrisA

[]

-- 
Best regards,
 Paul  mailto:pmis...@gmail.com
___
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/IKF27IGMHFCH7OBE4XJX54ZSEKGQ347U/
Code of Conduct: http://python.org/psf/codeofconduct/