Decorators for functions

Andrea Giammarchi andrea.giammarchi at gmail.com
Thu Oct 22 20:34:46 UTC 2015


which one is true?

> I think there is no ambiguity at all ... decorating a function should be
like decorating a class

'cause I think those are very different things. You gonna wrap for sure the
first one, you most likely ever even bother replacing the class, rather
enriching its prototype or its public statics.

Maybe it's me overlooking at this, but the fact we cannot distinguish
between classes and functions doesn't feel right to me.

Regards

P.S. babel has some target (browsers mostly, and nodejs) but it shouldn't
be the reason to choose a pattern instead of another, or at least not the
only one





On Thu, Oct 22, 2015 at 9:26 PM, Salvador de la Puente González <
salva at unoyunodiez.com> wrote:

> Hi people.
>
> After reading the conversation, I think there is no ambiguity at all or,
> may be, it must be there: decorating a function should be like decorating a
> class, you can not distinguish between them and that's all. Just look at
> the code generated in Babel:
>
> https://babeljs.io/repl/#?experimental=true&evaluate=true&loose=false&spec=false&code=%40decorator%0Aclass%20A%20{}
> <https://babeljs.io/repl/#?experimental=true&evaluate=true&loose=false&spec=false&code=%40decorator%0Aclass%20A%20%7B%7D>
>
> You'll see:
>
> ```
> A = decorator(A) || A;
> ```
>
> And this is the traditional notion of decorator we see in Python and other
> languages. A simple way to check for a generic decorator would be:
>
> ```
> function decorator(target, name='', descriptor=null) {
>   if (descriptor) console.log('Decorating a member');
>   else console.log('Decorating either a function or class');
> }
> ```
>
> And it's very consistent if you think the only difference a ES6 class
> introduces is that you are not allowed to call the class as a function.
>
> So, the generated code for:
>
> ```
> @decorator
> function A() { }
> ```
>
> Should be:
>
> ```
> function A() {}
> A = decorator(A) || A;
> ```
>
> And that's all, if you always add the overwrite after the definition,
> hoisting is irrelevant but if it worries you, simply avoid hoisting when
> decorating as Axel suggested.
>
>
> PS: Well thought, it must be possible for an hypothetical reflection
> function to determine if a function is a class or not as classes are marked
> to throw when they are not invoked with new.
>
> On Thu, Oct 22, 2015 at 9:52 PM, Andrea Giammarchi <
> andrea.giammarchi at gmail.com> wrote:
>
>> Ron, there's **no way** you can distinguish a class from  a generic
>> function in current specifications.
>>
>> Having one argument won't tell me much, having a way to know that is not
>> a class I need to decorate (traits/mixins) but just a function, so ignoring
>> its prototype and do something else, would be cool but it's unfortunately
>> not possible or portable.
>>
>> How would you distinguish between a class or a function for a generic
>> decorator? Or all you are saying is that decorators shouldn't be able to
>> distinguish at all between a class, rather than a function?
>>
>> Regards
>>
>>
>>
>>
>> On Thu, Oct 22, 2015 at 7:32 PM, Ron Buckton <Ron.Buckton at microsoft.com>
>> wrote:
>>
>>> Andrea,
>>>
>>>
>>>
>>> Is your concern about disambiguating the usage of a decorator at the
>>> call site or within the body of the decorator? In the current proposal, you
>>> can decorate a class member, or the class itself.
>>>
>>>
>>>
>>> When decorating a class member, three arguments are passed to the
>>> decorator: The target, the property key (string or symbol), and the
>>> descriptor. When decorating the class, one argument is passed to the
>>> decorator: The constructor function. Generally this means that you can
>>> disambiguate the usage of the decorator based simply on `arguments.length`,
>>> or testing for `undefined` for the property key or descriptor.
>>>
>>>
>>>
>>> Would it be better to have a more consistent way to disambiguate the
>>> usage of a decorator from within the decorator? This could be addressed
>>> with something like a Reflect.getDecoratorUsage API or a
>>> `function.decoration` meta-property or the like. Consider something like:
>>>
>>>
>>>
>>> ```js
>>>
>>> function memoize(target, key, descriptor) {
>>>
>>>   switch (Reflect.getDecoratorUsage(arguments)) {
>>>
>>>     case "class":
>>>
>>>       // `target` is the class constructor. `key` and `descriptor` are
>>> undefined.
>>>
>>>
>>>
>>>     case "function":
>>>
>>>       // `target` is the function. `key` and `descriptor` are undefined.
>>>
>>>
>>>
>>>     case "method":
>>>
>>>       // `target` is the object containing the method (e.g. constructor
>>>
>>>       // for a static method, prototype for a prototype method, or
>>>
>>>       // instance for an object literal method).
>>>
>>>       // `key` is the string or symbol property name for the method.
>>>
>>>       // `descriptor` is the property descriptor for the method.
>>>
>>>
>>>
>>>     case "accessor":
>>>
>>>       // `target` is the object containing the accessor (e.g.
>>> constructor
>>>
>>>       // for a static accessor, prototype for a prototype accessor, or
>>>
>>>       // instance for an object literal accessor).
>>>
>>>       // `key` is the string or symbol property name for the accessor.
>>>
>>>       // `descriptor` is the property descriptor for the accessor.
>>>
>>>   }
>>>
>>> }
>>>
>>> ```
>>>
>>>
>>>
>>> Ron
>>>
>>>
>>>
>>> *From:* es-discuss [mailto:es-discuss-bounces at mozilla.org] *On Behalf
>>> Of *Andrea Giammarchi
>>> *Sent:* Thursday, October 22, 2015 10:47 AM
>>> *To:* Yongxu Ren <renyongxu at gmail.com>
>>> *Cc:* es-discuss mailing list <es-discuss at mozilla.org>
>>> *Subject:* Re: Decorators for functions
>>>
>>>
>>>
>>> Removing ambiguity is my point since the very first post: current
>>> proposal is about a target, a property name, and a descriptor for such
>>> property ... having functions/variables decorators have no target (in
>>> strict mode undefined can't be a target, right?) and not necessarily a
>>> descriptor, or if any, always a data one with fields that makes no  sense
>>> (like enumerable within a private scope ... what does that even mean)
>>>
>>>
>>>
>>> I'm all in for a distinct, separate, syntax to decorate "callables" or
>>> other variables as long as the current proposal will make for ES7 and won't
>>> be bothered by this different requirement.
>>>
>>>
>>>
>>> Regards
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>> On Thu, Oct 22, 2015 at 6:29 PM, Yongxu Ren <renyongxu at gmail.com> wrote:
>>>
>>> I don't think
>>>
>>>
>>>
>>> > ```@@ or @() or @::meomize```
>>>
>>>
>>>
>>> would really help much, you can tell what the decorator does by simply
>>> looking at its name. And looks like you can not use @ and @@ for the
>>> same decorator function without adding extra condition checking inside the
>>> function.
>>>
>>>
>>>
>>> There are two patterns that we have discussed here, they are actually
>>> quite distinct. I still think we should support decorator on variables, but
>>> maybe we should have 2 distinct syntax for the normal decorators and
>>> "ambient decorators"(from Jonathan's post):
>>>
>>>
>>>
>>> 1.  decorator that alter the code behavior,  the currently proposed
>>> decorator. Such as ```@memoize```
>>>
>>>
>>>
>>> 2. decorator that absolutely does not alter the code behavior, only used
>>> for optimization, checking or debugging. Instead of @, a distinct syntax
>>> will be much clearer ex.```@annotatition@``` (Maybe it should be called
>>> annotation instead?):
>>>
>>> ```
>>>
>>> @deprecated@
>>>
>>>
>>>
>>> @number,number=>string@/*type checking*/
>>>
>>>
>>>
>>> @debug("this message will only print in development mode")@
>>>
>>> ```
>>>
>>>
>>>
>>> it sounds like terrible idea to have a decorator in code that you can
>>> not figure out if it will alter the code behavior by looking at it. I do
>>> like to see all the new ideas been added into javascript, but it is also
>>> necessary to eliminate the ambiguity whenever possible.
>>>
>>>
>>>
>>>
>>>
>>> On Thu, Oct 22, 2015 at 11:20 AM, Jonathan Bond-Caron <
>>> jbondc at gdesolutions.com> wrote:
>>>
>>> On Thu Oct 22 07:44 AM, Andreas Rossberg wrote:
>>> > > determined at creation time, allowing for massive engine
>>> optimization,
>>> >
>>>
>>> Ya I'm not sure from which hat "massive engine optimization" comes from?
>>>
>>> What's meant is likely using decorators as annotations (compile time
>>> optimizations hints):
>>> http://www.google.com/patents/US7013458
>>> <https://na01.safelinks.protection.outlook.com/?url=http%3a%2f%2fwww.google.com%2fpatents%2fUS7013458&data=01%7c01%7cron.buckton%40microsoft.com%7c4f28552d1837468197db08d2db08dcea%7c72f988bf86f141af91ab2d7cd011db47%7c1&sdata=atTz2em0YIlXUvUVgiWsZ5xKNjJsIOzm3wLejdDl33E%3d>
>>>
>>> Or 'ambient decorators':
>>>
>>> https://github.com/jonathandturner/brainstorming/blob/master/README.md#c6-ambient-decorators
>>> <https://na01.safelinks.protection.outlook.com/?url=https%3a%2f%2fgithub.com%2fjonathandturner%2fbrainstorming%2fblob%2fmaster%2fREADME.md%23c6-ambient-decorators&data=01%7c01%7cron.buckton%40microsoft.com%7c4f28552d1837468197db08d2db08dcea%7c72f988bf86f141af91ab2d7cd011db47%7c1&sdata=1aXPAnWuPpVgE3wCYZqcEnTaksCKqzwuq0bGLkkG8Uo%3d>
>>>
>>> There's 2 patterns (maybe more?):
>>> (a) Tagging a 'tree transformation'  on a node.
>>> (b) Metadata at compile time on a node.
>>>
>>> The thing about (b) is it can easily live outside of the code (like in
>>> typescript where you have an optional header/declaration file)
>>>
>>> With (a), it seems more conservative to see how it gets used with
>>> classes before bolting on to functions (opinion: end result in java is not
>>> something to be proud of).
>>>
>>>
>>> _______________________________________________
>>> es-discuss mailing list
>>> es-discuss at mozilla.org
>>> https://mail.mozilla.org/listinfo/es-discuss
>>> <https://na01.safelinks.protection.outlook.com/?url=https%3a%2f%2fmail.mozilla.org%2flistinfo%2fes-discuss&data=01%7c01%7cron.buckton%40microsoft.com%7c4f28552d1837468197db08d2db08dcea%7c72f988bf86f141af91ab2d7cd011db47%7c1&sdata=YHeobU0gimD8xIX0FwR3GAdjKwWiwOGNGUWVi%2bHZARg%3d>
>>>
>>>
>>>
>>>
>>> _______________________________________________
>>> es-discuss mailing list
>>> es-discuss at mozilla.org
>>> https://mail.mozilla.org/listinfo/es-discuss
>>> <https://na01.safelinks.protection.outlook.com/?url=https%3a%2f%2fmail.mozilla.org%2flistinfo%2fes-discuss&data=01%7c01%7cron.buckton%40microsoft.com%7c4f28552d1837468197db08d2db08dcea%7c72f988bf86f141af91ab2d7cd011db47%7c1&sdata=YHeobU0gimD8xIX0FwR3GAdjKwWiwOGNGUWVi%2bHZARg%3d>
>>>
>>>
>>>
>>
>>
>> _______________________________________________
>> es-discuss mailing list
>> es-discuss at mozilla.org
>> https://mail.mozilla.org/listinfo/es-discuss
>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20151022/8e948562/attachment-0001.html>


More information about the es-discuss mailing list