OS design...

Francois-Rene Rideau fare@tunes.org
Tue, 20 Oct 1998 12:47:45 +0200

>>: Fare
>: Bear

>> Sure. And the foundation is: the compiler. Not anything in the "kernel".
>> Choose an existing compiler, or implement a new one; calling conventions
>> for "system services" will follow automatically from that choice.
> Here, I think, is our fundamental conflict of opinion.  You are
> assuming that system services will and must be accessible as
> procedure calls.

Just what *else* can they be? If you build an additional abstraction,
it's going to be used through wrappers that build procedures, anyway!
[Of course, a good implementation would use inlining when useful].

Look at the linux libc: everything is defined in terms of C procedures,
and direct syscall access is doubly deprecated, since it's not portable
(even accross different Linux ports: different arch, linux on top of K...),
and it prevents filtering through DLLs (e.g. user-space filesystem
extensions). Just *ALL* Linux language implementations go through these
(except maybe one toy FORTH implementation I hacked as proof-of-concept).

In a LispOS, the standard system accessors would be Lisp functions
rather than C functions; that's all.

Oh, maybe you're wondering about how your system functions written
in some low-level language will communicate with Lisp? Well, just
don't write them in a low-level language; write LispOS implementation
in Lisp, just like COS (Linux) implementation is written in C.

Oh, of course, you'll have to have a few accessor functions and special forms
to access the hardware in real-time; but these can be abstracted away from
the drivers themselves, and put into implementation-dependent directories
(see linux/include/asm-*); only in a LispOS, these would be
clearly part of the compiler support, rather than hacks
around GCC extensions wrapped in CPP macros (yuck).

[About lots of different semantics for functions,
and their corresponding low-level implementation constraints]

> I am sick to death of building FFI's that map the semantics of
> one language's procedure calls to the semantics of another's in
> order to access services.

Building a lowest (or <foo>est) common denominator for system services
won't make it *any* better; it's quite the contrary!
The "impedance match" role played by FFI's is _intrinsic_
to the difference in semantics of languages.

Using again the LCD approach is just reinventing Unix, poorly.
Plus, it forcing everyone to go through that common (forcibly poor) semantics
is quite a waste, when the actual languages that will communicate have
semantics near to each other and far away from the common denominator
(which is also why CORBA sucks).

The only right approach is to allow users/programmers to specify
explicit "semantic bridges" between pairs of languages; these induce
a category of languages with compositions of specified bridges as functors.
Various heuristics may help semi-automatically find a bridge between two
languages that fits the user's needs, assuming the initial graph is connected.
Having a LCD is just having the initial graph be a "star", which is quite
a naive approach.

> I think it is a mistake to make one
> compiler more priveleged than another,

Reread the GNU Jargon File, Appendix A, AI Koans, Sussman&Minsky Koan.

> or complicate the task
> of implementors by forcing them to learn the internals of some
> particular compiler in order to build effective compilers for
> the system, and then force them to track changes in that other
> compiler on penalty of having theirs break.  (this is where most
> LISP FFI's that call C++ code are today).

Well, if you want to make two implementations communicate efficiently,
you just won't cut that part. Happily, assuming you have a high-level
description of calling conventions, the nitty-gritty details of register
allocation et al can be mostly metaprogrammed. But you'll *always* have
to add high-level semantic annotations to foreign C/C++ interfaces,
because the C/C++ interfaces are intrinsically lower-level than the
Lisp interfaces. [Now, the whole goal of a LispOS is to get rid of C/C++,
so who cares?]

> Also, I don't want to tie the system to my compiler's choices:
> three years from now I may learn something new and cool and
> change the way I implement procedure calls in my scheme
> compiler. When that happens, there are a bunch of things I don't
> want to break;

Oh you want to be able to change the compiler calling conventions? So do I.
But that's a fairly easy task: just recompile the system afterwards!
[Even Linux requires recompiles, when going from a.out to ELF to ELF/glibc2].

> 	1) Compiled code produced by earlier versions of the
> 		compiler.  A commercial application's customers [...]

First answer: FUCK with software hoarders who won't make the sources
available for recompiling! Second answer: they can distribute
uglified/optimized/otherwise_transformed source, if they fear we'd see
through them by looking at their code (but we don't need to; they're all
too obvious). Third answer: if they want to be nasty, then the burden
to recompile their components with 100 different targets is up to THEM;
of course, there can be standard tools to automatize it, in the form of
a standard, cacheing, server, that takes the (private) source and the
(public) compiler specs handled by customers, and outputs an according
binary. [My, I've described already it in the TUNES list a few years ago;
surely this should be written down on the web pages...]

As for "certifications" of code, they are due when changing the environment,
anyway. Just don't play with implicit hypotheses, like Ariane V did.

> 	2) Compiled code produced by [Other] compilers
Different conventions, GC, etc, means (logically) separated address spaces.
This means that non-native low-level conventions will be disadvantaged
by requiring a protection barrier, just like under Unix. So what?
Oh, and if you want to not have "native" conventions, then and have
protection barriers be the standard way to do things in your system,
well, just stick to Linux.

Now, if you just mean to have the native compiler understand a rich
semantics for calling conventions, so that it can take into account
the fact that such and such function may only be called in such and such
context, then not only is it possible (though costly in terms of compiler
complexity), but wishable anyway for compiler efficiency. And, yes,
you can have explicit source annotations help the compiler analyses
when determining the precise semantics of various functions;
which is exactly what FFI's do.

> You want to think about how silly the machine code would be if
> we compiled FORTH procedure calls to Scheme procedure calls??

Doesn't look silly at all to me. First, the standard back-end Scheme compiler
may be expected to produce fairly good code out of it (all the more with
compiler hints). It's just like people using C as a back-end language under
Linux. The fastest portable FORTH compilers for Linux use the C compiler!
[Same for Scheme: Stalin!]. I'd expect the fastest portable <FOO> compilers
for LispOS to use Lisp as a back-end, too, since the Lisp compiler would be
fairly optimized itself, and no one would want to be redundant with it.
Of course, you're free to use FORTH inside Unixish paranoid black box
protection; but then you're not actually *using* LispOS, just running
in a virtual hardware emulator on top of it (see DOSEMU, Wine, etc).

> My point is, let's just not go there, that would be continuing
> the kind of mistakes that current OS's make by priveling one
> language (or at least one set of calling conventions) over all
> others. Instead, let's have some standard method for accessing
> services that is reasonably language-neutral and easy for a
> compiler writer (compiling *whatever* language) to cope with.

Life is made of commitments.
Neutrality is a myth (unless towards the irrelevant).
Don't hide your responsibilities under that carpet.

## Far | VN: Уng-V Bn   | Join the TUNES project!  http://www.tunes.org/ ##
## FR: Franois-Ren Rideau |    TUNES is a Useful, Not Expedient System     ##
## Reflection&Cybernethics  | Project for a Free Reflective Computing System ##
The last good thing written in C was Franz Schubert's Symphony number 9.
	-- Erwin Dieterich <erwin@cvt12.verfahrenstechnik.uni-stuttgart.de>