Metaprogramming can be applied in ways that makes code hard to reason about, but that doesn't mean all metaprogramming is that way.
Decorators, especially the newly standardized decorators, provide a structured for of metadata where the possible actions are limited. Decorators can basically only replace the decorated class member with another member of the same kind: replace an accessor, or a method.
This should make things easier to reason about. The Lit @property() decorator for instance wraps the decorated setter with one that calls `this.requestUpdate()` - that's it.
The alternative is writing all the boilerplat by hand, which most users don't want to do (but is possible) or the adhoc metaprogramming systems that are fairly popular now, and I think those are much harder to reason about.
I mean couldn’t lit have just exposed a method like this.setReactiveProperty that calls this.requestUpdate and sets the property? The need for decorators seems because the api was designed to use decorators not because they are particularly necessary for this sort of thing
Lots of frameworks already have the ability to set properties on elements declaratively in templates. By using setters we work with their data binding system without hanging to teach them about Lit-specific APIs.
Decorators, especially the newly standardized decorators, provide a structured for of metadata where the possible actions are limited. Decorators can basically only replace the decorated class member with another member of the same kind: replace an accessor, or a method.
This should make things easier to reason about. The Lit @property() decorator for instance wraps the decorated setter with one that calls `this.requestUpdate()` - that's it.
The alternative is writing all the boilerplat by hand, which most users don't want to do (but is possible) or the adhoc metaprogramming systems that are fairly popular now, and I think those are much harder to reason about.