On Tue, Jun 28, 2016 at 8:53 PM, stepharo <[email protected]> wrote:
When I implemented annotation support I was initially thinking the
same - let's create an instance of CoolAnnotationClass when the code
is accepted
and then one can add arbitrary code to his CoolAnnotationClass. I
quickly realized this is a (very) bad idea. Or, to be precise, it is
a bad idea given the
environment. So I'd be very careful..
can you explain your statement?
Let me try, this is tricky for me as I'm not good at explaining :-)
The problems pop out when one need to load the code back. If <coolish:
100> gets parsed and stored in
an annotation container as instance of class Coolish (at compilation
time), this means that you just
introduced a dependency from package of the method which contains the
annotation to the package of
Coolish class. This is not (or rather was not in my case) desirable,
because I need/want to annotate
methods in kernel with annotations for tools. Kernel should not depend
or tools - I believe we agree on
that :-) Note, that this is less of a problem for Java since Java loads
all code lazily, on demand and in a defined
way. I personally found it very nice - though it has some (solvable?)
issues when this lazy loading is used in Smalltalkish
environment such as STX:LIBJAVA)
You can indeed parse them and store them as raw data and convert them
on demand in reflective
API. Then, if the class is not available what to do? Return an instance
of generic Pragma?
Throw an error? When one starts to put an arbitrary code into the
annotation object itself it's either
processing code only access data or it somehow fiddles about the
annotation itself and/or (worse!)
about the method itself. The latter results in difficult to debug
problems as the time the code is executed
is undefined (if you use lazy instantiation to avoid dependency
problem). This may be fine with
most Smalltalkers as there are other pieces of code that execute
randomly in an undefined order and still
very few complain :-) but I did not want to make things even worse.
For the former, mere data-accessing processing code, I don't see much
of a difference by putting it
somwhere else. Follows the same logic as visitor, instead of putting
code to nodes, you put them
to extra visitor class.
Eliot's design elegantly avoid these problems (the same way Java does
:-) by simply having one defined
structure which keeps the logical type of the annotation as data (the
selector of the message send).
It has other problems, but not the one above.
Not sure if it makes sense, but I did my best :-) I'm not saying it's
not solvable and you cannot have
class per annotation type, but it is not **that** easy to get it right.
This is my experience over the years.
HTH, Jan
Stef
Jan
P.S.: As for "which always forced me to hate Java": I found myself a
very enlightening to think carefully about why somebody else
do things differently before I start to hate her/him. Besides,
there's whole lot of things that Java guys got right...