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 < andrea.giammar...@gmail.com> 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 < > sa...@unoyunodiez.com> wrote: > >> Hi Andrea. >> >> On Thu, Oct 22, 2015 at 10:34 PM, Andrea Giammarchi < >> andrea.giammar...@gmail.com> 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 < >>> sa...@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.giammar...@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.buck...@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-boun...@mozilla.org] *On >>>>>> Behalf Of *Andrea Giammarchi >>>>>> *Sent:* Thursday, October 22, 2015 10:47 AM >>>>>> *To:* Yongxu Ren <renyon...@gmail.com> >>>>>> *Cc:* es-discuss mailing list <es-discuss@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 <renyon...@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 < >>>>>> jbo...@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@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@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@mozilla.org >>>>> https://mail.mozilla.org/listinfo/es-discuss >>>>> >>>>> >>>> >>> >> >
_______________________________________________ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss