Native Objects, part 1

Languages generally come with two distinct sets of features: native objects and library objects. The former are often built into a language, for example int and float in the C-family languages, or date and array in JavaScript. Such “binary” native types are quite distinct from user-defined types. In other languages, Python for example, there is little or no distinction between native types and user-defined types.

The lack of distinction is more common in object-oriented languages, and BOOL is not exception. Native types “look” identical to user-defined types; operationally they are identical. The next few posts discuss BOOL’s native objects.

The set of native objects a language supports is a big part of its standard, and since BOOL’s language standard is still a bit ambiguous in places, so is the definition of native objects.

One aspect is set: native objects look and operate exactly like non-native ones. An environment is allowed to implement native objects in some other language, but the objects must always behave as if they were real BOOL objects. (In fact, most native Models require implementation code to do the heavy lifting. Think about what the *float Model needs to do!)

BOOL native objects fall into three groups: Models, Generic Actions and Instance Objects (mostly constants). The Models is the most involved group; its members comprise the data types that BOOL supports natively. The native Generic Actions are what in other languages would be the language statements (such as if-else, while, switch, etc.). The final group consists of a handful of built in constants (Null, False, True, zero, one, pi, a few others) and even less global data.

All this takes place in the context of two built in Generic Actions: @system and @global.

A BOOL run-time environment looks as if these two Actions are defined:

.   {Native Models & Actions defined here.}
.   {Native Instance Data (constants) defined here.}
.   *list arguments = {initialized by system}
.   *list environment = {initialized by system}
.   @global arguments environment

>>  *list arguments
>>  *list environment
<<  *bool exitcode = False
.   {Library Models & Actions defined here.}
.   {User global (file scope) definitions here.}
.   @if @defined "@main"
.    set:exitcode @main arguments environment

The @defined Actor calls an as-if imaginary Action that returns true if the given Action is defined. The idea, obviously, is that the user should define a @main Action as the entry point to their program.

All the native objects act as if they were defined in the @system Action. If user code requires a yet-undefined constant, the new constant is added to this Action’s space (where it’s available to any other requests for that particular constant).

Libraries, whether required by the standard or imported by the user, go into the @global space along with all user-defined code. As with native objects (and library objects), there are only three basic groups: Models, Actions and Instance Objects.

When these are defined at file scope (i.e. on the left margin), the definitions become part of the @global Action. If they are defined within an Action or Model, they become part of that object. Which itself, or its parent, is an object in file scope and therefore part of the @global Action.

And the @global Action is defined in the @system Action! So the whole ball of wax, all the code, is actually part of the @system object.

Which is precisely aligned with the original vision for BOOL: a program is a single object with a tree-like structure of sub-objects, each one having a meta-type that defines the behavior of that object.

Note that the system is required to throw an exception on an attempt to call the @system or @global Actions.

[If you were wondering about library objects, I didn’t forget. They’re a topic for another time. For now consider them user-defined code with a certain native cachet.]

%d bloggers like this: