[Python-ideas] Re: @classproperty, @abc.abstractclasspropery, etc.
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?
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?
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
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?
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?
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?
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
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
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?
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
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
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?
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?
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?
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?
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?
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?
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?
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?
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?
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?
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?
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?
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?
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?
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?
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?
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?
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?
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?
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?
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/