On Thu, Jun 27, 2019 at 1:41 AM Anders Hovmöller <boxed@killingar.net> wrote:
On 26 Jun 2019, at 16:46, Chris Angelico <rosuav@gmail.com> 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