[Edu-sig] Reloading code (was Re: OLPC: first thoughts)
Paul D. Fernhout
pdfernhout at kurtz-fernhout.com
Sat Feb 24 15:35:00 CET 2007
Andreas-
Here is one post on this issue with code I made previously for Jython:
"ReloaderWindow 0.2 (improvements to selective reloading)"
http://www.arcknowledge.com/gmane.comp.lang.jython.user/2006-01/msg00023.html
This is a different (earlier) approach than for PataPata (PataPata uses
prototypes and overriding __getattr__) and the linked code works with
regular Python classes.
The important thing to understand is that a Python VM manages a world of
objects somewhat like a Smalltalk image, lumping all the objects from all
the loaded modules into the same objectspace. You can just reference some
of them (typically classes) by the way the current hierarchical Python
namespace is set up. When you reload a module, it creates completely new
class objects which just happen to have the same name as the old one and
the namespace now points to those new objects (sort of like if every time
you changed a method in Smalltalk the SystemDictionary Smalltalk was made
to point to entirely new classes, leaving the old ones floating, which
would obviously be a silly thing to do). So any existing instances of
original classes point still to the old classes (which are no longer
referenceable from the namespace).
The various approaches try to get around this in various ways, such as in
my approach above by loading a changed module into a temporary namespace
and then copying the methods from it on top of the old classes. Also,
things get a little more complicate than that, since Python often uses
method pointers, equivalent in some way to Smalltalk blocks, to hook up
GUI systems. So even if you keep the class the same and replace the
methods, your running GUI window typically has bindings by reference to
the old overwritten functions. So, as this approach I outlines does, you
need to also keep the shell of the old functions and just overwrite what
they actually do -- Kind of like if you kept CompiledMethods around and
just overwrote their code. It's an awkward way to do things. Now,
obviously, Smalltalk sometimes fails at updating GUIs when you tie actions
to blocks, where recompiling methods produces new blocks (a big problem in
older VisualWorks apps, not sure of the current status of VisualWorks or
Squeak). Of course, in Smalltalk you could make the block call a method
using a selector, which as least gives you a point of intervention.
Similarly in Python, if you modify code which the bound function
references, that newer code will be called by the old function's code as
dispatch works differently depending whether you have a function pointer
as opposed to an inline reference to another function in a Python
function. In Python, I can get around this by wrapping any function
pointer I give to a GUI callback using an object (like Java :-) where the
callback then calls by name. PataPata did some of that internally, though
obviously it adds extra layers of overhead to every GUI call, plus the
programmer had to proactively add a wrapper, making code uglier, and so on.
In Python, people often build specific hooks into their application to
explicitly reload modules, including sometimes closing and reopening only
one window inside a large application, to try to make the best of this.
There are other attempts to do a more selective reloading like the
approach I give above. Consider for example:
"[Patches] [ python-Patches-1212921 ] option to allow reload to affect
existing instances"
http://mail.python.org/pipermail/patches/2005-September/018060.html
There is some discussion at that link of the issue. And a reference there
to another approach:
http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/160164
From the first patch link: "Brett and I work at the same company. He made
this patch because we were wasting hundreds of hours debugging reload
problems or just quitting the application and restarting. I've
been using this patch now for 3 months. It has saved our company hundreds
of man-hours and we didn't have to change one line of existing code to
make it work. If the community doesn't want to use it, I'm fine with that.
I just want to make sure that you fully understand what you are giving up."
I'm not sure what the disposition of that patch is. But, you can see from
the responses there is a bit of a cultural problem here getting the value
of the idea across.
I did not look at the patch, but from the description I wonder if it still
might suffer from the issue of allowing identities for functions to change
(and so GUIs with actions previously linked to functions would still use
the old behavior).
There is also a more subtle issue for module reloading. Smalltalk is
essentially a declarative language, while Python is essentially an
imperative language (maybe there is a better word?). Essentially,
compiling a Smalltalk class has no side effects (other than perhaps
defining the class). But a Python module on loading can produce lots of
side effects from defining metaclasses to affect future class loading to
executing random bits of code (sort of like Forth in this sense). So, only
modules without these side effects can be easily reloaded. Consider for
example what if your module makes a singleton instance of something --
when you reload it, should it make a new singleton instance and leave the
other one to still perhaps be used by old instances, or should the
singleton instance get upgraded to the new class? Just one of many issues
that happen when you are using Python's textual module reloading paradigm.
Ideally, when you change a method in a text file you probably almost
always want only that specific method to change with everything else being
left alone. But that breaks the Python paradigm. Still, even with this
problem, easier class reloading like I outlined above still gets you great
value when developing new code, especially if you slightly alter how you
layout your new modules with this limitation in mind. But reloading older
code may present you with problems -- making maintenance using this
technique harder.
--Paul Fernhout
Andreas Raab wrote:
> Paul D. Fernhout wrote:
>
>>This "edit and continue" support is much more fine grained and
>>easier to use than reloading Python modules, even with the variants I and
>>others have created.
>
> Where can I find out more about these variants and what they do? We are
> currently trying to enable a workflow that centers around a life
> environment and these issues become important for us. Are there any
> other life environments (besides Patapata which I have looked at) that
> are worth studying?
More information about the Edu-sig
mailing list