Functions Reference
This page is the canonical reference for every CCL function the test suite exercises. Each heading is the stable anchor for the corresponding function:* tag (e.g. function:parse → #parse).
For the full recursive algorithm, see Parsing Algorithm. For patterns and examples, see Implementing CCL and Library Features.
Canonical Data Model
Section titled “Canonical Data Model”The canonical CCL data model is the in-memory shape that build_model produces and that every other function operates on — typed accessors project from it, canonical_format renders it back to text, and build_hierarchy is a JSON-friendly view of it.
The Model type is a recursive map:
type Model = Map<string, Model>There are no scalar leaves. A string value like "localhost" is not stored as a value — it becomes a key in the inner map pointing to the empty model ({}). This is what makes the model recursive in a single type rather than a sum of “object” and “string” cases.
host = localhost→ {"host": {"localhost": {}}}
Duplicate keys at the same level merge. Their inner maps are combined recursively, which is how bare lists, repeated keys, and compose all work uniformly:
item = firstitem = second→ {"item": {"first": {}, "second": {}}}
The model is order-agnostic. Key ordering within any map is unspecified. Anything that needs ordered access — most notably get_list — picks an order at the typed-access layer, governed by the array_order_* behavior. This is why two inputs that are semantically equal in the model produce identical canonical_format output even when their source text looked different.
Reference implementation. The OCaml reference exposes this model as fix : Parser.key_val list -> t where type t = Fix of t KeyMap.t. See ccl-test-data issue #142 for the ongoing work to formally add build_model to the test suite.
Tag: function:parse
parse(text: string) → Entry[]Converts CCL text into a flat list of key-value entries. Splits each line on its delimiter, trims keys, preserves in-value whitespace, folds continuation lines into the preceding value using the baseline-N rule.
Under the toplevel_indent_strip behavior, top-level parsing uses N = 0 and strips leading whitespace on top-level keys. Under toplevel_indent_preserve, the baseline is determined dynamically from the first content line.
See Continuation Lines for the baseline-N algorithm and Behavior Reference — Continuation Baseline for the top-level choice.
host = localhostport = 8080→ [{key: "host", value: "localhost"}, {key: "port", value: "8080"}]
parse_indented
Section titled “parse_indented”Tag: function:parse_indented
parse_indented(text: string) → Entry[]Nested-value parsing. Determines baseline N from the indentation of the first content line, then parses with that baseline. Used internally by build_hierarchy to re-parse nested values.
parse_indented and parse differ only in how they pick N. See parse vs parse_indented for the worked example.
build_model
Section titled “build_model”Tag: function:build_model
build_model(entries: Entry[]) → ModelConverts flat parsed entries into the canonical CCL data model. See that section for the Model type, the no-scalar-leaves rule, duplicate-key merging, and order-agnosticism.
server = host = localhost port = 8080→ {"server": {"host": {"localhost": {}}, "port": {"8080": {}}}}
build_hierarchy
Section titled “build_hierarchy”Tag: function:build_hierarchy
build_hierarchy(entries: Entry[]) → objectA JSON-friendly view of build_model. Projects the recursive Model type into a conventional nested-object shape:
- Single leaf node — a key whose inner model has exactly one key pointing to
{}→ string value - Multiple leaf nodes — a key whose inner model has multiple keys all pointing to
{}→ array of strings - Nested nodes — a key whose inner model has non-empty values → nested object (recursed)
server = host = localhost port = 8080→ {"server": {"host": "localhost", "port": "8080"}}
item = firstitem = seconditem = third→ {"item": ["first", "second", "third"]}
The flat string output for bare-list entries is the correct projection of leaf nodes from build_model — not a behavior choice, but a consequence of the projection rule. See Bare List Hierarchy and Parsing Algorithm — Build Hierarchy.
Tag: function:load
load(text: string) → objectConvenience combining parse + build_hierarchy in one call. Equivalent to build_hierarchy(parse(text)).
Typed Access
Section titled “Typed Access”All typed accessors project from build_model output, navigating the Model value by a key path passed as variadic string segments (e.g. get_string(ccl, "database", "host")).
Accessor behavior under ambiguous values is governed by:
boolean_strictvsboolean_lenient— which strings coerce totrue/false.list_coercion_enabledvslist_coercion_disabled— whetherget_liston a single value yields a one-element list or an error.
Error conditions (uniform across typed accessors):
- Missing path segment — fail with a path-aware error (implementations should include the full path and available siblings to aid debugging).
- Intermediate segment is a scalar, not an object — fail; the path cannot descend through a non-object value.
- Type conversion failure — e.g.
get_inton"hello". Fail with both the expected type and the raw value. - Empty path — implementation-defined; tests don’t require a specific behavior.
get_string
Section titled “get_string”Tag: function:get_string
get_string(ccl: CCL, ...path: string) → stringReturns the raw string value at the given path. No coercion.
get_int
Section titled “get_int”Tag: function:get_int
get_int(ccl: CCL, ...path: string) → intParses the string at the given path as an integer. Errors if the value is not a valid integer.
get_bool
Section titled “get_bool”Tag: function:get_bool
get_bool(ccl: CCL, ...path: string) → boolCoerces the string at the given path to a boolean. The accepted set of truthy/falsy tokens depends on the Boolean Parsing behavior.
get_float
Section titled “get_float”Tag: function:get_float
get_float(ccl: CCL, ...path: string) → floatParses the string at the given path as a floating-point number.
get_list
Section titled “get_list”Tag: function:get_list
get_list(ccl: CCL, ...path: string) → string[]Returns an array of string values at the given path. Bare-list entries (empty-key children) are the canonical source; get_list has well-defined array semantics regardless of how build_hierarchy represents bare lists (see Bare List Hierarchy).
Single-value coercion depends on List Coercion.
Processing
Section titled “Processing”filter
Section titled “filter”Tag: function:filter
filter(entries: Entry[], predicate) → Entry[]Filters entries. The test suite validates filter used to strip comment entries — keys beginning with / (see Comments).
compose
Section titled “compose”Tag: function:compose
compose(left: Entry[], right: Entry[]) → Entry[]Concatenates two entry lists so duplicate keys between them merge at object level when passed through build_hierarchy. compose is expected to be associative; the test suite validates this via the compose_associative algebraic property (and the identity_left/identity_right identity properties).
expand_dotted
Section titled “expand_dotted”Tag: function:expand_dotted
expand_dotted(entries: Entry[]) → Entry[]Transforms entries with dotted keys (e.g. database.host = localhost) into nested structures. Opt-in: CCL treats dotted keys as literal strings by default. See Dotted Keys Explained and the experimental_dotted_keys feature.
Formatting
Section titled “Formatting”Tag: function:print
print(ccl: CCL) → stringRenders a CCL value back to text in a structure-preserving form. Distinct from canonical_format, which imposes a normalized ordering.
See Library Features — Formatting for the print vs canonical_format comparison.
canonical_format
Section titled “canonical_format”Tag: function:canonical_format
canonical_format(ccl: CCL) → stringRenders a CCL value in a canonical form: stable key ordering, consistent indentation (per indent_spaces vs indent_tabs), no redundant whitespace. Two inputs that are semantically equal produce identical canonical output.
round_trip
Section titled “round_trip”Tag: function:round_trip
round_trip(text: string) → stringcanonical_format(load(text)). Validates the round-trip property: round-tripping a canonical input must be a fixed point.
See Also
Section titled “See Also”- Features Reference — language features every conformant implementation handles
- Behavior Reference — implementation choices with mutually-exclusive pairs
- Variants Reference — spec-compliance variants
- Decisions — canonical decisions on ambiguous semantics