-
Notifications
You must be signed in to change notification settings - Fork 126
Description
So, I've read through the issues asking for functions to support being decorated, and I have a different take: I don't think classes should support decorators, which also solves that semantic divide. The only reason to have decorator syntax at all is because of the limitations of object property syntax with respect to being able to alter the value separate from the name and being able to modify the descriptor. This is why the meat of decorators take three arguments: the target, the name, and the descriptor.
I can totally appreciate why developers would feel the need to have this syntax for these cases. I see @nonenumerable and I'm like "wow, yeah!! I'd love to be able to have that, instead of sitting around with the full verbosity of Object.defineProperty". Or being able to alter a function and turn it into a getter and setter: that also adds real power that I didn't have before without pretty painful workarounds where I stop using anything remotely straightforward and refactor to use Object.defineProperty.
However, for both bare functions and classes, there is very almost no difference from just calling the "decorator" directly on the value. The reason that we need this syntax in Python is because the way indentation kills the ability for that language to have anonymous functions, an issue JavaScript does not have. Meanwhile, attempting to support both class decorators and method decorators leads to two forms of decorators with different arguments and different semantics, which just seems strange.
Further, supporting decorators for classes begs the question of supporting them on functions, and in addition to opening the Pandora's Box of function hoisting scope, one realizes that it further emphasizes the semantic difference between the two different kinds of decorators: the various decorators in the draft specification for this feature all sound reasonable to also use with bare functions, but they all assume that there is a target object and a descriptor involved, which isn't often the case with functions.
(And, if we want to compare to Python for a second, we will see that while it supports decorators on various kinds of things, including functions and classes, in all cases the decorator has the same semantics: it returns a function that takes a single value argument and returns a replacement value that will be used for the binding. All of the "meta" information about class members is stored on the member, not in a descriptor of the class, so there is no semantics split between the use cases.)
I thereby will argue that this feature should be postponed for classes (as again: it is effectively the same syntax to just call the decorator passing the class as an argument, it will make people stop asking for this feature to be implemented on bare functions, and, and I really think this is important, it means that there is only a single semantics for what arguments a decorator takes: a decorator fundamentally acts on a target, name, and descriptor) but implemented for members (where it seems valuable).
(BTW: the people who are arguing that people will create degenerate classes in order to get access to decorators, to me, are actually helping provide an argument for this, as they are failing to notice that the different semantics for decorators means that a lot of the decorators people will want to define will only work for class/object members and won't work for bare functions as there will not be any descriptor to modify; a lot of these use cases for decorators, not just the syntax, actually require an object.)
(I constructed this as a separate issue because it is asking for the exact opposite result from the other issues talking about this overall concept. I'm terribly sorry if someone fundamentally disagrees that this is the correct approach to organizing these conversations. FWIW, without threads, I'd think that having this idea in the same issue as the opposite idea would probably make it fundamentally more confusing and, if nothing else, clutter the conversation of people talking about how to support bare functions.)