No, sorry, I don't think so. Maybe I don't get your point so could you provide an example of how decorators on functions could break the web?
As far as I understand, if you start to use foreign code beyond its API you could break the old code with and without decorators. On Fri, Oct 23, 2015 at 1:52 PM, Andrea Giammarchi < [email protected]> wrote: > OK let me rephrase: it is **not inter-operable** with well known libraries > that might have factories in the wild and no way to distinguish if they are > dealing with new ES6 syntax or old one. > > Having no way to distinguish easily breaks the web. > > Regards > > On Fri, Oct 23, 2015 at 11:44 AM, Salvador de la Puente González < > [email protected]> wrote: > >> Well, I see, it's not worse than other dynamic typing issues (think about >> `invokeThat.call()` being called on undefined or null, the exception only >> gives you a runtime error and you could always wrap in a try-catch, see the >> message and translate to yoour own exception or recover) but that does not >> relate at all with decorators which is my point. I agree on >> `Reflection.isClass` although I should check the spec in the search for >> something related with that specific topic but returning to the previous >> discussion about which syntax to use when decorating functions, I don't see >> this is a blocker for extending present decorator syntax to functions. >> >> On Fri, Oct 23, 2015 at 12:17 PM, Andrea Giammarchi < >> [email protected]> wrote: >> >>> well >>> >>> > Can you point me some example where not distinguishing between >>> functions and classes would be fatal, please? >>> >>> the fact a class throws once invoked like a function isn't enough fatal >>> to you? >>> >>> ```js >>> function invokeThat() { >>> var result = Object.create(this.prototype); >>> return this.apply(result, arguments) || result; >>> } >>> >>> invokeThat.call(function sum(a, b) { return a + b; }, 1, 2); // 3 >>> >>> invokeThat.call(class Point{constructor(x,y){this.x=x;this.y=y;}}, 10, >>> 15); >>> // Uncaught TypeError: Class constructors cannot be invoked without >>> 'new'(…) >>> ``` >>> >>> We are missing a `Reflection.isClass` ... useful or not, we've got two >>> kind of "invokables" and nobody can distinguish from them. >>> >>> Regards >>> >>> >>> >>> >>> On Fri, Oct 23, 2015 at 10:56 AM, Salvador de la Puente González < >>> [email protected]> wrote: >>> >>>> Hi Andrea. >>>> >>>> On Thu, Oct 22, 2015 at 10:34 PM, Andrea Giammarchi < >>>> [email protected]> wrote: >>>> >>>>> 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. >>>>> >>>> >>>> As far as I know, classes in ES6, apart from preventing you from >>>> calling without `new` (and minor subclassing details), are identical to >>>> functions. >>>> >>>> >>>>> 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. >>>>> >>>> >>>> Well, is not as sure you want to wrap a function at all. Suppose: >>>> >>>> ``` >>>> // operaations.js >>>> @priority(2) >>>> function taskA() { doSomething(); } >>>> >>>> @priority(1) >>>> function taskB() { doSomething(); } >>>> >>>> @priority(5) >>>> function taskC() { doSomething(); } >>>> >>>> taskManager.register(taskA, taskB, taskC); >>>> taskManager.run(); // run taking into account priority symbol of the >>>> functions >>>> >>>> // taskManager.js >>>> var priority = new Symbol(); >>>> >>>> function priority(p) { >>>> return function(target) { target[priority] = p; } >>>> } >>>> ``` >>>> >>>> On the contrary, you would want to replace a class completely: >>>> >>>> ``` >>>> @singleton >>>> class system { >>>> get version() { return '1.0.0'; } >>>> get drives() { return ...; } >>>> } >>>> >>>> console.log(system.version); >>>> >>>> function singleton(target) { >>>> return target(); >>>> } >>>> ``` >>>> >>>> I'm not saying is not important to distinguish between classes and >>>> functions, I'm just saying, it is not as important and not critical for the >>>> decorator syntax. It suffices for a framework to make their classes to >>>> inherit from a custom base object with a symbol `isClass` set to true to >>>> allow their own decorators to distinguish between classes and functions but >>>> these are specific-implementation details. What is true is the the syntax >>>> works for regular functions and class based functions. >>>> >>>> >>>>> >>>>> Maybe it's me overlooking at this, but the fact we cannot distinguish >>>>> between classes and functions doesn't feel right to me. >>>>> >>>> >>>> No, sorry, maybe it's me that I can not see a harmful side effect here. >>>> Can you point me some example where not distinguishing between functions >>>> and classes would be fatal, please? Maybe this way, I (and others) >>>> understand your concerns. >>>> >>>> >>>>> >>>>> 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 >>>>> >>>> >>>> Of course, but it is a clear indicator of semantics. It's very valuable >>>> for a language to allow its own declarative semantics to be expressed in a >>>> programmatic fashion as it denotes a very consistent and versatile data & >>>> execution models. >>>> >>>> >>>>> >>>>> >>>>> >>>>> >>>>> >>>>> On Thu, Oct 22, 2015 at 9:26 PM, Salvador de la Puente González < >>>>> [email protected]> 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 < >>>>>> [email protected]> 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 < >>>>>>> [email protected]> 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:[email protected]] *On >>>>>>>> Behalf Of *Andrea Giammarchi >>>>>>>> *Sent:* Thursday, October 22, 2015 10:47 AM >>>>>>>> *To:* Yongxu Ren <[email protected]> >>>>>>>> *Cc:* es-discuss mailing list <[email protected]> >>>>>>>> *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 <[email protected]> >>>>>>>> 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 < >>>>>>>> [email protected]> 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 >>>>>>>> [email protected] >>>>>>>> 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 >>>>>>>> [email protected] >>>>>>>> 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 >>>>>>> [email protected] >>>>>>> https://mail.mozilla.org/listinfo/es-discuss >>>>>>> >>>>>>> >>>>>> >>>>> >>>> >>> >> >
_______________________________________________ es-discuss mailing list [email protected] https://mail.mozilla.org/listinfo/es-discuss

