digitalmars.D - Idea for annotations
- %u (19/19) Jul 31 2011 An idea for a potential use of annotations:
- KennyTM~ (49/68) Aug 01 2011 I believe you mean
- Jacob Carlborg (4/83) Aug 01 2011 --
- Mehrdad (29/55) Aug 01 2011 Uh-oh... Houston, I think we have a problem. :\ How would you go about
- Peter Alexander (3/5) Aug 01 2011 What problem does this solve? Is it just syntax sugar? If so, is it
- Jacob Carlborg (5/24) Aug 01 2011 I have been thinking that exact same thing. I would love to see that in
- bearophile (5/6) Aug 01 2011 In my mind the main purpose of user-defined annotations is to allow the ...
- soywiz (20/20) Aug 13 2011 I really like the idea of annotations to use in traits (compile-time-pse...
An idea for a potential use of annotations: How about being able to annotate _anything_ with a template? It would be the equivalent of Python's annotations: the template's first parameter would be an alias to the thing being annotated, and its return value would be the code generated for that element. Of course, if there's no transformation being done, then it should simply "return" the alias itself. This would allow you to say something like: auto memoize(alias Fn, T...)(T args) { /* memoize code here */ } memoize int fib(int n) { ... } which would be somewhat (but not completely) "equivalent" to mixin memoize!(function int(int n) { ... }); And more trivial things like property would simply be template property(alias A) { alias A property; } with their sole effect being extra information found with reflection. Implementing this would obviously be difficult as I would assume, but does it sound like a reasonable idea?
Jul 31 2011
On Aug 1, 11 13:42, %u wrote:An idea for a potential use of annotations: How about being able to annotate _anything_ with a template? It would be the equivalent of Python's annotations: the template's first parameter would be an alias to the thing being annotated, and its return value would be the code generated for that element. Of course, if there's no transformation being done, then it should simply "return" the alias itself.+1.This would allow you to say something like: auto memoize(alias Fn, T...)(T args) { /* memoize code here */ } memoize int fib(int n) { ... } which would be somewhat (but not completely) "equivalent" to mixin memoize!(function int(int n) { ... });I believe you mean alias memoize!(<that function>) fib; your property below won't work as a mixin. Also, self-reference should be handled: memoize ulong fib(ulong n) { return n < 2 ? 1 : fib(n - 2) + fib(n - 1); // ^^^ recursion^^^ } exportName("F/List") class F_List { int content; F_List next; // ^^^^^^ self-reference } This works in Python trivially because functions and classes are looked-up by name in runtime. This isn't true in D, at least if it's a simple alias-ing.And more trivial things like property would simply be template property(alias A) { alias A property; } with their sole effect being extra information found with reflection.I'd prefer to make it more explicit, e.g. use a __traits to include that extra information: alias __traits(setAnnotation, X, "foo.prop", 1234) Y; // Y is a copy or reference of X but with the extra property enum prop = __traits(getAnnotationy, Y, "foo.prop"); // returns 1234, compile-time error if 'foo.prop' does not exist. enum prop = __traits(getAnnotationy, Y, "foo.bar", false); // same as above but with a default value. static if (__traits(hasAnnotation, Y, "foo.prop")) alias __traits(removeAnnotation, Y, "foo.prop") Z; So, e.g. one could write template serializable(alias F) if (is(f == struct) || ...) { alias __traits(setAnnotation, F, "mymodule.serializable", true) serializable; } ... serializable struct MyObject { int x; ... } and the serializer can check with auto serialize(F)(F x) if (__traits(getAnnotation, F, "mymodule.serializable", false)) { ... }Implementing this would obviously be difficult as I would assume, but does it sound like a reasonable idea?Would you mind to write a DIP? (http://www.prowiki.org/wiki4d/wiki.cgi?LanguageDevel/DIPs) (Speaking of which, what happened to DIP11?)
Aug 01 2011
On 2011-08-01 09:00, KennyTM~ wrote:On Aug 1, 11 13:42, %u wrote:That would be awesome.An idea for a potential use of annotations: How about being able to annotate _anything_ with a template? It would be the equivalent of Python's annotations: the template's first parameter would be an alias to the thing being annotated, and its return value would be the code generated for that element. Of course, if there's no transformation being done, then it should simply "return" the alias itself.+1.This would allow you to say something like: auto memoize(alias Fn, T...)(T args) { /* memoize code here */ } memoize int fib(int n) { ... } which would be somewhat (but not completely) "equivalent" to mixin memoize!(function int(int n) { ... });I believe you mean alias memoize!(<that function>) fib; your property below won't work as a mixin. Also, self-reference should be handled: memoize ulong fib(ulong n) { return n < 2 ? 1 : fib(n - 2) + fib(n - 1); // ^^^ recursion^^^ } exportName("F/List") class F_List { int content; F_List next; // ^^^^^^ self-reference } This works in Python trivially because functions and classes are looked-up by name in runtime. This isn't true in D, at least if it's a simple alias-ing.And more trivial things like property would simply be template property(alias A) { alias A property; } with their sole effect being extra information found with reflection.I'd prefer to make it more explicit, e.g. use a __traits to include that extra information: alias __traits(setAnnotation, X, "foo.prop", 1234) Y; // Y is a copy or reference of X but with the extra property enum prop = __traits(getAnnotationy, Y, "foo.prop"); // returns 1234, compile-time error if 'foo.prop' does not exist. enum prop = __traits(getAnnotationy, Y, "foo.bar", false); // same as above but with a default value. static if (__traits(hasAnnotation, Y, "foo.prop")) alias __traits(removeAnnotation, Y, "foo.prop") Z; So, e.g. one could write template serializable(alias F) if (is(f == struct) || ...) { alias __traits(setAnnotation, F, "mymodule.serializable", true) serializable; } ... serializable struct MyObject { int x; ... } and the serializer can check with auto serialize(F)(F x) if (__traits(getAnnotation, F, "mymodule.serializable", false)) { ... }-- /Jacob CarlborgImplementing this would obviously be difficult as I would assume, but does it sound like a reasonable idea?Would you mind to write a DIP? (http://www.prowiki.org/wiki4d/wiki.cgi?LanguageDevel/DIPs) (Speaking of which, what happened to DIP11?)
Aug 01 2011
On 8/1/2011 12:00 AM, KennyTM~ wrote:On Aug 1, 11 13:42, %u wrote:Yeah, same difference. :)mixin memoize!(function int(int n) { ... });I believe you mean alias memoize!(<that function>) fib;Also, self-reference should be handled: memoize ulong fib(ulong n) { return n < 2 ? 1 : fib(n - 2) + fib(n - 1); // ^^^ recursion^^^ } exportName("F/List") class F_List { int content; F_List next; // ^^^^^^ self-reference }Uh-oh... Houston, I think we have a problem. :\ How would you go about doing this, if the return type is inferred and the annotation template _depends_ on the return type? You could either go on a "best-effort" basis on the compiler, or just assume that internal references (whether direct or indirect) assume un-annotated symbols. But we could have different problems that way too (i.e. security holes: calling the same method from different places producing different results, etc.) so this would need lots of thinking to work correctly. Hopefully we can figure something out, though! :) On 8/1/2011 1:05 AM, Peter Alexander wrote:On 1/08/11 6:42 AM, %u wrote:(1) It's beautiful! (2) It documents the fact that you're doing a transformation on something else (3) It also works pretty well for non-transforming annotations (i.e. those that are there just for metadata) -- you could easy add static assertions inside the template and return the original alias, etc. (4) We're going to have annotations sooner or later (I hope?) so this is just an idea on how to make them work, without introducing a new kind of annotation declaration (since it works with pretty much any old template). (5) To my (VERY) limited knowledge, this could be incredibly useful Aspect-Oriented Programming, if I've understood the concept correctly. I could very well be wrong, though.An idea for a potential use of annotations: How about being able to annotate _anything_ with a template?What problem does this solve? Is it just syntax sugar? If so, is it worth complicating the language even more for this convenience?I wouldn't mind, but I think we might want to get some details straight first. I can't think of an obvious solution to the self-reference issue, so we should probably figure that part out before I actually suggest this for inclusion, right? :)Implementing this would obviously be difficult as I would assume, but does it sound like a reasonable idea?Would you mind to write a DIP? (http://www.prowiki.org/wiki4d/wiki.cgi?LanguageDevel/DIPs)
Aug 01 2011
On 1/08/11 6:42 AM, %u wrote:An idea for a potential use of annotations: How about being able to annotate _anything_ with a template?What problem does this solve? Is it just syntax sugar? If so, is it worth complicating the language even more for this convenience?
Aug 01 2011
On 2011-08-01 07:42, %u wrote:An idea for a potential use of annotations: How about being able to annotate _anything_ with a template? It would be the equivalent of Python's annotations: the template's first parameter would be an alias to the thing being annotated, and its return value would be the code generated for that element. Of course, if there's no transformation being done, then it should simply "return" the alias itself. This would allow you to say something like: auto memoize(alias Fn, T...)(T args) { /* memoize code here */ } memoize int fib(int n) { ... } which would be somewhat (but not completely) "equivalent" to mixin memoize!(function int(int n) { ... }); And more trivial things like property would simply be template property(alias A) { alias A property; } with their sole effect being extra information found with reflection. Implementing this would obviously be difficult as I would assume, but does it sound like a reasonable idea?I have been thinking that exact same thing. I would love to see that in the compiler. -- /Jacob Carlborg
Aug 01 2011
%u:An idea for a potential use of annotations:In my mind the main purpose of user-defined annotations is to allow the user to write small (scoped) extensions to the type system. But Python-style annotations too are useful. Bye, bearophile
Aug 01 2011
I really like the idea of annotations to use in traits (compile-time-pseudoreflection). I have the following code: http://code.google.com/p/pspemu/source/browse/trunk/src/pspemu/hle/kd/rtc/sceRtc.d Each function has associated a NID. And I have to specify the NID outside, repeating the name of the function and creating a method for that. Now I have to do: void initNids() { mixin(registerd!(0xC41C2853, sceRtcGetTickResolution)); } u32 sceRtcGetTickResolution() { //... } And with custom attributes/annotations I could do something like this: struct NID { uint nid; } [NID(0xC41C2853)] u32 sceRtcGetTickResolution() { //... } And then with traits: allMembers + get custom attributos from each member. The function name only appears once, and the NID appears near the implementation.
Aug 13 2011