ehird wrote:
The theory is to have a very tiny asm-only kernel. It'd do the very low level stuff needed to get the kernel to a level where it can run an ASM kernel-level interpreter for a highly object-oriented, fast, and not entirely unpleasant to code in (;)) language. Presumably, due to speed concerns, the unsuitability of just about every current interpreted language for e.g. driver development, and the needs-asm-interpreter part, it'd be a newly-created language. The interpreter would immediately initialize itself and then create a new instance of the (singleton, of course

) Kernel class. The constructor for Kernel would then initialize the things needed to have an OS that can do more than the very basics, and do something like OSLoader.start(loads of hardware info here...) or something of the sort. It would boot up the OS, and then continue...
I don't see a point in having an ASM kernel. I'd say it buys you more or less nothing. Ofcourse if you like writing in ASM, then it's ok, but really, it buys very little.
I also don't see point in running everything with an interpreter. Direct interpreter will never be fast enough, so you'll probably have to analyze the code enough anyway, that making it a compiler is just a question of adding a codegen to the interpreter. Once you have a basic (=bad, slow) compiler (which is still likely to be comparable to decent interpreter) it's relatively easy to start adding optimizations.
... You might have noticed the distinctly modular, microkernel-esque design this is leading to. Of course, this is a direct side-effect of object orientation....
I don't agree. You can have object-oriented monoliths, and non-object oriented microkernels. The point is, stuff is modular, when components don't need to care about other components. Object-orientation is neither necessary nor sufficient for making a system modular.
...to display a login prompt, call User.login with the details, etc
I'm going to claim that how the login prompt is displayed is going to be one of the less important parts of any system's design. In fact, even Unix kludges logins on top of setuid() system call (well, in a sense the actual kludge is the setuid() syscall itself).
1. User integration with instances
A user should be able to "own" an instance, so that an object initialized by a user is not accessable by any others (unless, for example, theUser.omnipotent returns true

).
If you have secure pointers (in the sense of references in Java) then you don't necessarily need "user" to be able to have somebody own an object. The only necessary condition then, is that only your "omnipotent user" is able to enumerate object in the system.
You should read about E-language capabilities if you haven't.
2. Subinstances
When you get a GUI and a window manager, you need to say "this instance is running under the gui". Traditional process-based OSs use parent processes to do this. But you have a subclass, why not a subinstance? i.e. an instance of a class that is a child of another instance of another class.
Eh? Why do you need such a thing? In Unix the process parenthood has one important function: it allows the parent process to wait for it's child to terminate, and receive the exit status of the child process.
You can implement such functionality in many ways. You could simply have the garbage collector notify certain object that another object was collected. But for practical purposes, I don't think even that is necessary.
If you have threads in your system, then you can have one thread be the parent of another thread, and the whole issue goes away. If you have a garbage collector, then nobody cares if the object representing the application has been collected. What everyone cares is whether the thread created for the application is still running.
It's also worth noting, that you can easily get rid of your parent in unix, by doing fork(), then exiting the original process, and continuing in the new child (which get inherited by init). That's more or less how you start daemons in Unix.
1. Applications are classes
Simple. Use other classes in your app, organize it, sure, but an application could be defined something like this:
Don't forget that "application" or "process" is for the combination of some data, some code, and a thread of control. In cases where all the data is local to the code, it's rather painful to create a whole class just to have a procedure. There is lots of programs which don't necessarily benefit from having a class at all.
Also, because an interpreter is running all the time, startup time of apps is almost non-existant: if you can create a class and run a method on it in X time, that's how long it is to start a program!
You'll still have to load the class for the program, unless you keep all classes in memory all the time. In a typical system, most of the startup time for a process would be used in loading the program.
Ofcourse there's some overhead in traditional system from creating a new protection domain and all, and this can be significant in cases where there is no significant I/O (eg. webserver fork()ing on each new request) but then again there are usually easy ways to avoid such cases (eg. writing a better webserver).
Rest of the overhead is probably related to managing threads, which you'll only avoid if you don't create new threads (eg. webserver works by using poll() or some of the better scaling newer alternatives like epoll in Linux). Once that starts being an issue, I think you'll have the resources to forget about interpreters.
"But what about files?" Simple. There are no files. Of course, you can persist objects, and it'd use a filesystem for that, but it would be abstracted away. For paths, it'd use e.g. "/Microsoft/products/WindozeXP" as a filename - direct mapping of namespaces to paths. If you wanted to, for example, give PNG support:
This is wonderful idea, except in some cases it's actually rather nice to have files. Like, suppose you want to serve files over network (webserver again) and you would prefer not to care about what files they are. You just want to read certain amount of bytes, and dump it to the socket, when when the socket is ready for more, you want to read some more, and dump that to the socket as well.
One of the advantage of files, is that it's possible to handle huge files, since they need to be read into memory at once. If you want to maintain any sort of performance, the application should be aware of this. Sure, you could use a B-tree of objects, but then you just end up re-inventing filesystems in applications, which isn't necessarily such a good thing.
Even media streams (like movies) become complicated problems, not to speak of stuff that requires random access to potentially huge amounts of data. Filesystems are pretty nice for stuff that requires an indirection anyway.
------
I don't think the concept of object oriented systems is a bad idea. But I also don't think it's good idea to take them too far.
Think of how your ideas scale to large amounts of users or data, and it'll probably work for one user with a little data as well.

The real problem with goto is not with the control transfer, but with environments. Properly tail-recursive closures get both right.