Formatters are functions from JSON nodes -> JSON nodes. Strings are
special cases of JSON nodes. In a {value|formatter1|formatter2}
chain, the last thing should be a string.
Predicates are functions from JSON nodes -> booleans. It was pointed
out that if you define *truth* on JSON nodes, which we've already
done, then formatters can serve as predicates.
But it doesn't work, because in the "false" case you may still need
substitutions:
{.section group|plural?}
There are {num} people in group {name}.
{.or}
There is one person in group {name}.
{.end}
So the plural? predicate can't just return "null", since we still need {name}.
Also, predicates and formatters do different things, so we shouldn't
make them the same concept. Formatters are concerned with
substitution of values, and apply only to substitutions. Predicates
are concerned with *whether* to show a section. You can combine the
two on the same section (they are *orthogonal*):
{.section group|plural?}
{@|fancy-formatter-for-plural-groups}
{.or}
There is one person in group {name}. {# No fancy formatter}
{.end}
Or use a totally different file for plurals:
{.section group|plural?}
{@|template-file plural-group.jsont} {# the "include" feature}
{.or}
There is one person in group {name}.
{.end}
Andy
I don't see the rule that this is implying. If plural? returns
"null", then how does the {.or} section have access to {name}? I
don't see how wrapping it in another section does it. Any rule I can
infer here will have a bunch of special cases and require keeping
track of more state.
>> {.section group|plural?}
>> {@|fancy-formatter-for-plural-groups}
>> {.or}
>> There is one person in group {name}. {# No fancy formatter}
>> {.end}
>
> {.section group|plural?}
> {@|fancy-formatter-for-plural-groups}
> {.or}
> There is one person in group {group.name}. {# No fancy formatter}
> {.end}
Also don't get this -- is the {group.name} vs. {name} a purposeful
disambiguation? I don't see why this is done differently than the
first case.
>
>> Also, predicates and formatters do different things, so we shouldn't
>> make them the same concept. Formatters are concerned with
>> substitution of values, and apply only to substitutions. Predicates
>> are concerned with *whether* to show a section.
>
> This is like saying that calls to an int(*)(void)
> and calls to a char(*)(void) do different things, so
> we can't refer to them both as function calls.
> The | syntax does the same thing in both cases: it takes
> the data, pipes it through the function, and uses the
> resulting value.
It's similar but not the same. In one case we substitute the
resulting value into the output. In the other we test the resulting
value for its "truth" and decide *whether* to expand a section into
the output. These are different things.
sections and substitutions are different. And formatters and
predicates are different. Although I agree that there is way to make
formatters apply to both sections AND substitutions -- there is also a
straightforward way for *predicates* to apply to section and
substitutions (coming next mail).
I want to avoid a 2x2 matrix of special cases, and instead have the
concepts be orthogonal. The special case I see here is: "If a
formatter is used in a substitution, its value is used. If it's used
in a section, then the value is tested for truth and that determines
if it's shown."
This morning I came up with a nice consistent model, which I'll write next.
Andy
I was assuming here that the new value is pushed on
the name lookup stack only in the true half of the .section.
>>> {.section group|plural?}
>>> {@|fancy-formatter-for-plural-groups}
>>> {.or}
>>> There is one person in group {name}. {# No fancy formatter}
>>> {.end}
>>
>> {.section group|plural?}
>> {@|fancy-formatter-for-plural-groups}
>> {.or}
>> There is one person in group {group.name}. {# No fancy formatter}
>> {.end}
>
> Also don't get this -- is the {group.name} vs. {name} a purposeful
> disambiguation? I don't see why this is done differently than the
> first case.
There's already a value stack, so if group was a valid name
in the .section line, then even if something did get pushed
onto the value stack during the .or, the lookup could still
find group again, and then use group.name.
Russ