This and similar thoughts have been brought up a few times now, so clearly folks care about this more than just a bit.
However, I strongly believe that custom expression syntax is not the way to solve this. Let me explain why.
The ECMAScript language is described in perfect detail by a 800+ page specification, ~70 of which specifically describe the grammar and runtime behavior of expressions. This specification is written with great care by some of the greatest minds in the world, and it is what every browser and other JS runtime implementation relies upon.
So do we in our JIT expression parser that turns attribute values into runtime AST (and the nearly 20.000 tests verifying it) as well our runtime AST responsible for wiring up observation and evaluating those expressions (and the nearly 10.000 tests verifying it).
Deviations from the standard expression syntax introduce exceptions that our users need to learn as a framework-specific thing, and that most likely either clashes with existing valid syntax, or potential future syntax.
For example, this is already valid syntax (grouping operator): repeat.for="(item) of items"
and it does the same thing as repeat.for="item of items"
, just like for ((item) of items)
in normal JS. Does it make sense to do that? Not really. But that’s the grammar as per the specification.
So should we now make the grouping operator invalid in only for-of statements or in all expressions?
Only when there is a comma inside, or in all cases?
What about when it’s nested in another?
Could there be a situation where a user really needs the grouping operator that we might not be able to think of right now?
Who knows.
But we already have this issue with value converters and binding behaviors (which could be solved with the new pipe operator). Increasing the scope of this issue, in my opinion, is a mistake. It’s not a risk we want to take anymore, nor is thinking about all these expression parser rules with an ever-evolving specification.
So now what?
- With destructuring, you can use the value converter approach.
- With
<let>
, you can declare anything you want (just like you would have to in a normal loop)
We could also introduce a hook, for example:
<div repeat.for="item of items" callback="processItem">
</div>
processItem(context, item, items) {
context.index = items.indexOf(item);
}
You could also share common logic this way. This could be an alternative to the hard-coded context properties added by the framework.
However with regards to nested repeaters, we could also make a few tweaks so that you don’t need to do the $parent.$index
thing. That seems unnatural anyway.
In any case, I’m open for discussions w.r.t. a hook (or something like that) or tweaks to the semantics of context traversal, but custom syntax is a no-no for me and I hope folks would agree with that based on my earlier explanation.