Richard Musil wrote:
> I had an idea for an abstract representation of the feature Nutchanon
> described. Let's call it aliasing and let's define it intuitively:
> a = 1
> b alias a
> print(b) -> 1
> b = 2
> print(a) -> 2
> The abstract representation would define a new construct
> _aliased_identifier_ (aid in short), which will behave exactly as the
> "normal" identifier behaves now. Now the Python identifier is basically a
> restricted string literal. The new aliased identifier will be a set of
> current identifiers. I am not saying it needs to be implemented as a Python
> set (it could be namespace, tuple, list, etc.), but feature-wise it will be
> a set - without ordering and with only unique members.
> Using Python "repr() style", one can write for example an aid with only one
> identifier called 'a' as aid('a').
> Whenever the code uses an identifier, it will be using the aid which
> contains the corresponding identifier and technically, writing:
> a = 1, will mean under the hood
> aid('a') = 1.
> The important property of the aid is that it behaves the same as an
> identifier now, so it can bind to only one object.
> The other important property is that the regular identifier can be present
> in only one aid, because the identifier has to identify this aid in a
> unique way.
> Therefore it is not possible to have aid('a', 'b') and aid('b', 'c'),
> because 'b' does not identify a unique aid.
> Now executing:
> b alias a, will translate to:
> 'b' alias aid('a') => aid('a').add('b') = aid('a', 'b').
> while preserving the binding aid('a') had before (if it had any).
> after that, whenever the code uses 'a' identifier, or 'b' identifier it
> will mean the same aid('a', 'b').
> aids should behave as the identifiers today, except for the aliasing and
> unaliasing commands (unaliasing done by 'del' in the example below).
> For example, what happens if I do:
> a = 1 => aid('a') = 1
> b alias a => aid('a', 'b') refers to the original object 1
> c = 2 => aid('c') = 2
> d alias c => aid('c', 'd') refers to the original object 2
> Now what to do when:
> b alias c
> => aid('c', 'd'),add('b') = aid('b', 'c', 'd') and refer to the object
> aid('c', 'd') referred before, i.e. 2
> but at the same time 'b' has to be removed from aid('a', 'b'), so we need
> to define:
> del b => aid('a', 'b').remove('b') => aid('a'), 'b' does not identify
> anything anymore, aid('a') still holds the reference.
> or if 'b' represents only simple aid('b') then
> del b => aid('b').remove('b') => 'b' does not exist anymore
> Can I alias an identifier to the item of the list, dict, etc.? No, because
> a[10] or d['key'] are not identifiers. I can make an alias to 'a' or 'd'
> though.
> The same principle can be applied to types, functions, etc. Running 'dir'
> should return aids though, not plain identifiers, but since each aid is
> uniquely identifiable by anyone of its member identifiers, dir could return
> only identifiers with an assumption that each identifier represents an aid
> to which it belongs.
> I expect that this abstraction can be used to build the behavior of the
> aids as an analogy to how identifiers behave today. It can also point to
> the problems, for example do we need to make the aids hashable, or how to
> make the identifiers in them searchable, etc.
> The implementation can be an additional attribute on an identifier, which
> will list the additional aliases (if any was defined). The interpreter will
> have to check this attribute and eventually search it for matching
> identifier (or perform some other search to find the matching aid for a
> given id).
> Richard
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.
```python
a = large_object()
b alias a # now aid('a,'b')
c alias a # now aid('a', 'b', 'c')
# To free mem. as Richard propose
del a # remain aid('b', 'c') cannot free mem
del b # remain aid('c') cannot free mem
del c # can free mem
```
Also, note that this is the same as Python chain assignment.
```python
# 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
```
My propose is `del` should un-bind all aliases at once. And still keep
aliasing status until `unaid() or unaid_all()` is explicitly called.
```python
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.
# To "un-alias"
unaid a # a is un-aliased. b, c are still aliases.
a alias b # a, b, c are aliases again.
a = heavy_object() # aid('a', 'b', 'c') = heavy_object()
unaid_all a # all are unaliased. but, each is not unbind to the object.
assert a is b and b is c # will be true.
```
Nutchanon
_______________________________________________
Python-ideas mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at
https://mail.python.org/archives/list/[email protected]/message/AMCJEWKOGZUIOES5UUIXODZKQL3BE6NY/
Code of Conduct: http://python.org/psf/codeofconduct/