Updated information on Dianne Hackborn's old vref proposal. A copy of
her original proposal has been included as an appendix, since it is hard to get since DejaNews lost their old archives.
This commit is contained in:
parent
655cf91b3a
commit
7626095211
162
pep-0205.txt
162
pep-0205.txt
|
@ -103,17 +103,14 @@ Weak References in Java
|
|||
|
||||
Previous Weak Reference Work in Python
|
||||
|
||||
Diane Hackborn's vref proposal. 'vref' objects were very similar
|
||||
to java.lang.ref.WeakReference objects, except there was no
|
||||
equivalent to the invalidation queues. Implementing a "weak
|
||||
dictionary" would be just as difficult as using only weak
|
||||
references (without the invalidation queue) in Java. Information
|
||||
on this has disappeared from the Web. Original discussion
|
||||
occurred in the comp.lang.python newsgroup; a good archive of that
|
||||
may turn up something more.
|
||||
|
||||
Dianne doesn't have any record of her proposal, and doesn't recall
|
||||
doing an implementation.
|
||||
Dianne Hackborn's proposed something called "virtual references".
|
||||
'vref' objects were very similar to java.lang.ref.WeakReference
|
||||
objects, except there was no equivalent to the invalidation
|
||||
queues. Implementing a "weak dictionary" would be just as
|
||||
difficult as using only weak references (without the invalidation
|
||||
queue) in Java. Information on this has disappeared from the Web.
|
||||
Original discussion occurred in the comp.lang.python newsgroup; a
|
||||
good archive of that may turn up something more.
|
||||
|
||||
Marc-André Lemburg's mx.Proxy package. These Web pages appear to
|
||||
be unavailable at the moment.
|
||||
|
@ -127,12 +124,21 @@ Previous Weak Reference Work in Python
|
|||
|
||||
http://www.handshake.de/~dieter/weakdict.html
|
||||
|
||||
PyWeakReference by Alex Shindich:
|
||||
|
||||
http://sourceforge.net/projects/pyweakreference/
|
||||
|
||||
|
||||
Possible Applications
|
||||
|
||||
PyGTK+ bindings?
|
||||
|
||||
Tkinter?
|
||||
Tkinter -- could avoid circular references by using weak
|
||||
references from widgets to their parents. Objects won't be
|
||||
discarded any sooner in the typical case, but there won't be so
|
||||
much dependence on the programmer calling .destroy() before
|
||||
releasing a reference. This would mostly benefit long-running
|
||||
applications.
|
||||
|
||||
DOM trees?
|
||||
|
||||
|
@ -142,6 +148,138 @@ Proposed Implementation
|
|||
XXX -- Not yet.
|
||||
|
||||
|
||||
Appendix -- Dianne Hackborn's vref proposal (1995)
|
||||
|
||||
[This has been indented and paragraphs reflowed, but there have be
|
||||
no content changes. --Fred]
|
||||
|
||||
Proposal: Virtual References
|
||||
|
||||
In an attempt to partly address the recurring discussion
|
||||
concerning reference counting vs. garbage collection, I would like
|
||||
to propose an extension to Python which should help in the
|
||||
creation of "well structured" cyclic graphs. In particular, it
|
||||
should allow at least trees with parent back-pointers and
|
||||
doubly-linked lists to be created without worry about cycles.
|
||||
|
||||
The basic mechanism I'd like to propose is that of a "virtual
|
||||
reference," or a "vref" from here on out. A vref is essentially a
|
||||
handle on an object that does not increment the object's reference
|
||||
count. This means that holding a vref on an object will not keep
|
||||
the object from being destroyed. This would allow the Python
|
||||
programmer, for example, to create the aforementioned tree
|
||||
structure tree structure, which is automatically destroyed when it
|
||||
is no longer in use -- by making all of the parent back-references
|
||||
into vrefs, they no longer create reference cycles which keep the
|
||||
tree from being destroyed.
|
||||
|
||||
In order to implement this mechanism, the Python core must ensure
|
||||
that no -real- pointers are ever left referencing objects that no
|
||||
longer exist. The implementation I would like to propose involves
|
||||
two basic additions to the current Python system:
|
||||
|
||||
1. A new "vref" type, through which the Python programmer creates
|
||||
and manipulates virtual references. Internally, it is
|
||||
basically a C-level Python object with a pointer to the Python
|
||||
object it is a reference to. Unlike all other Python code,
|
||||
however, it does not change the reference count of this object.
|
||||
In addition, it includes two pointers to implement a
|
||||
doubly-linked list, which is used below.
|
||||
|
||||
2. The addition of a new field to the basic Python object
|
||||
[PyObject_Head in object.h], which is either NULL, or points to
|
||||
the head of a list of all vref objects that reference it. When
|
||||
a vref object attaches itself to another object, it adds itself
|
||||
to this linked list. Then, if an object with any vrefs on it
|
||||
is deallocated, it may walk this list and ensure that all of
|
||||
the vrefs on it point to some safe value, e.g. Nothing.
|
||||
|
||||
|
||||
This implementation should hopefully have a minimal impact on the
|
||||
current Python core -- when no vrefs exist, it should only add one
|
||||
pointer to all objects, and a check for a NULL pointer every time
|
||||
an object is deallocated.
|
||||
|
||||
Back at the Python language level, I have considered two possible
|
||||
semantics for the vref object --
|
||||
|
||||
==> Pointer semantics:
|
||||
|
||||
In this model, a vref behaves essentially like a Python-level
|
||||
pointer; the Python program must explicitly dereference the vref
|
||||
to manipulate the actual object it references.
|
||||
|
||||
An example vref module using this model could include the
|
||||
function "new"; When used as 'MyVref = vref.new(MyObject)', it
|
||||
returns a new vref object such that that MyVref.object ==
|
||||
MyObject. MyVref.object would then change to Nothing if
|
||||
MyObject is ever deallocated.
|
||||
|
||||
For a concrete example, we may introduce some new C-style syntax:
|
||||
|
||||
& -- unary operator, creates a vref on an object, same as vref.new().
|
||||
* -- unary operator, dereference a vref, same as VrefObject.object.
|
||||
|
||||
We can then define:
|
||||
|
||||
1. type(&MyObject) == vref.VrefType
|
||||
2. *(&MyObject) == MyObject
|
||||
3. (*(&MyObject)).attr == MyObject.attr
|
||||
4. &&MyObject == Nothing
|
||||
5. *MyObject -> exception
|
||||
|
||||
Rule #4 is subtle, but comes about because we have made a vref
|
||||
to (a vref with no real references). Thus the outer vref is
|
||||
cleared to Nothing when the inner one inevitably disappears.
|
||||
|
||||
==> Proxy semantics:
|
||||
|
||||
In this model, the Python programmer manipulates vref objects
|
||||
just as if she were manipulating the object it is a reference
|
||||
of. This is accomplished by implementing the vref so that all
|
||||
operations on it are redirected to its referenced object. With
|
||||
this model, the dereference operator (*) no longer makes sense;
|
||||
instead, we have only the reference operator (&), and define:
|
||||
|
||||
1. type(&MyObject) == type(MyObject)
|
||||
2. &MyObject == MyObject
|
||||
3. (&MyObject).attr == MyObject.attr
|
||||
4. &&MyObject == MyObject
|
||||
|
||||
Again, rule #4 is important -- here, the outer vref is in fact a
|
||||
reference to the original object, and -not- the inner vref.
|
||||
This is because all operations applied to a vref actually apply
|
||||
to its object, so that creating a vref of a vref actually
|
||||
results in creating a vref of the latter's object.
|
||||
|
||||
The first, pointer semantics, has the advantage that it would be
|
||||
very easy to implement; the vref type is extremely simple,
|
||||
requiring at minimum a single attribute, object, and a function to
|
||||
create a reference.
|
||||
|
||||
However, I really like the proxy semantics. Not only does it put
|
||||
less of a burden on the Python programmer, but it allows you to do
|
||||
nice things like use a vref anywhere you would use the actual
|
||||
object. Unfortunately, it would probably an extreme pain, if not
|
||||
practically impossible, to implement in the current Python
|
||||
implementation. I do have some thoughts, though, on how to do
|
||||
this, if it seems interesting; one possibility is to introduce new
|
||||
type-checking functions which handle the vref. This would
|
||||
hopefully older C modules which don't expect vrefs to simply
|
||||
return a type error, until they can be fixed.
|
||||
|
||||
Finally, there are some other additional capabilities that this
|
||||
system could provide. One that seems particularily interesting to
|
||||
me involves allowing the Python programmer to add "destructor"
|
||||
function to a vref -- this Python function would be called
|
||||
immediately prior to the referenced object being deallocated,
|
||||
allowing a Python program to invisibly attach itself to another
|
||||
object and watch for it to disappear. This seems neat, though I
|
||||
haven't actually come up with any practical uses for it, yet... :)
|
||||
|
||||
-- Dianne
|
||||
|
||||
|
||||
Copyright
|
||||
|
||||
This document has been placed in the public domain.
|
||||
|
|
Loading…
Reference in New Issue