Values & shapes

One value type, every datum

A Value is the atom of a Prism document: a dtype plus a shape over a flat buffer. The dtype is one of bool, the signed and unsigned integer widths (i8u64), the floats (f32, f64), or str. The shape is a scalar, a 1-D run, or a multi-dimensional array. That is the entire type system — and it is deliberately enough to express everything the higher content kinds need.

def object "ball" {
    bool     visible = true
    float    radius  = 1.5
    float3   albedo  = (0.9, 0.2, 0.2)        # an f32 of shape (3)
    float[]  weights = [0.1, 0.2, 0.4, 0.3]   # a 1-D f32 array
    str      name    = "ball"
}

Shapes, not classes

The familiar aggregates are sugar over fixed shapes, not separate types. float3 is an f32 of shape (3); a 4×4 matrix is an f32 of shape (4, 4); a colour is a small float vector; an image is an f32 (or u8) array of shape (height, width, channels). There is no Vector3 class, no Matrix class, no Color class — there is Value, and a shape.

Value r   = Float(1.5);                      // f32 scalar
Value rgb = Float3(0.9, 0.2, 0.2);           // f32 shape (3)
Value pts = Value::array<float>({3, 2}, {0,0, 1,0, 1,1});  // f32 shape (3,2)
bool  vis = r.isScalar();                    // shape/dtype are introspectable

Why one type matters

This uniformity is the quiet engine of the whole platform. A single Value is simultaneously a transform component in a scene, a channel of pixels in an image, a control point in a vector path, and the text of a paragraph in a document. Because of that, the codecs can share canonical models instead of inventing a schema per format: an OpenEXR channel, a mesh's vertex buffer, an SVG point list, and a heading's text are all typed arrays distinguished only by dtype and shape. The argument that "almost all data is typed values at named addresses" is implemented here, in this one class.

Strict, typed access

A consumer should never silently get the wrong thing. Core offers permissive getters that return an optional, and strict getters that demand a type and report a clear error if the document disagrees:

auto  ball = doc.edit(Path("/world/ball"));
float r    = ball.getFloat("radius", 1.0f);   // permissive, with a default
Vec3  rgb  = ball.requireFloat3("albedo");    // throws a located error if absent or mistyped

Typed values mean a reader always knows what it is holding, and a program — or an agent — can demand the shape it expects rather than guessing. From here, two axes build on the value: properties add a name and time, and connections let one value flow from another.