This is why, for example, Solid.js does control flow through <For /> and <Show /> components instead of map/ternaries even though it uses JSX.
Such as:
import * from "svelte";
// ...omitted for brevity.
{
svelte.each(cats, ({ id, name }) => <p>Hello {name}</p>)
}
// ...omitted
This is easy to parse and transform, while being fully within JS.I think a much better recommendation would be an existing template language, iff svelte could understand it with perfect parity.
I hate being handed normal syntax to use when not all of it is normal, or when using it has different semantics than the syntax usually carries.
So the errors remain compile-time, not run-time.
So the developer must remember a new rule: "JS rules when calling foo.each(), Svelte rules when calling svelte.each()". A little harder to remember. Having a unique non-JS syntax makes the distinction obvious.
(Just playing Devil's Advocate here)
There are also technical reasons why `svelte.each` would be problematic, namely the fact that it is a compile-time concept which does not necessarily compile correctly if you move the call into a library, unless you have an extremely sophisticated compiler (aka: a slow compiler)
I am not suggesting that the svelte.each() call be moved into a library; I'm proposing that the callsite is trivial to identify in the AST. Svelte compiler could then do the same thing that it does now.
Grammar enforces where a grammar construct is allowed to exist. A custom grammar can be very restrictive (which it is, to great effect, in Svelte's case).
If we reuse JS grammar, then that comes with expectations of what should semantically work. For example something as simple as `$ = svelte.each` might evade a not-sufficiently-smart compiler. Or maybe `console.log(svelte.each(...))` might mis-compile because nobody ever thought to handle that case.
Having used systems with compile-time grammar constructs that look like runtime constructs, I can tell you that having your expectations about semantics being changed from under your feet can be a very frustrating experience.
Just to be clear, I am NOT saying that Svelte needed to do this. But merely suggesting options for discussion and learning.
[1]: https://github.com/jeswin-unmaintained/isotropy-ast-analyzer... - Here's for instance, some code I wrote for analyzing a JS sort expression. You'd think it'd take just a few hours, until you get to it. Btw, it uses an AST analysis framework I wrote called chimpanzee - it has only one user though. :) https://github.com/jeswin/chimpanzee
In such a case, I think it's less confusing at the end of the day to just have a custom DSL for looping so that there's no clashing with its list of arbitrary limitations.
Which is why we use JS and allow V8/SpiderMonkey/JSC to do it for us :)
But with Svelte 3 I actually agree with their choice now:
1. The extra templating syntax is rather small and concise. And explicit.
- There are very few directives, and they follow the same rules: `{# start block }{: alternative branch}{/end block}`
- external data that comes from Javascript is always `{data}`
- properties of html components that can be bound are always `prop:name|modifiers={data}`
This is in contrast to, say, Vue, where the syntax can never decide where it's going.
And compared to React, this isn't Javascript either if we think about it:
{
svelte.each(cats, ({ id, name }) => <p>Hello {name}</p>)
}
That's a specific extension that compiles to Javascript2. Your work becomes MVC-ish
Your template/html becomes "I have some data, let's display it". And since the template syntax doesn't allow arbitrary logic, you end up collocating transformations of your data with the code that's fetching it. Instead of doing some weird logic inside the template like `data.map.filter.map`
3. But to each their own :)
What really turned me towards Svelte is going through the tutorial and then trying it. It really is good :)
From Svelte: {#each cats as { id, name }, i}
JavaScript already has facility for loops and mapping, and relying on that will automatically get you tooling/IDE support. React handles this aspect quite well, and to me that's a point in favor of React.
I do agree with your post - especially on hooks being a step backward.