www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Idea for annotations

reply %u <wfunction hotmail.com> writes:
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
next sibling parent reply KennyTM~ <kennytm gmail.com> writes:
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
next sibling parent Jacob Carlborg <doob me.com> writes:
On 2011-08-01 09:00, KennyTM~ wrote:
 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)) { ... }
That would be awesome.
 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?)
-- /Jacob Carlborg
Aug 01 2011
prev sibling parent Mehrdad <wfunction hotmail.com> writes:
On 8/1/2011 12:00 AM, KennyTM~ wrote:
 On Aug 1, 11 13:42, %u wrote:
 mixin memoize!(function int(int n) { ... });
I believe you mean alias memoize!(<that function>) fib;
Yeah, same difference. :)
 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:
 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?
(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.
 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)
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? :)
Aug 01 2011
prev sibling next sibling parent Peter Alexander <peter.alexander.au gmail.com> writes:
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
prev sibling next sibling parent Jacob Carlborg <doob me.com> writes:
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
prev sibling parent reply bearophile <bearophileHUGS lycos.com> writes:
%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
parent soywiz <soywiz gmail.com> writes:
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