Cue Integration
CUE is a constraint-based configuration language built on a value lattice. Maggie integrates CUE as a first-class citizen, letting you project objects into CUE values, validate data against schemas, and use CUE unification for structural pattern matching.
CUE's value lattice has a natural correspondence with Smalltalk's object model: CUE's top type is like Object, unification narrows constraints like subclassing, and bottom (error) is like doesNotUnderstand:. This makes CUE a powerful substrate for schema validation, template matching, and (eventually) predicate dispatch.
This chapter covers the current CUE integration: contexts, values, object projection, and template matching.
ctx := CueContext new.
val := (ctx compileString: 'x: 42') value.
val kind >>> 'struct'
val isConcrete >>> true
Compiling and Inspecting CUE
Compile CUE from a string with compileString:. The result wraps a CueValue you can inspect with kind, isConcrete, exists, and error.
Use lookup: to navigate into nested structs by dot-separated path. Use toMaggie to convert concrete CUE values into native Maggie values (int, string, bool, Array, Dictionary).
ctx := CueContext new.
val := (ctx compileString: 'a: {b: {c: 42}}') value.
inner := (val lookup: 'a.b.c') value.
inner toMaggie value >>> 42
inner kind >>> 'int'
CUE Contexts and Values
A CueContext wraps the CUE evaluation engine. Use it to compile CUE source strings into CueValues, load CUE from files or directories, and validate data against schemas.
CueValues are immutable -- operations like unify: and fillPath:with: return new CueValues rather than modifying the original. Every CUE operation that can fail returns a Result (Success or Failure).
ctx := CueContext new.
result := ctx compileString: 'name: "Alice", age: 30'.
result isSuccess >>> true
result value kind >>> 'struct'
result value isConcrete >>> true
FillPath: Injecting Values into Templates
Use fillPath:with: to inject a concrete value at a specific path in a CUE template. This is useful for parameterizing CUE configurations or building up values incrementally. Hidden fields (starting with _) are supported.
ctx := CueContext new.
tmpl := (ctx compileString: 'x: _, result: x + 1') value.
filled := (tmpl fillPath: 'x' with: 10) value.
(filled lookup: 'result') value toMaggie value >>> 11
Object Projection with asCueValue
Any Maggie object can be projected into a CUE value with asCueValue. For objects with named instance variables, this produces a CUE struct whose fields match the ivar names. For scalars (numbers, strings, booleans), it produces a CUE scalar value.
This is the foundation for CUE-based pattern matching -- you project an object into the CUE lattice, then unify with a template to check if it matches.
42 asCueValue kind >>> 'int'
'hello' asCueValue kind >>> 'string'
true asCueValue kind >>> 'bool'
42 asCueValue isConcrete >>> true
Schema Validation
Use validate:against: on a CueContext to check data against a schema in a single step. Or compile separately and unify: manually for more control.
ctx := CueContext new.
result := ctx validate: 'name: "Alice", age: 30' against: 'name: string, age: int & >0'.
result isSuccess >>> true
bad := ctx validate: 'name: "Alice", age: -5' against: 'name: string, age: int & >0'.
bad isSuccess >>> false
Subsumption (Entailment)
Unification asks "can these merge?" Subsumption asks "does A already imply B?" — that is, is A more general than B? This is the entailment relation needed for constraint programming.
Use subsumes: to check if a schema covers a value, and subsumedBy: for the reverse. subsumes: also accepts plain Maggie objects (they are projected via asCueValue automatically).
ctx := CueContext new.
intType := (ctx compileString: 'int') value.
concrete := (ctx compileString: '42') value.
intType subsumes: concrete >>> true
concrete subsumes: intType >>> false
rangeType := (ctx compileString: '>0 & <100') value.
fifty := (ctx compileString: '50') value.
rangeType subsumes: fifty >>> true
rangeType subsumes: intType >>> false
Template Matching with matchesObject:
matchesObject: is the bridge between CUE schemas and Maggie objects. It projects the object into CUE (via asCueValue) and unifies with the receiver (a CUE template). Returns true if the unification succeeds, false if it hits bottom.
This gives you structural, range-aware, composable pattern matching against any object -- much richer than simple equality checks.
ctx := CueContext new.
intSchema := (ctx compileString: 'int') value.
intSchema matchesObject: 42 >>> true
intSchema matchesObject: 'hello' >>> false
strSchema := (ctx compileString: 'string') value.
strSchema matchesObject: 'world' >>> true
strSchema matchesObject: 99 >>> false
numRange := (ctx compileString: '>0 & <100') value.
numRange matchesObject: 50 >>> true
numRange matchesObject: 150 >>> false
numRange matchesObject: 0 >>> false
Unification
CUE unification combines two values, narrowing constraints. If the values conflict, the result is bottom (an error). Use unify: to combine a schema with concrete data.
ctx := CueContext new.
schema := (ctx compileString: 'name: string, age: int') value.
data := (ctx compileString: 'name: "Alice", age: 30') value.
result := schema unify: data.
result isSuccess >>> true