Summary
The Formulas docs describe CONCAT_WS as "Joins values with a separator — the last value is used as the separator" and add that "When no values resolve... most functions return undefined." But the partial-resolution case — when some inputs are absent and others present — isn't documented. This case is the most useful one in practice (it's how you express coalesce/fallback patterns that the formula DSL otherwise can't), and the actual behavior is better than the docs suggest. Worth spelling out so users can confidently rely on it.
What I tested
Created a temporary entity type with three properties:
a — string
b — string
combined — formula: a b ' / ' CONCAT_WS
Then four instances with different combinations of a and b. Read back the formula's stored value.
a |
b |
combined |
"A" |
"B" |
"A / B" |
"A" |
absent |
"A" |
| absent |
"B" |
"B" |
| absent |
absent |
"" (empty string) |
Useful findings (please document)
- Absent values are skipped cleanly. When one input is present and another absent,
CONCAT_WS returns only the present value — no stray separator. This makes it a usable fallback / coalesce pattern. Example: value_a value_b ' / ' CONCAT_WS returns value_a when value_b is absent.
- Both-absent case returns empty string, not
undefined. Slightly different from the "most functions return undefined" statement in the docs. The combined property gets written with value "" in this case (the property exists, with empty string value). Whether that's intentional or a minor inconsistency with MIN/MAX/AVERAGE is unclear — but it's worth being explicit either way.
Suggested docs change
Under Formulas → Empty Input Behaviour, add a row for CONCAT_WS and clarify the partial-resolution case:
| Function | Empty-input result | Partial-input behaviour |
|------------|--------------------|--------------------------|
| CONCAT | undefined | concatenates resolved values |
| CONCAT_WS | "" (empty string) | joins resolved values, skips absent ones (no stray separators) |
Or add a dedicated "Coalesce / fallback patterns" subsection showing the idiom — it's a non-obvious but very useful capability.
Why this matters in practice
We're using this for property inheritance in Polyphony's Entu schema — editions can override their parent work's voicing / duration / language, with a *_display formula that shows either the edition's own value (if set) or the work's value (if not), or both side-by-side when they diverge:
voicing _parent.work.original_voicing ' / ' CONCAT_WS
This wouldn't be safe to rely on without the empirical confirmation above — the docs leave the behavior ambiguous enough that I had to live-probe before committing to it.
Summary
The Formulas docs describe
CONCAT_WSas "Joins values with a separator — the last value is used as the separator" and add that "When no values resolve... most functions return undefined." But the partial-resolution case — when some inputs are absent and others present — isn't documented. This case is the most useful one in practice (it's how you express coalesce/fallback patterns that the formula DSL otherwise can't), and the actual behavior is better than the docs suggest. Worth spelling out so users can confidently rely on it.What I tested
Created a temporary entity type with three properties:
a— stringb— stringcombined— formula:a b ' / ' CONCAT_WSThen four instances with different combinations of
aandb. Read back the formula's stored value.abcombined"A""B""A / B""A""A""B""B"""(empty string)Useful findings (please document)
CONCAT_WSreturns only the present value — no stray separator. This makes it a usable fallback / coalesce pattern. Example:value_a value_b ' / ' CONCAT_WSreturnsvalue_awhenvalue_bis absent.undefined. Slightly different from the "most functions return undefined" statement in the docs. Thecombinedproperty gets written with value""in this case (the property exists, with empty string value). Whether that's intentional or a minor inconsistency withMIN/MAX/AVERAGEis unclear — but it's worth being explicit either way.Suggested docs change
Under Formulas → Empty Input Behaviour, add a row for
CONCAT_WSand clarify the partial-resolution case:Or add a dedicated "Coalesce / fallback patterns" subsection showing the idiom — it's a non-obvious but very useful capability.
Why this matters in practice
We're using this for property inheritance in Polyphony's Entu schema — editions can override their parent work's
voicing/duration/language, with a*_displayformula that shows either the edition's own value (if set) or the work's value (if not), or both side-by-side when they diverge:This wouldn't be safe to rely on without the empirical confirmation above — the docs leave the behavior ambiguous enough that I had to live-probe before committing to it.