The text format
How a .dxn document is put together: one value, an optional header, separators that do not matter, comments, identifiers, and the three prefixes that introduce everything beyond plain scalars and lists.
Documents and the header
A document is exactly one value — usually a map, but 42 or [1 2 3] are complete documents too. It may begin with the header @dxn and a version string; the header is optional and allowed only as the first form.
@dxn "1.0"
# settings for the importer
%{ batch: 500 }Whitespace and commas
Spaces, tabs, line breaks and commas are all separators, and none of them carries meaning — not even a trailing or doubled comma. These lines are the same map, and the list below loses nothing but punctuation:
%{x: 1, y: 2}
%{x: 1 y: 2}
%{
x: 1
y: 2
}[1,,, 2,]
[1 2]
Comments
A # starts a comment that runs to the end of the line; no space is needed after it. There are no block comments. Comments are gone once a document is parsed — no reader can hand them back, and the binary form has no place for them.
%{
retries: 3 # per request
#disabled is still just a comment
}%{retries:3}Identifiers
Symbols, keywords, struct names and tag names share one rule. An identifier starts with a letter (Unicode XID_Start) or _ and continues with letters, digits (XID_Continue), -, ? and !. A single / may split it into a namespace and a name. So retry-after, valid?, Point and my-app/money are all identifiers.
Reserved: nil, true, false, NaN and Infinity. None of the six sigil characters may begin a bare identifier:
| Sigil | Starts |
|---|---|
# | a comment |
@ | a tag, a set @{…} or the discard @_ |
% | a map %{…} or a struct %Name{…} |
~ | a date, time, timestamp or regex sigil |
? | a character |
: | a keyword |
Tags
A tag is @, an identifier, and the one value it applies to: @uuid "…", @ordered %{…}. The built-in tags are @ordered, @sorted-set, @array, @datetime, @duration, @uuid, @uri and @bytes, plus @dxn for the header. Any other name is a custom tag — see custom tags.
Discarding a value
@_ reads the value after it and drops it. Unlike a comment, the discarded value must still be valid DXN, so a broken one is a parse error rather than silently skipped. It is the quick way to switch off one element of a list or one value in a file.
[1 @_ "skip me" 2 3]
[1 2 3]