Library Features
Library Features (Optional)
Section titled “Library Features (Optional)”Type-Safe Value Access
Section titled “Type-Safe Value Access”CCL values are always strings. Type conversion is a library convenience, not part of Core CCL.
Common Functions:
get_string(config, path...)- Extract string valuesget_int(config, path...)- Parse integers with validationget_bool(config, path...)- Parse booleans (true/false, yes/no, 1/0)get_list(config, path...)- Extract lists from empty-key entries
Example:
app = name = MyApp port = 8080 debug = truename = get_string(config, "app", "name") // "MyApp"port = get_int(config, "app", "port") // 8080debug = get_bool(config, "app", "debug") // trueEntry Processing
Section titled “Entry Processing”Manipulate CCL entries for composition and filtering.
Common Functions:
filter(entries, predicate)- Remove entries (e.g., comments)compose(entries1, entries2)- Merge entry lists (Monoid composition)
Example:
/= Development configdatabase.host = localhost
/= Production overridesdatabase.host = prod.db.comdev_entries = parse(dev_config)prod_entries = parse(prod_config)combined = compose(dev_entries, prod_entries)final_config = build_hierarchy(combined)Formatting Functions
Section titled “Formatting Functions”CCL provides two distinct formatting functions that serve different purposes.
| Function | Purpose | Property |
|---|---|---|
print | Standard format | Structure-preserving: print(parse(x)) == x for standard inputs |
canonical_format | Model-level format | Semantic-preserving: transforms key = value to nested form |
The print Function
Section titled “The print Function”Purpose: Convert parsed entries back to CCL text format, preserving the original structure.
Key Property: For inputs in standard format:
print(parse(x)) == xThis is an entry-level isomorphism - the round-trip preserves the textual structure.
Example:
name = Aliceconfig = port = 8080 debug = trueAfter parse and print, the structure is preserved exactly.
The canonical_format Function
Section titled “The canonical_format Function”Purpose: Convert to a normalized model-level representation.
Key Property: Transforms all values into nested key structures:
key = value → key = value =This is a semantic-preserving isomorphism - no information is lost, but the structure changes to reflect the internal model.
The OCaml CCL implementation uses this approach, representing all data uniformly as nested KeyMap structures. This enables elegant recursion with the fix function and clean pattern matching.
Trade-off: With canonical_format, these two inputs produce identical output:
name = Aliceand:
name = Alice =Both become { "name": { "Alice": {} } } in the model, so the original structure cannot be recovered.
Standard Input Format
Section titled “Standard Input Format”A CCL input is in standard format when:
- Keys have exactly one space before and after
= - Nested content uses 2-space indentation per level
- Line endings are LF only (CR characters become part of value content)
- No extra whitespace before keys or after values
Standard format:
key = valuenested = child = valueNon-standard (extra spaces):
key = value nested =Round-Trip Testing
Section titled “Round-Trip Testing”Use round_trip to verify the isomorphism property:
parse(print(parse(x))) == parse(x)This verifies that print followed by parse produces identical entries to the original parse.
Implementation Guidance
Section titled “Implementation Guidance”For structure-preserving print, implementations need to track whether a value was originally a string or nested structure. Options:
- Leaf flag: Mark nodes that were originally string values
- Original value storage: Keep raw string alongside children
- Entry preservation: Keep original entry list, build hierarchy on-demand
For new implementations, use a tagged union type:
type Value = | String(string) | Object(map<string, Value>) | List(list<Value>)This makes print straightforward to implement while still supporting canonical_format when needed.
Experimental Features
Section titled “Experimental Features”Some implementations provide additional experimental features:
Dotted Representation (experimental):
- Allows accessing nested values using dot-separated paths in a single argument
- Example:
get_string(config, "database.host")instead ofget_string(config, "database", "host") - Not recommended for new implementations - use variadic path arguments as the standard API
- May be useful for compatibility with existing configuration conventions
Test Suite Coverage
Section titled “Test Suite Coverage”The CCL Test Suite provides tests for these features:
- Type-Safe Access: 381 assertions (99 tests) -
get_string,get_int,get_bool,get_float,get_list - Entry Processing: 15 assertions (12 tests) -
filter,compose, identity properties - Formatting:
printandround_triptests verify isomorphism properties - Experimental Features: 22 assertions (10 tests) for dotted representation
See Test Suite Guide for progressive implementation roadmap.