Python from Wise Guy's Viewpoint

Jacques Garrigue see at my.signature
Wed Oct 29 22:33:05 EST 2003


Pascal Costanza <costanza at web.de> writes:

> Matthias Blume wrote:
> 
> >>No, it's not. There's a class of programs that exhibit a certain
> >>behavior at runtime that you cannot write in a statically typed
> >>language _directly in the language itself_.
> > 
> > This is simply not true.  See above.
> 
> OK, let's try to distill this to some simple questions.
> 
> Assume you have a compiler ML->CL that translates an arbitrary ML 
> program with a main function into Common Lisp. The main function is a 
> distinguished function that starts the program (similar to main in C). 
> The result is a Common Lisp program that behaves exactly like its ML 
> counterpart, including the fact that it doesn't throw any type errors at 
> runtime.
> 
> Assume furthermore that ML->CL retains the explicit type annotations in 
> the result of the translation in the form of comments, so that another 
> compiler CL->ML can fully reconstruct the original ML program without 
> manual help.
> 
> Now we can modify the result of ML->CL for any ML program as follows. We 
> add a new function that is defined as follows:
> 
> (defun new-main ()
>    (loop (print (eval (read)))))
> 
> (We assume that NEW-MAIN is a name that isn't defined in the rest of the 
> original program. Otherwise, it's easy to automatically generate a 
> different unique name.)
> 
> Note that we haven't written an interpreter/compiler by ourselves here, 
> we just use what the language offers by default.
> 
> Furthermore, we add the following to the program: We write a function 
> RUN (again a unique name) that spawns two threads. The first thread 
> starts the original main function, the second thread opens a console 
> window and starts NEW-MAIN.
> 
> Now, RUN is a function that executes the original ML program (as 
> translated by ML->CL, with the same semantics, including the fact that 
> it doesn't throw any runtime type errors in its form as generated by 
> ML->CL), but furthermore executes a read-eval-print-loop that allows 
> modification of the internals of that original program in arbitrary 
> ways. For example, the console allows you to use DEFUN to redefine an 
> arbitrary function of the original program that runs in the first 
> thread, so that the original definition is not visible anymore and all 
> calls to the original definiton within the first thread use the new 
> definition after the redefinition is completed. [1]
> 
> Now here come the questions.
> 
> Is it possible to modify CL->ML in a way that any program originally 
> written in ML, translated with ML->CL, and then modified as sketched 
> above (including NEW-MAIN and RUN) can be translated back to ML? For the 
> sake of simplicity we can assume an implementation of ML that already 
> offers multithreading. Again, for the sake of simplicity, it's 
> acceptable that the result of CL->ML accepts ML as an input language for 
> the read-eval-print-loop in RUN instead of Common Lisp. The important 
> thing here is that redefinitions issued in the second thread should 
> affect the internals of the program running in the first thread, as 
> described above.

You have an interesting point here, but it is only partly related to
static typing. It is more about static binding vs. dynamic binding.
That is, are you able to dynamically change the definition of any
identifier in the language.
One must recognizes that dynamically typed systems, in particular Lisp
and Smalltalk, also give you full dynamic binding, and that this is an
incredibly powerful feature, at least for developpers.

Now, would it be possible to do it in a statically typed language?
I don't see why not. Some parts are relatively easy: allowing you to
change function definitions, as long as you don't change the type.  I
say only relatively, because polymorphism may get in your way: you
would have to replace any polymorphic function by a function at least
as polymorphic as it, whether this polymorphism is really needed by
the rest of the program or not.

Some parts are much more difficult: how to change the data
representation dynamically. This is already difficult in dynamically
typed language (you must introduce lots of kludges to convert the data
on the fly, probably on an as-needed basis), but in a statically typed
language this must be expressed at the level of types. Matthias'
argument would be that anyway you need to do some formal reasonning to
prove that, knowing the dataflow of your program, you have indeed
introduced all the needed conversions and kludges in you dynamically
typed program, and that this reasonning could be converted to some
kind of types, but this is going to be very hard. The most I know
about this is some work on data versionning, but it doesn't consider
modifications inside a running program.

I'm willing to concede you the point: there may be applications where
you want this ability to dynamically modify the internals of your
program, and, while knowing this is just going to be damned dangerous,
a fully dynamic (both types and binding) language is your only way to
be sure that you will be able to do all and every possible changes.
But these applications strike me as being of the high availability
kind, so that the very fact this is so dangerous may be a major
concern.

On the other hand, in the huge majority of cases, this feature is only
used during program development, and once you're done you compile and
optimize, and optimizing actually means loosing most of the dynamic
binding to allow inlining.
In those cases, clever statically typed languages like ML compensate
for their staticness in various ways, for instance by allowing
efficient separate compilation as long as interfaces do not change.
You may have to restart your program, but do not loose much time for
that. And since more bugs are caught by the type system, the need to
correct them is less frequent. You are also provided with an
interactive toplevel, which lets you change some of the definitions at
runtime, at least those functions and variables you have explicitly
declared as mutable. Static typing does not prevent you from running
and modifying interactively a GUI application, it just restricts the
extent of the modifications you can do.

(Contrary to Matthias I'm a purely static guy, but I've always been
attracted by those fancy dynamic development environments.)

---------------------------------------------------------------------------
Jacques Garrigue      Kyoto University     garrigue at kurims.kyoto-u.ac.jp
		<A HREF=http://wwwfun.kurims.kyoto-u.ac.jp/~garrigue/>JG</A>




More information about the Python-list mailing list