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