From: | Francois-Rene Rideau <rideau@ens.fr> |
Newsgroups: | comp.compilers,comp.lang.misc |
Date: | 18 Mar 1997 12:48:35 -0500 |
Organization: | Ecole Normale Superieure, Paris, France |
References: | 97-03-037 97-03-053 |
Keywords: | arithmetic, design |
[This is a public answer to a query by hrubin]
>>: rideau@ens.fr (Fare Rideau)
>: hrubin@stat.purdue.edu (Herman Rubin)
>> Still, that was the heart of what is now the Tunes project (see
>>below in my .sig), with which I'm periodically harassing people on the
>>Usenet (sorry, bored readers).
>
> Your .signature included seems to give no information about the
> project.
The moderator apparently stripped it (in good faith, I trust him).
Down there is another copy of it.
> These languages do some of this, but not too much. Probably what is
> needed, which I have asked for, is an intelligent assembler
> language, which is weakly typed and uses programmer syntax, together
> with a good assembler optimizer. With good (arbitrary syntax)
> macros, and choice of which expansion should be used for the
> platform, the assembler, or intermediate language, program should
> work well.
I have e-met many people who have considered that or even tried, but I
could not get them to collaborate on a project that could be
published, and never heard them or about them again on such subject.
I fully agree with you and them, and that's also what I've wanted for
a long time. Only, I have since separated concerns of syntax and
semantics.
For instance, on the intel platform, I've met the Terse language, that
provides a *very* concise syntax for assembly, which would have been
very practical if I was still programming a lot of intel assembly;
however, the language provides nothing semantically better than
traditional macro-assembly languages; no intelligence at all: syntax
was much lighter, but the burden of optimization was still mine.
Also, the syntax was so terse that reading code back was difficult.
On the other hand, I've experimented myself at building a set of
macros using the m4 preprocessor, that, despise the cumbersome syntax
(grr), were meant to allow basically what you describe. That way, I
would put aside syntax problems (hoping to tackle them another day),
and concentrate on the semantics.
The problem was that macros were very stupid, and it was too
difficult to have them understand concepts like pipelining; even
pinhole optimization was very annoying to write. Because m4 was
syntax-based preprocessor expansion, I also had to redo some expensive
parsing in braindead m4 (grrr), and use contrived constructs; to
reconstruct information that would have been gratuitous if
collaborating with the assembler.
Of course, I had a lot of trouble debugging all that to begin with,
all the more as m4 semantics is very unclean, doesn't allow quoting,
and was buggily implemented in the version of m4 I had (grrrr; GNU m4
1.4 since solved the problem). Also, the compilation of even a simple
program (the boot loader for an OS) was darn slow, because it spent
lots of time manipulating *large* strings representations, instead of
manipulating directly the concepts I wanted (grrrrr).
All these led me to conclude that macro-expansion is too stupid to
achieve what I want. Surely, *theoretically*, its Turing-equivalence
should allow anything to be done through it, but if Turing-equivalence
was a sufficient practical criterion, I would already be writing
everything as Turing machines and not worrying about optimization at
all!
Hence, the crucial point here is "intelligent" assembler. While I
want to precisely control certain spots, I also want to be relieve by
automatic optimization on most other (non-critical) spots. Also,
there are cases when I have many different implementation ideas, whose
performance depend on how they combine with the (varying) rest of the
program, so that I'd like the system to automatically combine the
ideas and measure their performance, to as to actually optimize
things, without my having to unfallibly determine the right thing
everytime, or my having to do lots of stubborn error-prone manual
recombination.
To sum things up, what I want is NOT specifically writing assembly
code (I can already), but being able to modify whichever spot in the
compiler will allow me to achieve the best performance for the least
overall cost. I want to produce reusable optimization tactics and
tactic patterns.
We see that once the software is required to be "intelligent", you
can't restrict it merely to be an assembler anymore. What I need is a
real meta-computing system; because I'd also like to engineer this
system, I need a meta-meta- system, etc. So as to have a finite
foundation, and not to develop lots of different language, what is
needed hence is a *reflective* system: a system that is its own
dynamic development system, so that any enhancement or optimization to
generated code also benefits generating code, and vice versa; so that
I don't have to redefine the same structures and
structure-manipulation algorithms at every programming level so as to
manipulate them; so that I don't have a long stupid series of filters
spending most of their time in low-level communication
administratrivia, stupidly discarding information, and having to
partially rebuild it later without being able to do that reliably,
etc; so that I have an integrated interface to everything in the
system, instead of building lots of interfaces that require my
learning their idiosyncrasies, and my manually enforcing consistency
between them; so that I be not stuck with having to choose between a
kludgy system that doesn't work as I think it should, or having to
rewrite everything from scratch.
Actually, I've finally accepted that I'll indeed have to rewrite
everything from scratch. But then, I'll only have to do it once, and
nobody will never ever have to do that again, for I will make it free
software.
Another serious concern is the correctness of all that. In a
reflective system, things are thus interconnected, that if you start
adding and modifying code and meta-code, you'll soon end with an
unrecoverably unstable system. Things only get worse if code is going
to get reused by multiple programmers, so that what is a feature for
one will have the other one's system crash.
Of course, a solution could be that everyone would have his own
system and not communicate; but autistic systems like that cannot
healthily develop; they are limited to what the unique author has time
and proficiency to learn and implement the hard way, and subtle
meta-bugs will have the author lose lots of his time unproductively;
the program wouldn't be trusted by anyone else, and would die when the
author stops maintaining it (a hard limit to that being his own
eventual death). In any case, such is NOT a solution.
The solution is to have a way for the system to specify and verify
correctness of all that one does. After all, the programmer himself
knows (or believes) that his code is correct, because he is able to
make sound reasoning about the program, and prove correctness to
himself and to whoever bothers to think about it. Only humans can
sometimes do small bugs, and is unable to remember every single
constraint when doing modifications months later; even if he wrote
down the constraints in the documentation, there may be too many of
them for him to verify manually in any reliable way plus there might
also be bugs in his documentation. All in all, it is obvious that
maintaining correctness constraints (and even finding simple proofs)
is a computer's job.
Note that all this does not mean your having to actually prove
correctness of everything you do before the computer accepts to
consider doing it (besides, this fascist practice wouldn't even be
effective since there could still be bugs or holes in the specs). It
only means that you CAN do it WHEN YOU NEED IT, which is almost never
for immediate interaction (though a few automatic idiotproofing tests
are a nice feature to enable by default), but almost always for any
long-term development of critical software.
The problem is that currently just NO ONE has ever tried to implement
a system on such grounds. Surely, there have been lots of stupid
fascist pseudo-secure systems, lots of uncontrollable and inefficient
reflective systems without any way to define or enforce any
constraint, and even reasonably well designed proof systems that were
death slow (they couldn't safely self-optimize, not being reflective),
and despised real-life programming as a target for proofs, unless they
openly affirmed such goal being "too ambitious" to them.
Building a safe efficient reflective system
is the goal of the TUNES project.
Well, I hope I didn't bore you. Sorry for being that long.
Best regards,
== Fare' -- rideau@ens.fr -- Franc,ois-Rene' Rideau -- DDa(.ng-Vu~ Ba^n ==
Join the TUNES project for a computing system based on computing freedom !
TUNES is a Useful, Not Expedient System
URL: "http://www.eleves.ens.fr:8080/home/rideau/Tunes/"
--
Return to the
comp.compilers page.
Search the
comp.compilers archives again.