A new start with quajets ( 2024-11-17 )

It seems i am not done, but while resting i did have some new inspiration, call it clarity. For one, ruby is too big, so i will try to prove the point with som. And the second one come from the quaject realisation, quajects are the way forward.

The ruby size problem

Ruby started out as quite a reasonable little language, but, with c extensions, keyword args, and explicit metaprogramming has grown into a beast of functionality. This is daunting, too much so. Or, put another way, it is not interesting to me to get every litte ruby functionality done, passing the tests etc, not on my own.

What i really want is to see that the approach works, the calling the layers, and the quajects. Get decent size benchmarks to prove the point, without running full rails apps. So i found SOM, a simplest version of oo, which already has 9 implementations, and good benchmarks to make a fair comparison.

When that works, i hope to continue with ruby. Then with some good numbers to back the case.

Quajects

As mentioned i have been wondering about quajects for years, and finally "got" it. And they made me think about flow-control on the way.What that means needs to be unpacked a little (below) but will influence the coming work in major ways. Already because of the SOM thing i need to change the name, and because of the importance of quajects, i am leaning towards QuaVM. But lets unpack the aspects in turn.

Normal objects

Let's try an analogy: 3d printing. 3d printing is not really 3d, because it only ever prints in one layer, so 2d, and then moves up one layer to print the next layer. Objects are like the current 3d printing in that sense, not "real" objects.

Another way to look at objects shortcomings is from a historic point of view. C has had srtucts and functions, and C++ just slapped the type in the struct (called it self) and implicitly passed the struct to functions. So the data (the struct) and the functions are still quite sperate, just defined as a nicer package.

Real objects, or quajects

The quaject idea is to really have code and data mixed in an object. One way to think about this in current lanuages is to have closures or blocks as instance variables. This gives sort of idea but does also fall short because of the calling aspect, or control flow. And the possibility of truly private (ie embedded) data.

The orinal quajects had data and methods (called callentries), but also callouts and callbacks. Callbacks are easiest to undertsand as they are used frequently today, and basically implement a commnication protocol between caller and callee, so that information would get back to the caller other than through return values.

Callouts are a little harder, but can be seen as a type of abstract method that gets called in certain circumstances (eg buffer full). Derived classes would implement the abstract method to their need. Alas originally inheritance was not used and the callout was populated with a function pointer acording to it's type.

The most difficult part to understand about quajects was the creation or instantiation. As assembler templates were used, which do not map well to higher language contructs. As per the thesis "most" of the code was thus part of the quaject, and not as in objects in seperate function tables. It is here, combined with the above ideas that i see most potential (tbc).

Control flow

Controlflow has been an issue for me in two ways, object creation and call semantics. Both involve non trivial coding, and as this is happening inside the compiler, ie not in a higher language, i struggled to express the logic in a clear and consice way. Mainly i think due to missing concepts, like the quaject ideas.

So let's go back a bit and come around to the current issues and possible ideas later.

Tree Control flow

C's stack based calling implementation has led us programmers to think in terms of functions/methods calling methods calling methods, control always returning back to where the method was called. This thinking may be so automatic that it may take an effort to unlearn.

In the sixties and even seventies this was not always so. People used jumps and gotos, often with terrible results and while creating unvariably unreadable "spaghetti" code. So gotos had to go, and the only jumps allowed were method call and return.

And while i am not suggesting we go back to gotos, we did loose something when that was thrown out. It's like with metaprogrammin, which is great, but only in 2-3 percent of the time. When used too much, it produces unreadable code, but when used in the 2 percent, as in rails for creating accessors or url helpers, it is so much more elegant than eg handing extra aguments all the time

Linear control flow

So what i am suggesting/exploring is how to go back to a linear control flow. Remeber that is what a cpu basically does, always one step/intruction at a time and some of those are (conditional) jumps (also a return is just a jump, really). But hopefully quajects will let us do this in a more controlled way than assembler, thus adding to the systems, not making it more dangerous.

This way of looking at it is (off course?) only applicable at the compiler level, the level where we generate code. A Quaject in this sense is an expansion of the concept of a basic block, or an oo way of looking at basic blocks.

And old archives