Bill writes:
Iâve been away from the keyboard for a few months and am slowly getting back to work and I thought Iâd celebrate by taking a closer look at the new annotation support that Grubba has put together. My plan is to have a âchapterâ of material for a future edition of the pike manual.
Welcome back, and great!
What follows are a few comments as well some questions (possibly disguising a feature request or two).
- Iâve noticed that annotations(something, 1) returns annotations
associated not only with each identifier, but also with the class containing the identifier. For example:
class a {
@âfooâ;
@âbarâ: void gazonk() {}
}
annotations(a()) returns:
({ (<âbarâ>) })
While annotations(a(), 1) returns:
({ (<âfooâ, âbarâ>) })
That seems strange; don't you mean
annotations(a()->gazonk)
and
annotations(a()->gazonk, 1)
respectively above?
I donât think I would have expected that behavior⦠I think Iâd have been more likely to expect some sort of result that described annotations on the identifier of the present class versus annotations on the same identifier from any inherited class. I was just wondering if there was a particular use case where that might be handy?
The use case that I had in mind (as far as I recall) was using annotations for serialization metadata.
- I added Program.annotations() in order to query the annotations
directly made on a program. Iâm not sure that the additional flag argument works in a reasonable way: if set, Program.annotations(prog) displays the annotations for the entire inherit tree, whereas without the flag, only the annotations defined directly in the present program are displayed. That seems backward to me, but I did it that way to keep the ânatureâ of the behavior similar to annotations(), but it think that should be reversed in order to limit surprise. Thoughts?
That does seem a bit backward.
- Annotations currently must be constant expressions, and that
works well for the builtin annotations, but it prevents annotations that take arguments, which is a pretty common use case in other languages. For example:
@Web.Routing(â/path/to/methodâ, Web.Method.GET): void my_method(object request) { ⦠}
I looked a little more closely and realized that the built-in annotations are all classes. I was wondering what the benefit of that is versus being objects, the benefit/need for the expression to be constant, and whether it would be feasible to allow for âannotations with argumentsâ as described above.
Incorrect. All of the current annotations when used are objects. Eg:
@Pike.Annotations.Implements(AbstractSimpleNode);
A Pike-level class can be marked as creating constant objects using the "annotation"
@constant;
(which sets the PROGRAM_CONSTANT flag in the class).
- I wonder if it would be possible to define a syntax (and possibly
add placeholder functionality) for being able to annotate function arguments.
For example:
void foo(string a, @NotNull: string b) { ⦠}
NotNull seems to me to be a property of the type rather than the argument.
I'm currently in the process of reworking the type checker, which would fix the issue that 0 is accepted everywhere.
I realize there isnât currently a framework in place for asking about the nature of an individual argument, but I can imagine the feature might be useful, is present in other languages that implement metadata and if we thought it were feasible, might be nice to define the syntax now. Any thoughts?
I guess that it is doable, but I'd like a proposed API (and possibly a use case) first.
Apologies for all of the questions, I donât recall all of the discussion over the years about this, and am attempting to map my C#/Java experience with metadata onto pike.
No problem.
/grubba