On Tue, Sep 24, 2019 at 10:26 AM Nutchanon Ninyawee <me@nutchanon.org> wrote:
Talking about `del` and `unaid()` ("un-alias" or `unlink()` in my previous mention), I think `del` should keep its ability to let garbage collection free the memory.
if we use the keyword del to "unbind" and "un-alias" that could be a mistake.

There are two points:
1) As you wrote later, `del` will only allow garbage collection if the deleted reference was the last one. So it is not an operation on the object itself but on the binding between the identifier and the object. And since there is no notion in Python about the identifier without a binding, the identifier is deleted as well.
Also, note that this is the same as Python chain assignment.
# a,b,c are chain-assigned.
a = b = c = large_object()

# To free mem
del a # remain b,c cannot free mem
del b # remain c cannot free mem
del c # can free mem

2) When I wrote the first version of my idea, I actually defined `del` differently:
a = 1
b alias a
del b
would translate to:
aid('a') = 1
del aid('a', 'b')
which would work exactly as it works now in Python, `del` will remove the binding of aid('a', 'b') to '1', and consequently also delete aid('a', 'b') (because it will be no longer bound to any object). The consequence was that also the aliasing ceases to exist.
While I considered it more true to the `del` behavior as we have now, I was bothered by a confusing aspect that it will basically delete all aliased names as well, and it may not be obvious which or how many they are.

This was the reason why I eventually changed the behavior and let `del` work on aliases and only if the identifier was the last one in an aid remove the binding as well (i.e. as a `del` as we have now). This also kind of matches the today's behavior of the object with multiple references (as in your example). The consequence however is that you have to do `del` on every name in an aid to really release the object. So I guess both approches have some pros and cons.

My propose is `del` should un-bind all aliases at once. And still keep
aliasing status until `unaid() or unaid_all()` is explicitly called.
obj = a = large_object()
b alias a # now aid('a,'b')
c alias a # now aid('a', 'b', 'c')

# To free mem.
del a # aid('b', 'c', 'a')  remains, but aid('b', 'c', 'a') not point to the large_object() anymore
del b # raise NameError
del obj # free mem by delete last reference.

Now, what you propose, does not really have a analogy in current Python. Preserving the aid even when it is not longer bound to any object would mean that things like this will stop to work:
In [1]: a = 1
In [2]: a
Out[2]: 1
In [3]: del a
In [4]: a
NameError                                 Traceback (most recent call last)
<ipython-input-4-3f786850e387> in <module>
----> 1 a
NameError: name 'a' is not defined
In [5]:
Because Python will have to keep all aids once they were created somewhere (it could not distinguish between only one-id aid, and many-id aid, because these could change easily during the lifetime by aliasing or unaliasing).