CCL FAQ
Are there types?
Section titled “Are there types?”No. Keys and values are strings. Your application converts them:
port = 5432enabled = trueThe values in this case are "5432" and "true".
Can I use dots in keys?
Section titled “Can I use dots in keys?”Yes. database.host is a literal string key with dots:
/= Key: "database.host"database.host = localhostFor nested structure, use indentation instead.
How do I nest?
Section titled “How do I nest?”Use indentation:
database = host = localhost port = 5432How do lists work?
Section titled “How do lists work?”Empty keys create list items:
servers = = web1.example.com = web2.example.comAre comments part of the data?
Section titled “Are comments part of the data?”Yes. Comments are entries with / as the key:
/= This is a commentkey = valueFilter them in your application.
Common Confusions
Section titled “Common Confusions”These questions cover common surprises for authors and implementers.
What does build_hierarchy return for a bare list?
Section titled “What does build_hierarchy return for a bare list?”For a section whose entries are all empty-key strings, you get a flat list under the parent key:
users = = alice = bob{ "users": ["alice", "bob"] }If the bare entries have nested CCL of their own, you get a list of objects instead. See Bare List Hierarchy for the normative rule and edge cases.
Are dotted keys like database.host nested?
Section titled “Are dotted keys like database.host nested?”No. database.host is a literal string key containing a dot — not a path. CCL only nests via indentation.
If you want dot-as-path semantics, use the opt-in expand_dotted function. It is gated behind the experimental_dotted_keys feature tag and is not part of core CCL. Implementations are not required to provide it. See Dotted Keys Explained and expand_dotted.
How are tabs handled in continuation lines?
Section titled “How are tabs handled in continuation lines?”There is no tabs_as_whitespace / tabs_as_content choice — that pair has been removed. The real, registered conflict is between two behaviors that govern what happens to a tab character on a continuation line:
continuation_tab_to_space— the tab is normalized to a single space when measuring indentation and emitting the value.continuation_tab_preserve— the tab is kept verbatim in the value.
Implementations declare exactly one. See Continuation Lines and the Behavior Reference.
What happens to CRLF in nested values?
Section titled “What happens to CRLF in nested values?”By default CCL treats only \n as a line terminator, so a stray \r is preserved as part of the value. Implementations that opt into the crlf_preserve_literal behavior must apply that handling uniformly — flat documents and nested sections behave the same way. There is no “flat-only” CRLF mode. See CRLF Handling in Nested Structures.
Why does the “first content line” rule exist?
Section titled “Why does the “first content line” rule exist?”When the parser starts (top-level or inside a recursive call), it has no preceding entry to attach a continuation to. The first non-empty content line therefore always starts a new entry, regardless of its indentation; continuation detection only applies from the second line onward.
Without this rule, a parser using toplevel_indent_strip (baseline indent N = 0) would treat the first indented line as “a continuation of nothing” and either drop it or crash. See Parsing Algorithm and Continuation Lines — Top-Level Parsing for worked examples.