[Python-ideas] Re: A proposal (and implementation) to add assignment and LOAD overloading

2019-06-26 Thread Stephen J. Turnbull
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) ...]

2019-06-26 Thread Stephen J. Turnbull
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

2019-06-26 Thread nate lust
: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

2019-06-26 Thread Brendan Barnwell

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

2019-06-26 Thread Andrew Barnert via Python-ideas
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

2019-06-26 Thread Greg Ewing

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)

2019-06-26 Thread Chris Angelico
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

2019-06-26 Thread Andrew Barnert via Python-ideas
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

2019-06-26 Thread Greg Ewing

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

2019-06-26 Thread Andrew Barnert via Python-ideas
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

2019-06-26 Thread Andrew Barnert via Python-ideas
 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

2019-06-26 Thread Yanghao Hua
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

2019-06-26 Thread Yanghao Hua
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

2019-06-26 Thread nate lust
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

2019-06-26 Thread nate lust
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

2019-06-26 Thread Chris Angelico
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

2019-06-26 Thread Yanghao Hua
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

2019-06-26 Thread Chris Angelico
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

2019-06-26 Thread Andrew Barnert via Python-ideas
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

2019-06-26 Thread Yanghao Hua
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

2019-06-26 Thread Ethan Furman

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

2019-06-26 Thread Chris Angelico
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

2019-06-26 Thread Yanghao Hua
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

2019-06-26 Thread James Lu
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

2019-06-26 Thread Chris Angelico
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

2019-06-26 Thread nate lust
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

2019-06-26 Thread Anders Hovmöller


> 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

2019-06-26 Thread Chris Angelico
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

2019-06-26 Thread Anders Hovmöller



> 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

2019-06-26 Thread Rhodri James

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

2019-06-26 Thread Yanghao Hua
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

2019-06-26 Thread Stephen J. Turnbull
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/