cwal

Value Types
Login

Value Types

(⬑Central cwal Documentation Hub)

Achtung: these docs are very much in-progress, being ported and rewritten from older documentation.

See also: Scoping and Memory Management

Value Types in cwal

cwal started life as a fork of a library for working with JSON, and that provided the basics of the data type model which was initially envisions for cwal: something more or less JavaScript-esque (noting that JSON's core data types are in no way limited to JS, though its syntax is very much derived from JS).

That then evolved, with only minor changes, into what is still the core data type model.

cwal_value, referred to in the docs as simply Value, provides the client-opaque base interface for all Values in the engine. The derived family of types includes booleans, numbers, strings, memory buffers, functions, generic objects (key/value stores), arrays, and several others, including cwal_native, which is dedicated to connecting arbitrary client-side types with cwal.

Each Value has a pointer to a so-called virtual table, a.k.a. vtab. The core vtab type defines the interfaces required for type-dependent behavior in various cases, e.g. features such as comparison, cleanup, and rescoping (a topic we'll cover in more detail in the scoping docs). Each value, except for built-in constant values (see below), also has a pointer to its owning scope, a reference count, and space for a small handful of flags (packed as memory-efficiently as seems possible - a truly undue amount of effort has been expended optimizing cwal's core for low aggregate memory usage).

The internal overhead of Values makes them, of course, appreciably larger than the native C counterparts but the internal recycling mechanisms generally reduce that difference to not only negligible levels, but often reverse the trend entirely, requiring less memory (in the aggregate) than using equivalent native counterparts. i.e. the abstraction penalty, in terms of memory, tends to be very low or even negative.

Yes, we have data to prove that, and collecting it for inclusion into these docs is on the TODO list. Aggregate costs of as low as 1 byte per integer and 4 bytes per string are frequently witnessed.

Sidebar: as an optimization, cwal uses built-in constant Value instances for several cases. Such Values outwardly behave, as far as client-side code goes, just like "normal" Values, but live outside of the lifetime management system and thus do not actually take part in reference counting, cycles, and the like. It's possible, but rarely useful (outside of cwal's own core), to distinguish a builtin Value from a normal one, but the library discourages clients from having any logic which depends on that distinction. Some examples of builtin constants include empty strings, booleans, and the numeric values -1, 0, and 1.

Containers vs. Non-Containers

Values are broken into two major categories:

A few Value types fall somewhere between those two, holding a fixed set of child values (meaning that they can participate in cyclic structures) but not being general-purposes containers nor capable of holding arbitrary key/value pairs. Examples include the so-called property references, which wrap a key/value pair referencing a separate container, and tuples (lightweight fixed-length arrays).