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

Reply via email to