[Python-ideas] Re: A proposal (and implementation) to add assignment and LOAD overloading
Chris Angelico writes: > Then I completely don't understand getself. Can you give an example > of how it would be used? So far, it just seems like an utter total > mess. It's possible that __getself__ would be implemented "halfway". That is, if __getself__ is present, it is invoked, and performs *side effects* (a simple example would be an access counter/logger for the object). Then the compiler loads that object, discarding any return value of the method. I think this is the semantics that the proponents are thinking of. ___ 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/Q5XDXZBDBIFUZP424TNPF4C4UNXDWSI7/ Code of Conduct: http://python.org/psf/codeofconduct/
[Python-ideas] Code is a social construct [was: A proposal (and implementation) ...]
Anders Hovmöller writes: > In python code basically can't be understood at face value. Not really a problem. The #ToddlerInChief doesn't code; the rest of us are adults and use code by consent. Obfuscate your code by seriously violating the expections for the meaning of "+" or ".denominator" and we'll withdraw consent. Really, it's as easy as that. "We" know unacceptable obfuscation "when we see it." There's no "red line", but this is good enough. The problem with the proposal is that it obfuscates "in a good cause" by confounding the Pythonic semantics of "= as name binding" with the natural[1] but un-Pythonic[2] "= as changing a variable in-place". Somebody (Rhodri?) recently said something like "I keep coming back to the Zen: explicit is better than implicit." I think that says the whole argument against the proposal. Footnotes: [1] In other languages. [2] IMO, I do not speak for Guido. ___ 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/WFW3QJ6KBGHDGRTGISSOVGDU7Z5KO2VK/ Code of Conduct: http://python.org/psf/codeofconduct/
[Python-ideas] Re: A proposal (and implementation) to add assignment and LOAD overloading
:Hello all, I am sorry to send this out to the list and then be so silent, work and children and all. I am going to try and address the issues raised in this thread, with apologies if I miss someones issue. Some of these are addressed in the documentation I wrote, but I know I can't expect people to take their time to go off and read a lot of material, I am thankful enough for the time that people put even into reading and responding. This message might get long, again, my apologies. I have put names by the response to that person, so you can read your section. The response may refer to other responses, but this was long enough without duplication. Again I might not have been completely through with each response in light of the length, but tried to hit the high points and conceptual discussions, if not the details. For these responses I may refer to some of the demos here: https://github.com/natelust/CloakingVarWriteup/blob/master/examples.py Ben Rudiak-Gould: Your point with iteration is well taken. Depending on the variable bound, it may end up transparent to you without you needing to care, as in the case of something like my HistoricVar demo. However it is a fair point, that it might not be transparent and you could end up with an exception thrown at some point. I would argue this is not much different than using any library code where you would need to understand the api, but documentation is not always up to par, and it is indeed one more thing to think about or check for. Your idea of marking a variable with something like metavar is an interesting idea, and definitely something I am going to think more on. If this is required for the new behavior in each function where it is used I don't think that is compatible with how I was envisioning this to work, it would require more thought. At this point one of the benefits of this type of metavar, is that I can declare it with whatever side effects I want (such as a callback on assignment) and pass it into existing third party code and not need that code to be altered, that code would not care that it is special. This is a case where the sense of responsibility is flipped from what you are worried about though, where I would be responsible for creating an appropriate variable (like I am for types now) when I am using your library. I am not sure how that would play well with a keyword at declaration, except that someone could read my code (or a library using this type of variable) and see that it was defined in a special way. Rhodri James: Your point seems similar Ben's above so perhaps that addresses some of your points. I think the idea is in what context will this code be used. If I am a library author then I might not want to expose this type of variable to outside the api without some sort of annotation. That does not mean it could not be really useful inside an api, or for instance used as an instance level property. Anders Hovmoller: Apologies about not getting the accents in your name as I type this. I appreciate the devils advocate stance. If this proposal went anywhere or not, I was hopping to learn a lot through the discussion, and process. Continuing the discussion really helps to that end. Chris Angelico: In my proposal you are correct that in functions such as: def f1(): x = metavar() return x def f2(): return metavar() would not have worked as expected. As soon that the variable became bound to the name, the LOAD operations that happened before a RETURN operation would call __getself__ and the result would be returned. A built in method wold have been required to get to the underlying object, such as in def f3(): x = metavar() return getcloaked('x') This means that those two functions would have resulted in different returns. (A similar problem would exist for function calls). I was never entirely happy with this behavior either. A little while ago I pushed a patch up to my cpython fork that made the behavior the same as existing python, if you use a metavar in the return statement, it will be returned from the function to the calling scope, where it will again behave as a metavar (I also made the same change for calling a function with a metavar as an argument) I hope some of the examples I linked to in previous messages helped, but I am happy to talk more about what the call chain looks like, and how I intend things to work. Greg Ewing: I think some of your points were also addressed above. I am happy to expand on any of them myself if the above has not addressed them. Andrew Barnert: I thank you for also playing devils advocate, and if not providing a "vote of confidence" then a willingness to make sure my ideas are heard, and that I have a chance to address and possibly make a better proposal. Brendan Barnwell: I can appreciate your position, and might well feel the same if I was a maintainer of the python code base. However, I will confess I did come away a little stung by the tone of your message.
[Python-ideas] Re: A proposal (and implementation) to add assignment and LOAD overloading
On 2019-06-26 14:27, nate lust wrote: This is the example I was talking about specifically: https://github.com/natelust/CloakingVarWriteup/blob/master/examples.py#L76. There are other possibilities as well, I would be happy to explain my Ideas directly, I am not sure exactly everything Yanghao is saying as I have not been able to follow it very closely. I've been reading this discussion off and on, and just looked at your example. It only confirms what I've thought since the beginning: none of the examples or use cases described provide even remotely sufficient justification for changing the behavior of assignment to a bare name. They are light years away from being sufficient justification. In the unlikely event that you want something that can track all the values that have been assigned to it, I just don't see any reason why you can't make that thing be an attribute of an object. Then the descriptor protocol already handles everything under discussion here. If you don't like typing you can name the object "x" so you just have to type "x.foo = 1". Adding descriptor-like behavior to bare names massively increases the potential confusion and, as far as I can see, the only "benefit" proposed is that you don't have to type a dot. I'm frankly quite surprised that this discussion has gone on so long. I just can't see any benefit to any of the proposals that gets anywhere close to justifying the increased difficulty of reasoning about code where any assignment to a local variable can call arbitrary code under the hood. -- Brendan Barnwell "Do not follow where the path may lead. Go, instead, where there is no path, and leave a trail." --author unknown ___ 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/SCOFYLLZR2DOOZOAOIQT3E6M2HDLGVDZ/ Code of Conduct: http://python.org/psf/codeofconduct/
[Python-ideas] Re: A proposal (and implementation) to add assignment and LOAD overloading
On Jun 26, 2019, at 15:46, Greg Ewing wrote: > > Yes, but it's pretty universal across languages with name-binding > semantics for assignment (Lisp, Ruby, Javascript etc.) that assigning > to a local name doesn't invoke any magic. I don’t think that’s quite true. Many languages with name-binding semantics simply don’t invoke any magic for any assignments. Among those that do, I don’t think there’s anything universal about allowing it on some scopes but not local. For example, in Lisp, if you replace the setf macro, that replaces local symbol sets just as much as closure, global, and dynamic sets, and even non-symbol sets like to generalized-variables. The fact that Python’s namespaces are object-oriented, and Python makes it very easy to replace or hook class instance namespaces, a bit harder to replace or hook global namespaces, and very hard to replace or hook local namespaces, is probably specific to Python. And think about this: If you had code involving “x = 2” that stopped working when you moved it from local to a module init function to the top level of the module because it was no longer doing anything that could be construed as binding x, would you think “Something is broken”, or “That’s ok, x isn’t local, so I wasn’t expecting assignment to mean binding”? (Code that actually does something fancy with namespaces, your expectations on moving it might be different, of course—but in that case, you’re already thinking about the namespace semantics, so you’re prepared for that.) ___ 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/UNCJDQFMSXR7HWC5XNL7EAQKXU5IXFOE/ Code of Conduct: http://python.org/psf/codeofconduct/
[Python-ideas] Re: A proposal (and implementation) to add assignment and LOAD overloading
Yanghao Hua wrote: when you do x.y = z and if y is a descriptor you don't expect x.y is now pointing/binding to z, you have to understand the object behavior anyway. I do not see how this is different in the set/getself() case. The difference is that the special behaviour is associated with 'x.y', not just 'y'. -- 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/IVTQ5J4NZIUPSA4XBCA674JDP2P4TXZL/ Code of Conduct: http://python.org/psf/codeofconduct/
[Python-ideas] Parsing strings with Python (was Re: Re: Proposal: Using % sign for percentage)
Please change the subject line when you change the topic of conversation. Or even better, since this isn't strongly related to what you're replying to, and you quoted no text whatsoever - just make it a brand new post. Thanks! On Thu, Jun 27, 2019 at 5:06 AM James Lu wrote: > > What if we had reverse format strings, i.e. reading formatted input? > > x = readf("{:.0%}", "50%") > # => x == 0.50 > x = readf("{:.0}", "50") > # => x == 0.50 > > Readf takes the repr() of its second argument and “un-formats” the string. What you're talking about sounds like a scanf sort of thing. In C, printf and scanf are approximate counterparts, as are sprintf and sscanf, which work directly with strings (compare json.load and json.loads, or json.dump and json.dumps). The way sscanf works is that every marker clearly defines the type of value it can parse: %d - one integer, decimal %f - floating-point value in decimal %s - string etc, etc Trying to form a parallel to the way Python's .format() method works is a little tricky, because format() starts with the object it's formatting, and then says "hey, format yourself, kay?". So it may be best to abandon that and instead stick with the well-known sscanf notation. The main advantage of sscanf over a regular expression is that it performs a single left-to-right pass over the format string and the target string simultaneously, with no backtracking. (This is also its main DISadvantage compared to a regular expression.) A tiny amount of look-ahead in the format string is the sole exception (for instance, format string "%s$%d" would collect a string up until it finds a dollar sign, which would otherwise have to be written "%[^$]$%d"). There is significant value in having an extremely simple parsing tool available; the question is, is it worth complicating matters with yet another way to parse strings? (We still have fewer ways to parse than ways to format strings. I think.) 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/IZLZAS33HISBT3XGTFUXJRMLT6YPZCJH/ Code of Conduct: http://python.org/psf/codeofconduct/
[Python-ideas] Re: Proposal: Using % sign for percentage
On Jun 25, 2019, at 08:44, James Lu wrote: > > What if we had reverse format strings, i.e. reading formatted input? > > x = readf("{:.0%}", "50%") > # => x == 0.50 > x = readf("{:.0}", "50") > # => x == 0.50 > > Readf takes the repr() of its second argument and “un-formats” the string. What’s the algorithm for this? There’s at least possibly an answer for things like C printf, because the format specifier “%.1f” tells you the type—if you pass anything but a double to printf with that specifier, it’s undefined behavior, so you can write a scanf function that knows that “%.1f” has to “unprintf” into a double. But Python format specifier “.1” tells you nothing about the type—it can be passed a float, a str, an instance of some arbitrary user-defined type… so what type can tell you how to “unformat” it? (By the way, format(50.0, “.1”) gives you “5e+01”, not “50”. And the repr of the string “50” is the string “‘50’”. Also, surely unformatting returns not a single value, but as many values as there are format specifiers, right? But these issues are trivial.) It might be possible to come up with a solution to this. Maybe you could explicitly specify the types in the “unformat” specifier, before the colon, and it calls __unformat__ on that type, which returns the parsed value and the remainder of the string?That could work for simple cases: x, = unformat(“{float:.0f}”, “50”) … or even: x, op, y = unformat(“{float.0f} {str:.1} {float:.0f}”, “2 * 3”) But what happens in this case: x, op, y = unformat(“{float.0f} {str} {float:.0f}”, “2 * 3”) There’s no way str.__unformat__(“”, “* 3”) can know whether to parse one character or the whole string or anything in between. Unless you want some horribly inefficient backtracking scheme, this has to be illegal. (And this is exactly why people come up with more restricted languages to parse. If you know the language is regular, you can write a regex to parse it, which actually can disambiguate cases like this without exponential backtracking.) ___ 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/ABQHFVX5DOK2C2HIYPLKGUTH2MI353AC/ Code of Conduct: http://python.org/psf/codeofconduct/
[Python-ideas] Re: A proposal (and implementation) to add assignment and LOAD overloading
Anders Hovmöller wrote: On 26 Jun 2019, at 16:46, Chris Angelico wrote: it violates programmer expectations *across many languages* regarding refactoring. isn't that potentially extremely different in C++ for example? Yes, but it's pretty universal across languages with name-binding semantics for assignment (Lisp, Ruby, Javascript etc.) that assigning to a local name doesn't invoke any magic. -- 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/4SD63RFWWIZ3FBW6TIH432M3T75NJMVA/ Code of Conduct: http://python.org/psf/codeofconduct/
[Python-ideas] Re: A proposal (and implementation) to add assignment and LOAD overloading
On Jun 26, 2019, at 13:53, Chris Angelico wrote: > Then in what circumstances will getself NOT be called? What is the > point of having an object, if literally every reference to it will > result in something else being used? I think Yanghao has misunderstood the proposal. What Nate actually proposed is not that every time the value is accessed it calls __getself__, only accesses that are loads from a variable. The infinite regress problem is no worse than, say, __getattribute__ usually needing to call a method on super or object. But if I’m right, then your initial refactoring point is still unanswered. You can return or otherwise use the value of self or the return of the uncloak function or whatever without triggering another call to __getself__, but if you refactor the return statement by storing an intermediate value in a temporary local variable, accessing that variable will trigger another call to __getself__. I assume Nate is working on an answer to that along with all the other points that have been raised. ___ 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/72KYUGOAW7M33BHQ22LBOBYWVVHX4XVF/ Code of Conduct: http://python.org/psf/codeofconduct/
[Python-ideas] Re: A proposal (and implementation) to add assignment and LOAD overloading
On Wednesday, June 26, 2019, 11:53:30 AM PDT, Chris Angelico wrote: > I don't think you can define what "f->spam" means Well, you can, but only the first half of what it means, so I don't think this changes your point. If f is a pointer, then f->spam means to dereference the pointer f, then access the spam attribute of the result. If f is an instance of a user-defined class, rather than a raw pointer, it can redefine ->. But only to change the "dereference" part, not the "access the spam attribute" part. In other words, f->spam means something like (*(f.operator->())).spam and you can overload the operator->. Of course, under very restricted conditions, you can do something like this: #include struct pstatus; struct status { int eggs, spam; } struct pstatus { status *p; status* operator->() { return reinterpret_cast(reinterpret_cast(p) - sizeof(int)); } }; pstatus frob() { return pstatus{new status{1, 2}}; } int main() { auto f = frob(); // eggs = 1, spam = 2 std::cout << f->spam; // accesses eggs, and prints 1 rather than 2 return 0; } Compile that with g++ or clang++ with -std=c++11 (we don't actually need any C++11 feature here, the code's just a bit shorter and simpler with auto, etc.), and it should compile without warnings, and print out 1 rather than 2 when you run it. The trick is that "access the spam attribute" actually means "access bytes 4-8 of the struct as an int", so if we have a pointer to 4 bytes before the start of the real struct, you get the int at bytes 0-4 of the real struct, which is the real eggs. (Actually, we should be using the difference between offsetof(spam) and offsetof(eggs), not sizeof(int), so it would be legal even with non-default alignment. But so many tiny things could turn this code into undefined behavior, even with that change, like just adding a virtual method to status, or referencing f->eggs in code that doesn't even run… so let's not worry about bulletproofing it.) ___ 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/IT2URM7MXF7CD2Y5JF7A6HLUFE32YY3V/ Code of Conduct: http://python.org/psf/codeofconduct/
[Python-ideas] Re: A proposal (and implementation) to add assignment and LOAD overloading
On Wed, Jun 26, 2019 at 11:24 PM nate lust wrote: [...] > Yanhao, I do not think you are doing this proposal any good. I appreciate you > trying to go to bat for it, but there are many good concerns here that would > be good to hear out and address rather than trying to dismiss them. I was trying to understand the concerns ... not dismissing them. most of the concerns is of course valid, but many seems to be extremely general/high-level which seems more of subjective matter rather than objective technical discussions. I can back off if you think I am not helping here ... it is your battle just remember you are not the only one likes this feature. ___ 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/NH5QB7UDLHZFW7WF64DPFRF5VGRBG5FR/ Code of Conduct: http://python.org/psf/codeofconduct/
[Python-ideas] Re: A proposal (and implementation) to add assignment and LOAD overloading
On Wed, Jun 26, 2019 at 11:16 PM Chris Angelico wrote: [...] > Then I completely don't understand getself. Can you give an example of > how it would be used? So far, it just seems like an utter total mess. Sure, below is my code snippet for signal get/set, using "L[:] = thing" syntax and overriding get/setitem(). In this case, signal follow a declaration (e.g. x = signal()) and use (e.g. x[:] = thing, thing = x[...]) paradigm. getitem always return a integer or delegates it to another object (self.current). 207 def __setitem__(self, key, value): 208 if self.typ == IN: 209 raise SignalError("IN type signal cannot be assigned") 210 if self.edge != 0: 211 raise SignalError("edge signal cannot be assigned") 212 elif isinstance(value, self.__class__): 213 self._set_next(key, value.current) 214 delay = Delay(0, value.current, signal=self) 215 self.sim.delta_next.append(delay) 216 elif isinstance(value, Delay): 217 value.next = value.delay + self.sim.current_time # relative delay to absolute time 218 value.signal = self 219 self._set_next(key, value.value) 220 if value.delay == 0: 221 self.sim.delta_next.append(value) 222 else: 223 self.sim._event(value) 224 else: 225 self._set_next(key, value) 226 delay = Delay(0, value, signal=self) 227 delay.next = self.sim.current_time 228 self.sim.delta_next.append(delay) 230 def __getitem__(self, key): 231 ''' 232 Slicing of signals 233 ''' 234 if self.value_type != int: 235 return self.current.__getitem__(key) # support generic payloads, not just int, so delegate it to "current" 236 # int signal always returns an int 237 if key in [slice(None, None, None), ...]: 238 return self.current # behaves like an int if explicitly indexed 239 elif isinstance(key, slice): 240 start = key.start 241 stop = key.stop 242 step = key.step 243 if key.step: 244 step = key.step 245 else: 246 step = 1 247 if start < stop: # the little endian case 248 if stop > self.width: 249 raise SignalError("slice stop is too big: %d (> width %d)" % (stop, self.width)) 250 stop += 1 251 else: # the big endian case 252 if start >= self.width: 253 raise SignalError("slice start is too big: %d (>= width %d)" % (start, self.width)) 254 stop -= 1 255 step = 0 - step 256 vrange = range(start, stop, step) 257 length = len(vrange) 258 current = self.current 259 value_list = [] 260 #print("current:", current) 261 for i in vrange: 262 v = (current >> i) & 0x1 263 #print("v:", v) 264 value_list.append(v) 265 return self._get_value(value_list) 266 elif isinstance(key, int): 267 if key >= self.width: 268 raise SignalError("key is too big: %d (>= width %d)" % (key, self.width)) 269 return (self.current >> key) & 0x1 270 elif isinstance(key, tuple): 271 raise SignalError("signal indices must be integers or slices, not tuple") And this is how it can be used by a user: 8 @block("hdl") 9 def ADD(name, 10 a: signal(32, IN), 11 b: signal(32, IN), 12 out: signal(32, OUT), 13 ): 14 15 x = signal(1, OUT, "x") 16 17 @always(a, b) 18 def add(): 19 out[:] = (a + b) EOF. ___ 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/I5BR4WTECUYYGFQ4NX6VOZ3AJTPMMHH2/ Code of Conduct: http://python.org/psf/codeofconduct/
[Python-ideas] Re: A proposal (and implementation) to add assignment and LOAD overloading
This is the example I was talking about specifically: https://github.com/natelust/CloakingVarWriteup/blob/master/examples.py#L76. There are other possibilities as well, I would be happy to explain my Ideas directly, I am not sure exactly everything Yanghao is saying as I have not been able to follow it very closely. On Wed, Jun 26, 2019 at 5:20 PM Chris Angelico wrote: > On Thu, Jun 27, 2019 at 7:11 AM Yanghao Hua wrote: > > > > On Wed, Jun 26, 2019 at 11:00 PM Chris Angelico > wrote: > > > > > > On Thu, Jun 27, 2019 at 6:50 AM Yanghao Hua > wrote: > > > > > > > > On Wed, Jun 26, 2019 at 10:16 PM Chris Angelico > wrote: > > > > > > > > > > Let's suppose that frob() returns something that has a __getself__ > > > > > method. Will f1 trigger its call? Will f2? If the answer is "yes" > to > > > > > both, then when ISN'T getself called? If the answer is "no" to > both, > > > > > > > > What's the problem for the "yes" case? If you define such an object > of > > > > course __get/setself__() is always called, and f1() is still equal to > > > > f2(). > > > > > > Then in what circumstances will getself NOT be called? What is the > > > point of having an object, if literally every reference to it will > > > result in something else being used? The moment you try to return this > > > object anywhere or do literally anything with it, it will devolve to > > > the result of getself, and the original object is gone. > > > > No, it won't -- getself() will/can return self, setself(self, other) > > will type-checking other and re-interpret them into integers, and do > > the magic (e.g. signal.next = integer). I implemented exactly the same > > thing using signal[:] overriding get/setitem(). I mean, how to use it > > is up to the user, there are endless possibilities. You can choose to > > return self, or something entirely different, the point is you now > > have control over "=" operator as you can for the other operators. > > Then I completely don't understand getself. Can you give an example of > how it would be used? So far, it just seems like an utter total mess. > > 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/ZBWKD4BGIRDBNQVF6SRXUMZ7EMKLCKCT/ > Code of Conduct: http://python.org/psf/codeofconduct/ > -- Nate Lust, PhD. Astrophysics Dept. Princeton University ___ 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/HHXKZ5VL2CF2TD5VCCEPY3NMYZSWWCOE/ Code of Conduct: http://python.org/psf/codeofconduct/
[Python-ideas] Re: A proposal (and implementation) to add assignment and LOAD overloading
Chris, There are a lot of messages for me to catch up on from today, but I am heading home from work, and your most recent one is the easiest to address quickly. I want to start out by saying I agree with many of the objections and concerns raised here, and there were some I had not thought about. This is why I put the proposal out, to learn more and perhaps make a stronger proposal (I like the idea raised last night of denoting these variables with a keyword to denote they are special and should be treated as such). Yanhao, I do not think you are doing this proposal any good. I appreciate you trying to go to bat for it, but there are many good concerns here that would be good to hear out and address rather than trying to dismiss them. To your last message Chris, I just wanted to point out one way I envision this may be used used (Although it is still a bit of a toy). In my longer examples.py file I have a history variable that tracks all the values that were bound to the name (using __setself__) in a history list. __getself__ would then always return the most recently set value when loaded. I introduced a "built in" called getcloaked what would allow fetching the actual cloaking variable such that it could be used. In this case that would be something like getcloaked('var').rollback_history(2) to move back to a previous assignment. This could potentially be used in say a debugger, or try except or the like. As you say this would only be good from within a single scope, unless the return statement of the function was: return getcloaked('var') (or conversely a function was called like foo(getcloaked('var") to pass it into scope). I do think that this proposal needs work (or possibly thrown out all together if it could not be refined), and all the ideas and questions were exactly what I was hoping for, as there is more that others will be able to see than I am alone. On Wed, Jun 26, 2019 at 5:04 PM Chris Angelico wrote: > On Thu, Jun 27, 2019 at 6:50 AM Yanghao Hua wrote: > > > > On Wed, Jun 26, 2019 at 10:16 PM Chris Angelico > wrote: > > > > > > Let's suppose that frob() returns something that has a __getself__ > > > method. Will f1 trigger its call? Will f2? If the answer is "yes" to > > > both, then when ISN'T getself called? If the answer is "no" to both, > > > > What's the problem for the "yes" case? If you define such an object of > > course __get/setself__() is always called, and f1() is still equal to > > f2(). > > Then in what circumstances will getself NOT be called? What is the > point of having an object, if literally every reference to it will > result in something else being used? The moment you try to return this > object anywhere or do literally anything with it, it will devolve to > the result of getself, and the original object is gone. > > 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/DXRITYQA3MY7P6V3FYGE7ZPR53EHWHPV/ > Code of Conduct: http://python.org/psf/codeofconduct/ > -- Nate Lust, PhD. Astrophysics Dept. Princeton University ___ 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/JZY5T37LKOB74QVJ4XWZN62E5SEXNMW6/ Code of Conduct: http://python.org/psf/codeofconduct/
[Python-ideas] Re: A proposal (and implementation) to add assignment and LOAD overloading
On Thu, Jun 27, 2019 at 7:11 AM Yanghao Hua wrote: > > On Wed, Jun 26, 2019 at 11:00 PM Chris Angelico wrote: > > > > On Thu, Jun 27, 2019 at 6:50 AM Yanghao Hua wrote: > > > > > > On Wed, Jun 26, 2019 at 10:16 PM Chris Angelico wrote: > > > > > > > > Let's suppose that frob() returns something that has a __getself__ > > > > method. Will f1 trigger its call? Will f2? If the answer is "yes" to > > > > both, then when ISN'T getself called? If the answer is "no" to both, > > > > > > What's the problem for the "yes" case? If you define such an object of > > > course __get/setself__() is always called, and f1() is still equal to > > > f2(). > > > > Then in what circumstances will getself NOT be called? What is the > > point of having an object, if literally every reference to it will > > result in something else being used? The moment you try to return this > > object anywhere or do literally anything with it, it will devolve to > > the result of getself, and the original object is gone. > > No, it won't -- getself() will/can return self, setself(self, other) > will type-checking other and re-interpret them into integers, and do > the magic (e.g. signal.next = integer). I implemented exactly the same > thing using signal[:] overriding get/setitem(). I mean, how to use it > is up to the user, there are endless possibilities. You can choose to > return self, or something entirely different, the point is you now > have control over "=" operator as you can for the other operators. Then I completely don't understand getself. Can you give an example of how it would be used? So far, it just seems like an utter total mess. 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/ZBWKD4BGIRDBNQVF6SRXUMZ7EMKLCKCT/ Code of Conduct: http://python.org/psf/codeofconduct/
[Python-ideas] Re: A proposal (and implementation) to add assignment and LOAD overloading
On Wed, Jun 26, 2019 at 11:00 PM Chris Angelico wrote: > > On Thu, Jun 27, 2019 at 6:50 AM Yanghao Hua wrote: > > > > On Wed, Jun 26, 2019 at 10:16 PM Chris Angelico wrote: > > > > > > Let's suppose that frob() returns something that has a __getself__ > > > method. Will f1 trigger its call? Will f2? If the answer is "yes" to > > > both, then when ISN'T getself called? If the answer is "no" to both, > > > > What's the problem for the "yes" case? If you define such an object of > > course __get/setself__() is always called, and f1() is still equal to > > f2(). > > Then in what circumstances will getself NOT be called? What is the > point of having an object, if literally every reference to it will > result in something else being used? The moment you try to return this > object anywhere or do literally anything with it, it will devolve to > the result of getself, and the original object is gone. No, it won't -- getself() will/can return self, setself(self, other) will type-checking other and re-interpret them into integers, and do the magic (e.g. signal.next = integer). I implemented exactly the same thing using signal[:] overriding get/setitem(). I mean, how to use it is up to the user, there are endless possibilities. You can choose to return self, or something entirely different, the point is you now have control over "=" operator as you can for the other operators. ___ 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/55Y74CR76JLBUUZL2EJA7B4GLZFPMYTD/ Code of Conduct: http://python.org/psf/codeofconduct/
[Python-ideas] Re: A proposal (and implementation) to add assignment and LOAD overloading
On Thu, Jun 27, 2019 at 6:50 AM Yanghao Hua wrote: > > On Wed, Jun 26, 2019 at 10:16 PM Chris Angelico wrote: > > > > Let's suppose that frob() returns something that has a __getself__ > > method. Will f1 trigger its call? Will f2? If the answer is "yes" to > > both, then when ISN'T getself called? If the answer is "no" to both, > > What's the problem for the "yes" case? If you define such an object of > course __get/setself__() is always called, and f1() is still equal to > f2(). Then in what circumstances will getself NOT be called? What is the point of having an object, if literally every reference to it will result in something else being used? The moment you try to return this object anywhere or do literally anything with it, it will devolve to the result of getself, and the original object is gone. 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/DXRITYQA3MY7P6V3FYGE7ZPR53EHWHPV/ Code of Conduct: http://python.org/psf/codeofconduct/
[Python-ideas] Re: A proposal (and implementation) to add assignment and LOAD overloading
On Jun 26, 2019, at 07:34, Anders Hovmöller wrote: > > I 100% agree that this proposal is a bad idea. But I do have to play Devils > advocate here. > > The the-code-is-understandable-at-face-value ship has already sailed. + > doesn't mean add, it means calling a dunder function that can do anything. No, + does mean add. But Python doesn’t know what it means to add two Fraction or Decimal or ndarray objects, so if you’re the one writing that class, you have to tell it. It still means add—unless you lie to your readers. And you can always lie to your readers; dunder methods aren’t needed for that. Sure, you could define Fraction.__add__(self, other) to print self to a file named str(other) and return clock(), but you could just as easily store the numerator in an attribute named “denominator”, or name the class “EmployeeRecord” instead of “Fraction”, or store the Fraction 1/2 in a variable named “pathname”. It’s not up to Python to prevent you from lying to your readers. > Foo.bar = 1 doesn't mean set bar to 1 but calling a dunder method. No, it does mean setting bar to 1. The only difference between __add__ and __setattr__ is that the latter has default behavior that works for many classes. If your type(Foo) class has disk-backed attributes or immutable attributes or attributes that dir in reverse order of assignment rather than arbitrary order, you have to tell Python how to do that. Unless you’re lying, you’re defining what it means to set the bar attribute to 1, not defining Foo.bar = 1 to mean something different from setting the bar attribute. The problem isn’t that __setself__ could be used to lie; the problem is that __setself__ can’t be used in a way that isn’t lying. None of the suggested examples are about providing a way to define what binding x to 1 means in the local/classdef/global namespace, they’re all about providing a way to make x = 1 not mean binding x to 1 in that namespace at all. In particular, the best example we’ve seen amounts to “Python doesn’t have a send operator like <- so instead of adding one, let’s allow people to misuse = to mean send instead of than assign”. The obvious way to justify this is by appeal to descriptors: the __set__ method isn’t there because people want to use descriptors directly, it’s there because people do want to use classes with custom attributes like properties, classmethods, etc. and descriptors make defining those classes easier. Maybe in a better example, we’d see that __setself__ is similarly there to make it easier to define namespaces with custom bindings easier, and people do want those namespaces. If so, the reason not everyone is convinced is that we’ve only seen bad examples so far. But then someone needs to give a good example. > In python code basically can't be understood at face value. This is the Humpty Dumpty argument from Alice. English can’t be understood at face value if Humpty can use any word to mean anything he wanted, rather than what Alice expected that word to mean. And yet, among normal speakers—even with slightly different idiolects, even in discourses that explicitly redefine words (as with most math papers, which is probably what Lewis Carroll has in mind)—English actually can be understood, it just can’t prevent Humpty from misusing it. ___ 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/4254JCBLY5MXLCDJK3UAEC5DTZGPYBLW/ Code of Conduct: http://python.org/psf/codeofconduct/
[Python-ideas] Re: A proposal (and implementation) to add assignment and LOAD overloading
On Wed, Jun 26, 2019 at 10:16 PM Chris Angelico wrote: > > On Thu, Jun 27, 2019 at 5:29 AM Yanghao Hua wrote: > > > > On Wed, Jun 26, 2019 at 4:47 PM Chris Angelico wrote: > > [...] > > > There are many things that can be implemented with dunders, yes, but > > > in Python, I would expect these two functions to behave identically: > > > > > > def f1(x): > > > return frob(x).spam > > > > > > def f2(x): > > > f = frob(x) > > > s = f.spam > > > return s > > > > > > This correlation is critical to sane refactoring. You should be able > > > to transform f1 into f2, and then insert print calls to see what 'f' > > > and 's' are, without affecting the behaviour of the function. The > > > proposed magic would change and completely break this; and as such, it > > > violates programmer expectations *across many languages* regarding > > > refactoring. > > > > Chris, I might need a bit more education here. I am trying to guess > > what you meant to say here is if in f2(), f or s is already defined, > > it will then change the "usual" understanding. In this case, I am > > assuming when you start to assign in f2() a local variable f or s with > > an object that has __set/getself__(), then you know later on assigning > > to it will mean differently. How is this different from descriptors? > > when you do x.y = z and if y is a descriptor you don't expect x.y is > > now pointing/binding to z, you have to understand the object behavior > > anyway. I do not see how this is different in the set/getself() case. > > Let's suppose that frob() returns something that has a __getself__ > method. Will f1 trigger its call? Will f2? If the answer is "yes" to > both, then when ISN'T getself called? If the answer is "no" to both, What's the problem for the "yes" case? If you define such an object of course __get/setself__() is always called, and f1() is still equal to f2(). > then when IS it called? And if they're different, then you have the > refactoring headache that I described. That's a problem that simply > doesn't happen with descriptors, because this example is using local > variables - local variables are the obvious way to refactor anything. What's the point if it is never called? I cannot make any sense from this example unfortunately, maybe I am too dumb ... > You're proposing allowing values to redefine local variables. That is > completely different from descriptors and other forms of magic, which > allow a namespace to define how it behaves. First, this is not my proposal. The one I had is a new operator, and it is NOT allowing values to redefine local variables. But I do like this one a lot more indeed. Second, isn't descriptor doing exactly the same thing, but just within your so called "namespace"? Isn't the top level itself a namespace? isn't every function local itself a namespace? The entire descriptor concept in my view is a awkward concept that is having too many odds and special cases. And this one, on the other hand, is truly generic and universal. > I'm basically done trying to explain this to you. Multiple people have > tried to explain how this is NOT the same as descriptors, and you keep > coming back to "but descriptors can do this too". They cannot. You are > granting magical powers to *values*, not to namespaces. That makes > basically ALL code impossible to reason about. Sheep can never explain to wolfs why it is a good idea to be vegetarian, can they? And like wise vice versa. Please help to teach me and trust that a 10 years python developer could still learn a thing or two. And don't be too childish ;-) I really just don't get the point (if there is one). ___ 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/NLN3VZJNS5FD5VUKTAV7GLIPX662ABPF/ Code of Conduct: http://python.org/psf/codeofconduct/
[Python-ideas] Re: A proposal (and implementation) to add assignment and LOAD overloading
On 06/26/2019 07:34 AM, Anders Hovmöller wrote: I 100% agree that this proposal is a bad idea. But I do have to play Devils advocate here. The the-code-is-understandable-at-face-value ship has already sailed. + doesn't mean add, it means calling a dunder function that can do anything. True, it can do anything -- but if the thing it does is not related to combining two things together and returning the result, people will be surprised and consider it a bad function. (Or they should. ;-) Foo.bar = 1 doesn't mean set bar to 1 but calling a dunder method. But the `Foo.` tells us Magic May Be Happening, and we still expect something reasonable to occur -- perhaps a boundary check, maybe a cache lookup, perhaps a type change to an equal-but-different representation (1.0 instead of 1, for example), or even setting other dependent variables. -- ~Ethan~ ___ 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/M4TZ2XZZJFUDGPIWKXGN3JJ2B22JC3CQ/ Code of Conduct: http://python.org/psf/codeofconduct/
[Python-ideas] Re: A proposal (and implementation) to add assignment and LOAD overloading
On Thu, Jun 27, 2019 at 5:29 AM Yanghao Hua wrote: > > On Wed, Jun 26, 2019 at 4:47 PM Chris Angelico wrote: > [...] > > There are many things that can be implemented with dunders, yes, but > > in Python, I would expect these two functions to behave identically: > > > > def f1(x): > > return frob(x).spam > > > > def f2(x): > > f = frob(x) > > s = f.spam > > return s > > > > This correlation is critical to sane refactoring. You should be able > > to transform f1 into f2, and then insert print calls to see what 'f' > > and 's' are, without affecting the behaviour of the function. The > > proposed magic would change and completely break this; and as such, it > > violates programmer expectations *across many languages* regarding > > refactoring. > > Chris, I might need a bit more education here. I am trying to guess > what you meant to say here is if in f2(), f or s is already defined, > it will then change the "usual" understanding. In this case, I am > assuming when you start to assign in f2() a local variable f or s with > an object that has __set/getself__(), then you know later on assigning > to it will mean differently. How is this different from descriptors? > when you do x.y = z and if y is a descriptor you don't expect x.y is > now pointing/binding to z, you have to understand the object behavior > anyway. I do not see how this is different in the set/getself() case. Let's suppose that frob() returns something that has a __getself__ method. Will f1 trigger its call? Will f2? If the answer is "yes" to both, then when ISN'T getself called? If the answer is "no" to both, then when IS it called? And if they're different, then you have the refactoring headache that I described. That's a problem that simply doesn't happen with descriptors, because this example is using local variables - local variables are the obvious way to refactor anything. You're proposing allowing values to redefine local variables. That is completely different from descriptors and other forms of magic, which allow a namespace to define how it behaves. I'm basically done trying to explain this to you. Multiple people have tried to explain how this is NOT the same as descriptors, and you keep coming back to "but descriptors can do this too". They cannot. You are granting magical powers to *values*, not to namespaces. That makes basically ALL code impossible to reason about. 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/AXWHQJD7X3B2UCLIDTMZWBRCX2MTKCIQ/ Code of Conduct: http://python.org/psf/codeofconduct/
[Python-ideas] Re: A proposal (and implementation) to add assignment and LOAD overloading
On Wed, Jun 26, 2019 at 4:47 PM Chris Angelico wrote: [...] > There are many things that can be implemented with dunders, yes, but > in Python, I would expect these two functions to behave identically: > > def f1(x): > return frob(x).spam > > def f2(x): > f = frob(x) > s = f.spam > return s > > This correlation is critical to sane refactoring. You should be able > to transform f1 into f2, and then insert print calls to see what 'f' > and 's' are, without affecting the behaviour of the function. The > proposed magic would change and completely break this; and as such, it > violates programmer expectations *across many languages* regarding > refactoring. Chris, I might need a bit more education here. I am trying to guess what you meant to say here is if in f2(), f or s is already defined, it will then change the "usual" understanding. In this case, I am assuming when you start to assign in f2() a local variable f or s with an object that has __set/getself__(), then you know later on assigning to it will mean differently. How is this different from descriptors? when you do x.y = z and if y is a descriptor you don't expect x.y is now pointing/binding to z, you have to understand the object behavior anyway. I do not see how this is different in the set/getself() case. ___ 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/2N7QGYNTQAIEYU6TOPVGFEZW4DZ56PHZ/ Code of Conduct: http://python.org/psf/codeofconduct/
[Python-ideas] Re: Proposal: Using % sign for percentage
What if we had reverse format strings, i.e. reading formatted input? x = readf("{:.0%}", "50%") # => x == 0.50 x = readf("{:.0}", "50") # => x == 0.50 Readf takes the repr() of its second argument and “un-formats” the string. ___ 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/DHACYJQLXNXLQCD3STGPQOQVNQ2AUZFE/ Code of Conduct: http://python.org/psf/codeofconduct/
[Python-ideas] Re: A proposal (and implementation) to add assignment and LOAD overloading
On Thu, Jun 27, 2019 at 1:41 AM Anders Hovmöller wrote: > > On 26 Jun 2019, at 16:46, Chris Angelico wrote: > > There are many things that can be implemented with dunders, yes, but > > in Python, I would expect these two functions to behave identically: > > > > def f1(x): > >return frob(x).spam > > > > def f2(x): > >f = frob(x) > >s = f.spam > >return s > > > > This correlation is critical to sane refactoring. You should be able > > to transform f1 into f2, and then insert print calls to see what 'f' > > and 's' are, without affecting the behaviour of the function. The > > proposed magic would change and completely break this; and as such, it > > violates programmer expectations *across many languages* regarding > > refactoring. > > I'm out of the game for many years but isn't that potentially extremely > different in C++ for example? In C++, there's awkwardnesses with simply returning a struct, so I'm going to tweak it so it returns a pointer instead (which is more equivalent to what Python does; also, it avoids questions of whether the object still exists - not an issue in Python because it's garbage collected). int f1(const char *x) { return frob(x)->spam(); } int f2(const char *x) { status *f = frob(x); int s = f->spam(); return s; } I don't think you can define what "f->spam" means, so I turned that into an actual method call, too. In any case, the refactoring is still valid, and the disassembly of these two functions will probably be identical (since C++ compilers are allowed to optimize out local variables). Point is, breaking a single expression into multiple sub-expressions is a standard action [1] when refactoring, and it should always be safe. Any time it isn't, you probably have either an awful language or an awful codebase. And you should post something to TheDailyWTF. ChrisA [1] meaning you can do one of them each round of combat, and still have enough time for a move action ___ 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/EBARLGWZGNUT2RNUWT7DELO4PDEGIAWI/ Code of Conduct: http://python.org/psf/codeofconduct/
[Python-ideas] Re: A proposal (and implementation) to add assignment and LOAD overloading (was: (Re: Re: Overloading assignment concrete proposal (Re: Re: Operator as first class citizens -- like in s
Stephen, Thanks for the reply, it is a busy day at work today, so it is going to take me a little bit of time to sit down and really process all you have said. I wanted to drop you a message though and link you to the examples that I mentioned. https://github.com/natelust/CloakingVarWriteup/blob/master/examples.py . If you want to see them in context with the outputs (to save cloning and building my patched python) they can be found at the end of this document: https://github.com/natelust/CloakingVarWriteup/blob/master/writeup.md. A direct link to the interpreter changes that support this can be found here: https://github.com/natelust/cpython/commit/3b3714694b9cd9e2b1b706661765050c363ce35a, in case there is any question on how things are working, or just general interest. I do appreciate you, and everyone, taking their time to weight in on this, as it is very educational. Once I have a bit of spare brain power, I will fully process what you wrote and may have additional questions. Thank you On Wed, Jun 26, 2019 at 3:12 AM Stephen J. Turnbull < turnbull.stephen...@u.tsukuba.ac.jp> wrote: > nate lust writes: > > > On first read, that may be surprising, but it extends a behavior > > pattern that already exists for things like properties (and > > generically descriptors) to object instances themselves. > > I don't think that's a correct interpretation. In all cases of > assignment, a name is rebound (in some sense) in a separate namespace. > In the case of an attribute, that namespace us explicit. It *is* the > object, and we know the object's type: the type of objects that have > that attribute. (Circular, do you say? Well, that circularity is the > essence of duck typing.) > > What you want to do is make some object its own namespace, and that > breaks the connection between "bare" names and the implicit namespace > of the module or function that contains it. Your proposal will set > magic loose in the world: it is no longer possible to reason with > confidence about the behavior of objects denoted by bare names > locally. This is action at a distance on *every name in a program*. > > Attribute notation makes action at a distance (ie, the interaction > with other attributes of that object inherited from the caller) > explicit. That's good; combination of mutable attributes which > persist through a function invocation is the essence of object- > oriented programming. But it needs to be explicit or brains will > explode (more likely, they'll implode: instead of trying to figure out > whether an involutary namespace is present, developers will just go > ahead and assume it isn't, and pray they have a new job before it > blows up). > > Ben's post parallel to this one explains detailed examples of How > Things Can Go Wrong. > > I'm -1 on this (truncated from -1000). Python's simple, easy-to- > reason about behavior for assignments should not be messed with. > __getself__ and __setself__ are good names if we're going to have the > behavior, but it should be explicitly attached to an operator, not > invoked implicitly by assignment. (FWIW, I don't yet see a need for > the behavior, but I'm waiting on promised examples.) > > Steve > -- Nate Lust, PhD. Astrophysics Dept. Princeton University ___ 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/345L35IAEX5AYRXZFDDSQCT2BBB5NTMK/ Code of Conduct: http://python.org/psf/codeofconduct/
[Python-ideas] Re: A proposal (and implementation) to add assignment and LOAD overloading
> On 26 Jun 2019, at 16:46, Chris Angelico wrote: > >> On Thu, Jun 27, 2019 at 12:37 AM Anders Hovmöller >> wrote: >> On 26 Jun 2019, at 14:28, Rhodri James wrote: On 26/06/2019 08:34, Yanghao Hua wrote: I find the objection reasoning very strange as none of the default behavior changed, and yet if you use this feature you do need to worry about the object behavior regarding assignment, this is true for descriptors and all other magics. >>> >>> The problem is not the default behaviour. The problem is that the average >>> reader of your code cannot know that something that appears to be an >>> ordinary assignment has been redefined elsewhere to be something entirely >>> herring. Your code stops being understandable to other people. >> >> I 100% agree that this proposal is a bad idea. But I do have to play Devils >> advocate here. >> >> The the-code-is-understandable-at-face-value ship has already sailed. + >> doesn't mean add, it means calling a dunder function that can do anything. >> Foo.bar = 1 doesn't mean set bar to 1 but calling a dunder method. In python >> code basically can't be understood at face value. >> > > There are many things that can be implemented with dunders, yes, but > in Python, I would expect these two functions to behave identically: > > def f1(x): >return frob(x).spam > > def f2(x): >f = frob(x) >s = f.spam >return s > > This correlation is critical to sane refactoring. You should be able > to transform f1 into f2, and then insert print calls to see what 'f' > and 's' are, without affecting the behaviour of the function. The > proposed magic would change and completely break this; and as such, it > violates programmer expectations *across many languages* regarding > refactoring. I'm out of the game for many years but isn't that potentially extremely different in C++ for example? / Anders ___ 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/YMHEUHBCRNN6PEAPOTA6NWBKB5GCPKJS/ Code of Conduct: http://python.org/psf/codeofconduct/
[Python-ideas] Re: A proposal (and implementation) to add assignment and LOAD overloading
On Thu, Jun 27, 2019 at 12:37 AM Anders Hovmöller wrote: > > > On 26 Jun 2019, at 14:28, Rhodri James wrote: > > > >> On 26/06/2019 08:34, Yanghao Hua wrote: > >> I find the objection reasoning very strange as none of the default > >> behavior changed, and yet if you use this feature you do need to worry > >> about the object behavior regarding assignment, this is true for > >> descriptors and all other magics. > > > > The problem is not the default behaviour. The problem is that the average > > reader of your code cannot know that something that appears to be an > > ordinary assignment has been redefined elsewhere to be something entirely > > herring. Your code stops being understandable to other people. > > I 100% agree that this proposal is a bad idea. But I do have to play Devils > advocate here. > > The the-code-is-understandable-at-face-value ship has already sailed. + > doesn't mean add, it means calling a dunder function that can do anything. > Foo.bar = 1 doesn't mean set bar to 1 but calling a dunder method. In python > code basically can't be understood at face value. > There are many things that can be implemented with dunders, yes, but in Python, I would expect these two functions to behave identically: def f1(x): return frob(x).spam def f2(x): f = frob(x) s = f.spam return s This correlation is critical to sane refactoring. You should be able to transform f1 into f2, and then insert print calls to see what 'f' and 's' are, without affecting the behaviour of the function. The proposed magic would change and completely break this; and as such, it violates programmer expectations *across many languages* regarding refactoring. 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/G5MGMNL2XYTF457F2HS7K5JU4P2UZXVA/ Code of Conduct: http://python.org/psf/codeofconduct/
[Python-ideas] Re: A proposal (and implementation) to add assignment and LOAD overloading
> On 26 Jun 2019, at 14:28, Rhodri James wrote: > >> On 26/06/2019 08:34, Yanghao Hua wrote: >> I find the objection reasoning very strange as none of the default >> behavior changed, and yet if you use this feature you do need to worry >> about the object behavior regarding assignment, this is true for >> descriptors and all other magics. > > The problem is not the default behaviour. The problem is that the average > reader of your code cannot know that something that appears to be an ordinary > assignment has been redefined elsewhere to be something entirely herring. > Your code stops being understandable to other people. I 100% agree that this proposal is a bad idea. But I do have to play Devils advocate here. The the-code-is-understandable-at-face-value ship has already sailed. + doesn't mean add, it means calling a dunder function that can do anything. Foo.bar = 1 doesn't mean set bar to 1 but calling a dunder method. In python code basically can't be understood at face value. / Anders ___ 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/QC7GUH6RHHKEYNSWILCTWRTZORC2LMCQ/ Code of Conduct: http://python.org/psf/codeofconduct/
[Python-ideas] Re: A proposal (and implementation) to add assignment and LOAD overloading
On 26/06/2019 08:34, Yanghao Hua wrote: I find the objection reasoning very strange as none of the default behavior changed, and yet if you use this feature you do need to worry about the object behavior regarding assignment, this is true for descriptors and all other magics. The problem is not the default behaviour. The problem is that the average reader of your code cannot know that something that appears to be an ordinary assignment has been redefined elsewhere to be something entirely herring. Your code stops being understandable to other people. The thing I keep coming back to in this whole discussion is the Zen line "Explicit is better than implicit". -- Rhodri James *-* Kynesim Ltd ___ 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/4CKDYSYN3JVALYZZDR4LO2HHO2FCNBJ5/ Code of Conduct: http://python.org/psf/codeofconduct/
[Python-ideas] Re: A proposal (and implementation) to add assignment and LOAD overloading (was: (Re: Re: Overloading assignment concrete proposal (Re: Re: Operator as first class citizens -- like in s
On Tue, Jun 25, 2019 at 11:01 PM nate lust wrote: > > This message is related to two previous threads, but was a sufficiently > evolved to warrant a new topic. > > I am proposing that two new magic methods be added to python that will > control assignment and loading of class > instances. This means that if an instance is bound to a variable name, any > attempts to rebind that name will > result in a call to the __setself__ (name negotiable) of the instance already > bound to that name. Likewise > when a class instance bound to a name is loaded by the interpreter, if > present, the __getself__ method of that > instance will be called and its result will be returned instead. I have been > internally calling these cloaking > variables as they "cloak" the underlying instance, parallelling the idea of > shadowing. Feel free to suggest > better names. Very interesting and this will be much better than introducing new operators for DSLs! This makes Python finally treating "=" operator symmetric as rest of the operators, and I will definitely stop using descriptors forever if this feature gets accepted! I find the objection reasoning very strange as none of the default behavior changed, and yet if you use this feature you do need to worry about the object behavior regarding assignment, this is true for descriptors and all other magics. ___ 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/BMBEOGRTSNIG76NOXHTWF6NYKPEEMZYG/ Code of Conduct: http://python.org/psf/codeofconduct/
[Python-ideas] A proposal (and implementation) to add assignment and LOAD overloading (was: (Re: Re: Overloading assignment concrete proposal (Re: Re: Operator as first class citizens -- like in scala
nate lust writes: > On first read, that may be surprising, but it extends a behavior > pattern that already exists for things like properties (and > generically descriptors) to object instances themselves. I don't think that's a correct interpretation. In all cases of assignment, a name is rebound (in some sense) in a separate namespace. In the case of an attribute, that namespace us explicit. It *is* the object, and we know the object's type: the type of objects that have that attribute. (Circular, do you say? Well, that circularity is the essence of duck typing.) What you want to do is make some object its own namespace, and that breaks the connection between "bare" names and the implicit namespace of the module or function that contains it. Your proposal will set magic loose in the world: it is no longer possible to reason with confidence about the behavior of objects denoted by bare names locally. This is action at a distance on *every name in a program*. Attribute notation makes action at a distance (ie, the interaction with other attributes of that object inherited from the caller) explicit. That's good; combination of mutable attributes which persist through a function invocation is the essence of object- oriented programming. But it needs to be explicit or brains will explode (more likely, they'll implode: instead of trying to figure out whether an involutary namespace is present, developers will just go ahead and assume it isn't, and pray they have a new job before it blows up). Ben's post parallel to this one explains detailed examples of How Things Can Go Wrong. I'm -1 on this (truncated from -1000). Python's simple, easy-to- reason about behavior for assignments should not be messed with. __getself__ and __setself__ are good names if we're going to have the behavior, but it should be explicitly attached to an operator, not invoked implicitly by assignment. (FWIW, I don't yet see a need for the behavior, but I'm waiting on promised examples.) 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/SXNCLX7SP2RB2DYSGPMSI3OU3WZVGDMF/ Code of Conduct: http://python.org/psf/codeofconduct/