On Tunes infrastructure

Alaric Snell alaric@alaric-snell.com
Sat May 31 06:19:01 2003

On Saturday 31 May 2003 05:01, Lynn H. Maxson wrote:

> Programs cannot automate themselves through the use of
> other programs beyond the programmed boundaries contained
> in them.  If we as programmers dictate those boundaries by
> our writing of them, no program that we ever write will ever
> extend beyond those boundaries.  In short no program can
> operate outside its own logic.  No program as meta-program
> can either.  Changing the name does not change the limits.

Ah... What the piece you quoted means to me isn't the old sci fi 
miscomprehension of a computer that repograms itself to become sentient, but 
more things like:

1) Making it easier to write compilers. Compilers are metaprograms! What a 
compiler does is well-defined and bounded, but the behaviour of the combined 
system of "compiler plus execution of the results" is bounded merely by the 
capabilities of the hardware :-) Now, most current compilers have to do ugly 
things like generate machine code or output to another language (such as C) 
and then invoke another compiler for that; but systems that have better 
integrated metaprogramming could handle this step much more elegantly. As a 
more extreme example of "programs writing themselves", imagine a system that 
has to emulate a logic circuit. It takes (as input) a description of the 
circuit, uses boolean algebra and Karnaugh maps and so on to optimise the 
description into a basic network of logic functions, then converts that 
network into source code for a function that emulates the logic circuit - a 
function from the boolean values of the inputs to the outputs. With a nice 
"compile()" function it can convert that source code to an actual invocable 
function at run time and proceed to use it to emulate the circuit. Without 
access to a nice "compile()" function it must either just interpret the logic 
circuit each time it wants to run a simulation, which takes longer than 
executing a compiled form, or it must do something like producing C source, 
compiling it, then forking and exec'ing the newly compiled program, 
communicating to it via pipes.

2) Runtime binding. Under Java RMI, any class that you would like to make 
accessible via RMI needs to have a stub statically generated for it with the 
"rmic" utility. Wouldn't it be nice if the RMI runtime system could just 
generate stub classes on the fly, on the client? Because otherwise the client 
either needs to have the stub class built in (which makes it sensitive to 
changes on the server; old clients may not be able to use the new class, even 
if you've only *added* methods which the old clients don't use anyway), or to 
fetch it every time via HTTP (the RMI classloader). Why can't the client 
library throw stubs together itself if needed? Well, more recent versions of 
RMI can do this: using the Proxy system (part of the Java reflection tools), 
you can create a form of class at run time. To create a Proxy you provide a 
list of interfaces it must support, and a generic invocation handler function 
that gets called to implement the methods. This proxy object then implements 
all the interfaces, but any call to any methods turn into calls to the 
invocation handler function. We've used this where I work to produce a 
"better RMI"; the client declares which interfaces it wants to use on the 
remote object, and gets a proxy implementing those interfaces. Method 
invocations are handled by sending the method name (as a string) and the 
argument list over the network to the server; the presence of "extra" methods 
on the server that the client does not know is not a problem, and if the 
client invokes a method the server lacks, this turns up when the server tries 
to find the server-side method of that name to invoke. Our implementation 
currently just throws back an exception in that case, but it could easily 
change that behaviour to anything we like.

3) Debuggers are metaprograms. Without metaprogramming tools it's hard to 
write a debugger - you need to do it at the machine code level. With 
metaprogramming tools, the debugger can bring the program to be debugged into 
itself (perhaps modifying it to include special debugging hooks - eg, on 
every assignment to shared state, invoking debugger code to log the change, 
etc), compile it to a function, and invoke it - but then when interrupted, 
use reflection APIs to assess the state of the program within for human 

> Moreover we are ultimately bound by the instruction set of
> the executing machine.  No instruction set thus far (or even
> proposed) has the capability of extension, of creating an
> instruction or instruction set, not derivable from the existing
> instructions.

Not true... some machines have reprogrammable microcode! And consider JNI, 
the Java Native Interface, which allows one to link in external machine code 
to do things that the JVM itself cannot do.

> We cannot in short imbue programs with "intelligence".

We don't need to!


Oh, pilot of the storm who leaves no trace, Like thoughts inside a dream
Heed the path that led me to that place, Yellow desert screen