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 (int8 through uint64), the floats (float32, float64), 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)        # a float32 of shape (3)
    float[]  weights = [0.1, 0.2, 0.4, 0.3]   # a 1-D float32 array
    str      name    = "ball"
}

Shapes, not classes

The familiar aggregates are sugar over fixed shapes, not separate types. float3 is a float32 of shape (3); a 4×4 matrix is a float32 of shape (4, 4); a colour is a small float vector; an image is a float32 (or uint8) array of shape (height, width, channels). One Value plus a shape covers a vector, a matrix, and a colour alike.

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

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 Value.

Strict, typed access

A consumer always knows the type it holds. Kinogaki 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.