Skip to main content.

Saturday, February 25, 2012

Uhm... not quite like this:



However, I introduced a concept in Falcon called "Mantra"; it's not visible at language level, at least not for now; it's a concept used in the engine. A Mantra is a basic entity that can be invoked, or better summoned in the engine or in a module. Namely, now it's either a Function or a Class. After searching a bit in the literature for a concept capturing this two concepts in one definition, I found nothing precise, so I picked this ... rather spiritual ... but adequate name.


(Yes, there are function objects, functionoids, functors and function classes, but that isn't quite a synthesis of the two distant concept of function and class; rather, is a way to express and re-define one of the concepts through the other one).

The need arose in the serialization. Some of the serialized entities are meant to be fully serialized, so that they can be re-built out of simple elements (PSteps, expressions, statements, values etc.), while others are just references to native entities, as for instance, C functions, or classes provided as native code by third party modules, or even directly created in the engine by embedding applications. The engine needs to know if those entities CAN be described in the VM language, or must just be "summoned" in an environment; if they are to be summoned, it must know what elements to search and load to restore them in memory, in the state they were found when serialized. And if the element can be expressed as VM code, the engine (or the user) might still wish not to do that, and just reference that entity by its logical place in the engine target environment. To allow this flexibility, the entities that can be treated this way should have a common storage behavior that can be overridden, which is Class::store &c does; but having the Class and Function hierarcies completely separated required either to write some glue code knowing both of them or doing some other terrible hack.

The best solution, is that of putting in common the things we know about Function and Class, and give them a common name (some times ago I wrote an article as programming being giving names to things). For instance: we know that they may come from modules, may be either opaque or expressed in a form that the engine can understand, they can be searched by name either in the engine or in a module providing them, they can be associated to symbols and they can be exposed to the script via Class handlers (yes, both Class and Function have Class derived handlers).

I found no better name for them than Mantra.

Other than this serialization issue, I felt somewhat uneasy at the idea that I had get/add function/class all around. They are often duplicate methods, with duplicate maps, just being different for the pointer types. Yes, modules need to do special thing for classes, but some special behavior doesn't really justify a completely different set of methods taking care of them. And the same thing goes for the Engine registered classes and known functions. And, similarly, I have different dynamic load methods for classes and functions... This Mantra entity allows me to simplify all those aspects, and it's ready to accept other basic concepts we might want to introduce in future.

Now both Function and Class derive from Mantra. Each mantra must present a handler Class (to be handled by the engine and exposed to scripts) via a virtual handler() method. As its descendant, Mantra itself must expose a handler; in its case it's ClassMantra; of course, it's a Class.

So, ClassMantra <-- Class <-- Mantra, and ClassMantra --handles--> Mantra. Of course, Class needs a handler as well: MetaClass <-- ClassMantra <-- Class <-- Mantra, and MetaClass --handles-->Class. The engine doesn't expose MetaClass, but if it were to, then MetaClass would be able to be a handler for a MetaClass instance.

Something similar goes with functions, but the chain is less spectacular, so I won't bore you with that.

We have now reached a point where we can serialize or invoke everything in the engine. In the channel, we're trying to find an ergonomic way to have this ability exposed to the engine users, so that they can cherry pick what to serialize and what to ask the remote side for invocation, giving sensible defaults where the user doesn't express any preference, and necessary constraints where one way is precluded; but that's just a matter of how to show it, as the problem of to do it is now solved.


Comments

No comments yet

Add Comment

This item is closed, it's not possible to add new comments to it or to vote on it