Claus Ibsen created CAMEL-24921:
-----------------------------------

             Summary: camel-core: read a predicate inside ${ } in the Simple 
language, as EL and Groovy do
                 Key: CAMEL-24921
                 URL: https://issues.apache.org/jira/browse/CAMEL-24921
             Project: Camel
          Issue Type: Improvement
          Components: camel-core
            Reporter: Claus Ibsen


h3. What the language does today

Tested on 4.23.0-SNAPSHOT:

|| expression || today ||
| {{$\{header.n > 0 ? 'positive' : 'negative'\}}} | works |
| {{$\{header.n > 0\}}} | error: _Operators go outside the function_ |
| {{$\{header.n\} > 0}} | works |
| {{$\{header.n > 0 && header.n < 10 ? 'in' : 'out'\}}} | error (CAMEL-24920) |

Operators inside the braces are already parsed - as the condition of a ternary 
- but only comparisons, never {{&&}} or {{||}}, and never a compound condition. 
Outside a ternary the same characters are refused. A person has to hold three 
overlapping rules in their head.

h3. Why the wrong form is the natural one

Every other language that uses {{$\{ \}}} treats the braces as a complete 
expression: Jakarta EL ({{$\{user != null && !user.list.isEmpty()\}}}), Groovy 
GString, JavaScript template literals, Thymeleaf with SpEL. In Simple, {{$\{ 
\}}} delimits a value and the template is what surrounds it. Both models are 
defensible - the trouble is that Simple looks like EL and is not.

h3. Evidence that a better message does not fix it

In the AI route benchmark (20 runs of four HTTP examples with a local model 
driving the camel-jbang MCP tools), _Operators go outside the function_ fired 
56 times across four series. The message already prints the corrected 
expression back. Of the 52 refusals followed by another attempt, only *17 were 
free of the same mistake* - it is repeated two times out of three. For 
comparison, the hint for {{handled: true}} (CAMEL-24915) was obeyed 11 times 
out of 11. A message cures a shape nobody has seen before; it does not cure a 
habit carried in from another language.

h3. What it would cost, measured

Corpus: every {{$\{...\}}} in a Camel context across camel (route tests via the 
{{simple(...)}} literal, route YAML and XML), camel-kamelets, camel-examples 
and camel-jbang-examples. Maven properties and prose excluded. *3425 uses, 804 
unique expressions.*

How many would an expression parser re-read?

|| rule || re-read ||
| any operator character anywhere | 564 uses (16%) |
| ignoring quotes, {{[...]}} and {{(...)}}, and colon-prefixed functions 
({{date:}}, {{bean:}} ...) | 61 uses (1.8%) |
| and requiring whitespace around the operator | *1 use (0.03%)* |

The 61 are all one shape: a dotted name whose last segment has a hyphen - 
{{$\{header.Content-Length\}}}, {{$\{exchangeProperty.aws-s3-bucket\}}}. None 
has a space around the hyphen. The single remaining use is an existing ternary, 
which is meant to be an expression. The bracket form is already safe: 
{{$\{header[Content-Type]\}}} and {{$\{header[ce-file]\}}} - 516 of the 564 raw 
hits - live inside {{[...]}}, which a top-level scanner never enters.

h3. Proposal

If the inside of {{$\{ \}}} parses as a predicate or an arithmetic expression 
*with whitespace-separated operators at the top level*, evaluate it as one; 
otherwise it is a function, exactly as today. Simple already requires 
whitespace around the ternary's {{?}} and {{:}}, so the rule is not new. This 
subsumes the ternary instead of sitting beside it, and CAMEL-24920 disappears 
with it.

Before any code:
# a prototype parser with the 3425-expression corpus as a regression suite - 
every expression must produce the same value before and after
# a decision on the template case: {{$\{header.n\} > 5}} in a text template 
produces {{5 > 5}}, while {{$\{header.n > 5\}}} would produce {{true}}. Both 
are useful and they must not collide
# the error message when the inside does not parse, which is where the current 
design pays off - it can say what is wrong and where, instead of refusing the 
shape



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to