Expressions
Audience: collection authors and tool authors using computed fields.
Authoritative for:
- the shared expression language
- computed field definitions, sibling-field scope, and stored-value evaluation
- date-part fields derived from a sibling date (
from_date)
See also:
- Foundations: the shared expression language
- Field Definition Reference: field types, constraints, and generation
- Managed Notes and Properties: stored frontmatter and materialization
- Authoring: immutable fields and additional generation strategies
This optional module defines computed fields as a consumer of the shared expression language. Its scope is sibling-field derivation; field types and general materialization remain with their linked owners.
computed#
computed defines a stored text field whose value is derived from sibling frontmatter fields instead of being authored directly. Unlike generated, it is not about value origination from time, randomness, identity, or tool-specific automation; it is the single schema-defined mechanism for sibling-field derivation in this specification version. It uses the shared text-template expression context.
Example:
first_name:
type: text
nullable: false
last_name:
type: text
nullable: false
full_name:
type: text
computed: '${capitalize(first_name)} ${capitalize(last_name)}'
nullable: false
Rules:
- FDR-218
computedMAY be omitted. - FDR-219 If present,
computedMUST be a non-empty string in the shared text-template expression context. - FDR-220
computedMAY be declared only on top-level frontmatter fields. - FDR-221
computedis the single schema-defined mechanism for deriving a field value from sibling fields of the same managed note. - FDR-222
generatedandcomputedare distinct:generatedcovers value origination without sibling-field inputs;computedcovers sibling-field derivation. - FDR-223 A field declaring
computedMUST declaretype: text. - FDR-224 A field declaring
computedMUST NOT declaregenerated,default_value, orconst_value. - FDR-225 A field declaring
computedMUST NOT declareimmutable: true, because its stored value is recomputed from its dependencies. - FDR-226
computeddoes not make a field virtual. Computed fields still follow the same type validation, optionality, stored-frontmatter, and canonical materialization rules as other declared fields. - FDR-227 For
computed, the shared expression-language scope is the managed note's sibling top-level fields in the effectivefrontmatter. - FDR-228 Every reference name used by a
computedexpression MUST resolve to a sibling top-level field declared in the same effectivefrontmatter, and MUST NOT resolve to the declaring field itself or to a field that itself declarescomputed. - FDR-229 Every field referenced by a
computedexpression MUST declaretype: text. - FDR-230
computeduses the shared expression-language syntax and transform semantics; it defines no local syntax extensions. - FDR-231 A
computedexpression is evaluated against the managed note's materialized sibling-field values after non-computed defaults, schema-derived values, and generation strategies have been applied. - FDR-232 Every referenced field MUST hold a concrete non-null string when the
computedexpression is evaluated; otherwise the computed field has no conforming value and MUST be reported asinvalid_field_value. - FDR-233 Tools that create, scaffold, import, normalize, or otherwise write managed-note frontmatter MUST evaluate every
computedexpression and store the resulting value before writing the note. - FDR-234 A stored computed value MUST equal the result of its
computedexpression; a mismatch is aninvalid_field_valuefailure. - FDR-235 The computed result MUST satisfy the field's declared constraints; a schema MUST NOT combine
computedwith constraints its expression cannot satisfy. - FDR-236
computedMUST NOT depend on the note body, resolved note links, query results, collection-global state, or any data outside the sibling-field scope defined above. - FDR-237 A
computedfield whose stored value disagrees with its evaluated expression is a note-levelinvalid_field_valuefailure, not a schema-shape failure. - FDR-238 A syntactically invalid shared expression, an unresolved sibling-field reference, a type-incompatible reference, or an unknown transform name makes the declaring artifact invalid.
from_date#
Periodic notes file and query by their period, so they store its parts: a
weekly note keeps its ISO year and week beside its date. from_date derives
such a part from one sibling date or datetime field with the storage-pattern
formats, so tools fill and check it instead of authors:
week_start:
type: date
nullable: false
year:
type: integer
from_date: {field: week_start, part: GGGG}
week:
type: text
from_date: {field: week_start, part: WW}
Rules:
- FDR-293
from_dateMAY be declared only on a top-levelintegerortextfield, as a mapping whosefieldnames a sibling top-leveldateordatetimefield and whosepartis a storage date format. - FDR-294
partMUST beYYYY,MM,DD,Q,WW, orGGGGon anintegerfield, and any of those orYYYY-MMorYYYY-MM-DDon atextfield. - FDR-295 The derived value formats the source's effective value as Storage Rules do (
NTS-120,NTS-128); anintegerfield holds that text's numeric value. - FDR-296 A field declaring
from_dateMUST NOT declarecomputed,generated,default_value,const_value, orimmutable: true. - FDR-297 When the source has no non-null effective value, the derived value is null.
- FDR-298 Writers MUST store the derived value as
FDR-233requires forcomputed, and a stored value differing from it is aninvalid_field_valuefailure.
Links to Enclosing Periods#
Periodic notes usually link to the notes of the periods that contain them.
Those notes are named from their own dates, so a from_date part, or a
computed field joining parts, yields the target's name, and a self_field
content expansion renders it as a
link. A daily note on 2025-12-29 belongs to week 2026-W01 but to month
2025-12:
date: {type: date, nullable: false}
iso_year: {type: text, from_date: {field: date, part: GGGG}}
week: {type: text, from_date: {field: date, part: WW}}
week_note: {type: text, computed: '${iso_year}-W${week}'}
month_note: {type: text, from_date: {field: date, part: YYYY-MM}}
<!-- typedmark:expansion {"id":"week","mode":"auto","state":"materialized","source":{"kind":"self_field","field":"week_note"},"render":{"item":"[[${value}]]"}} -->
[[2026-W01]]
<!-- /typedmark:expansion -->
The rendered name matches the target type's note_name_pattern by convention
only, and the link is body text, not a relationship: queries use the stored
parts instead. A week that ends in another month, and links to the previous or
next period, need date arithmetic, which the expression language does not
define (FND-70).
Shared Expression Language#
Several governed surfaces need to derive values from structured data. Rather than defining separate mini-languages for each feature, TypedMark defines one shared expression language and lets each consumer define its own input scope, required result type, and evaluation timing.
Example:
computed: '${capitalize(note_type)}: ${title}'
Rules:
- FND-58 TypedMark defines one shared expression language. A governed surface uses it only when another rule explicitly says so.
- FND-59 This specification version defines exactly one shared expression context: the text-template context.
- FND-60 A text-template expression is a string composed of literal text plus zero or more placeholders.
- FND-61 A placeholder has the form
${name}or${transform(name)}. - FND-62
nameandtransformin the shared expression language MUST each match the field-name grammar^[a-z][a-z0-9_]*$. - FND-63 The shared expression parser operates on the decoded string value after parsing its containing YAML or JSON syntax. Within that string,
\\represents a literal backslash and\${represents a literal${; any other backslash escape is invalid. - FND-64 Shared-expression evaluation MUST be deterministic and side-effect free.
- FND-65 Shared expressions MUST NOT read the current time, random sources, the filesystem, the network, or any state outside the consumer-defined input scope.
- FND-66 The shared transform library in this specification version contains exactly
uppercase,lowercase, andcapitalize. - FND-67
uppercase(name)andlowercase(name)each take exactly one reference-name argument and return the referenced string converted to uppercase or lowercase respectively, using locale-independent Unicode case mapping. - FND-68
capitalize(name)takes exactly one reference-name argument and returns the referenced string with its first Unicode code point converted to uppercase and its remaining code points converted to lowercase; the empty string remains empty. - FND-69 This specification version defines no other placeholder forms, no nested transform calls, and no transform arguments other than one reference name.
- FND-70 This specification version defines no dot access, bracket access, arithmetic, comparisons, boolean operators, conditionals, list indexing, link traversal, regex operators, or date arithmetic in the shared expression language.
- FND-71 Every consumer of the shared expression language MUST define the expression's available reference names, required result type, evaluation timing, and how absent or null input values are handled.
- FND-72 A consumer MAY narrow the shared language's available reference names or result types, but it MUST NOT redefine the shared syntax or transform semantics.
- FND-73 A syntactically invalid shared expression or an unknown transform name makes the declaring artifact invalid.