On Wed, May 29, 2019 at 08:56:58AM -0400, Ricky Teachey wrote:
> For the understanding of all, it would help tremendously for you to
> implement a WORKING TOY example showing exactly the behavior you want in
> real (not theoretical) python, maybe something like this as a starting
> point:

I don't think the precise hardware signal behaviour is important. We 
can simplify the whole thing down to a toy example:

    I want to print "Surprise!" whenever I assign a value 
    to a variable.


Or perhaps log the value and target. Whatever the behaviour, we can 
assume Yanghao Hua knows how to implement it, he just needs a hook:

Addition operator + hooks into __add__ and __radd__ 

Equality operator == hooks into __eq__ 

When the assignment target is a dotted name, obj.x, the 
  assignment pseudo-operator = hooks into the descriptor 
  protocol and __setattr__ 

But when the assignment target is a bare name, not an attribute, 
  the assignment "operator" hooks into ... nothing.


So if we cannot hook into assignment, perhaps we could have another 
operator which looks kinda-sorta like assignment. The walrus operator := 
is already taken (as of Python 3.8) but we can invent a new arrow 
operator:

    target <== value

which calls target.__arrow__(value). Yanghao Hua can write his own 
__arrow__ method; he just needs the interpreter to call it.


The obvious solution to customising assignment is to use a dotted 
target:

    obj.x = value


but that doesn't really work. I know in my previous message I said the 
problem was the aesthetics, but on further thought there are more 
problems with it. Suppose you want to pass x to some function:

    # initialise the value
    obj.x = 0
    # pass it to a function
    function( .... what goes here??? ... )


If you write this:

    function(obj.x)

what the function receives is not the special object "obj" with an 
attached "x" attribute, but *the current value of obj.x* alone (in the 
example shown, that would be the plain old int 0). The link to obj is 
lost. But if you write this instead:

    function(obj)

now function needs to know that it has to operate on obj.x rather than 
obj.y or obj.spam or obj.foo. The function is now tightly coupled to the 
name of the attribute. If you have multiple objects with differently 
named attributes, you can only pass one to the function:

    a.x = 0
    b.spam = 0
    function(a)  # hard-codes the attribute name "x"
    function(b)  # fails with AttributeError


We can "fix" this problem by telling function what name to use as a 
seperate argument:

    function(a, "x")  # operates on a.x
    function(b, "spam")  # operates on b.spam


but I'd have to be really, really desperate to write code that 
inelegant.

As far as I can tell, there is no straight forward way in Python to 
pass a dotted reference to a function and have the function see the 
dotted reference itself rather than the value of the dotted reference. 

I *think* that some variation on Call-By-Reference or Call-By-Name 
semantics, as used by Pascal or Algol, might solve this, but we're even 
less likely to get that than we are to get a new operator.


-- 
Steven
_______________________________________________
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to