Raise of hands (virtually): How many here use AOP?

C

Chris Smith

You wouldn't restrict your development to some extreme lowest common
denominator, i.e. telnet, would you?

Depends. There are really two things going on here. There are a lot of
very nice features of development environments like Eclipse that do NOT
force me to use them, because they help with the PROCESS of writing
code. On the other hand, mis-uses of AOP try to change the GOAL of
writing code, causing people to accept code that would have been
rejected otherwise.

Put as an analogy: an index is quite helpful in using a book. However,
the index should not be used as an excuse for failing to organize the
book in a logical flow with related information grouped logically
together. Similarly, AOP programming aids should not be used as an
excuse for failing to organize code in such a way that control flow is
indicated in the source.
I guess I'm not following. You acknowledge that
Eclipse IDE with AspectJ enabled is sufficient if you do all your
development in Eclipse, which you do. Yet you still don't want to reap
the benefits of AOP.

I think part of the misunderstanding is that I write "only if" and you
seem to have read that as "if and only if". I don't believe that the
forward direction is true.

Uses of AOP, except in the limited contexts I've mentioned, are wrong on
two levels: a symptom, and a cause. The symptom is that they lead to
certain enumerable maintenance hassles, which can admittedly be
mitigated by tools. The cause, though, is that they abuse the language.
That abuse of the language doesn't just cause the immediately apparent
maintenance hassles. I tried to explain that in the earlier article,
but perhaps I failed to be clear.

Let's say I throw an exception in some code, and Eclipse pops up a
little icon in the margin informing me that there's some AOP advice that
applies to this code. I click on the icon, and discover that the
exception I am throwing is going to be emailed to the development team
with its full stack trace in an automated bug report. I don't want that
to happen, so I have to go modify the pointcut and avoid it. This is
the "ideal" situation, in which I had all the tools to tell me exactly
what was going on, and they did their job. Yet AOP was still extremely
far from harmless. Rather, it did the following:

1. Something that should have taken 15 seconds has now taken 100 times
as long.

2. Some single unit of code (the pointcut) is now accumulating a list of
places where non-logged exceptions are thrown. This is not useful
information, and its maintenance complicates management of the project.

3. The logging code therefore becomes very unstable... as unstable as
the most unstable part of the project to which it applies.

4. I become reluctant to throw exceptions in places where they might be
a good idea, because I don't want to deal with accidentally tripping
someone's checkpoint again.

We haven't just lost encapsulation; we've invented poor abstractions,
and then enforced them on everyone. Or, as the article said that I
originally posted, we have switched to a new language that sort of like
Java, but not really. In this new language, which is used only in this
project, throwing an exception means two different things: control flow,
and logging. As an experienced Java developer, I feel confident writing
Java to work in someone's project... but I certainly don't feel
comfortable writing in this pseudo-Java. If I don't read through and
understand all the AOP stuff before writing ANY code for the project, I
am reduced to the level of a programming novice who determines if code
is correct by compiling it... except I look for little AOP icons in the
margins of Eclipse instead.

(I keep using the exceptions example because I see it done a lot, and
it's horrid. Matching patterns of method names -- as in, add this code
every time I call a method starting with "test" -- is even worse, but I
think most people recognize the silliness of this and avoid it... most
of the time. Occasionally, though, I'm wrong in that last bit.)
Lets say you did, code
a cross-cutting concern into, say, 35 different classes pretty much all
the same code woven into those classes where appropriate. [...] And
another developer comes in and has to code a new requirement into the
cross-cutting concern.
[...]

Do you feel that the above error prone process is the lesser of the
evils here?

No, I feel that it's a straw man that is ridiculous to even consider.
It would be hard to come up with a programming technique that's NOT
better than what your hypothetical programmer is doing.

Let's get this straight. So he's got 35 copies of exactly the same
code, and yet he hasn't even bothered to factor that code out into a
utility method somewhere? What's wrong with him?!? I've certainly put
off work on code cleanliness to meet scheduling deadlines... but 35
copies?!? And he realizes that they are all copies, and he worries
about making sure they all stay in sink, and yet it's never occurred to
this guy that he ought to put this code in a function somewhere? The
solution to this problem is for the hypothetical programmer to leave his
job and enter the lucrative field of real estate management. They seem
to like his sort, there.

I don't mean to say that I never think AOP is useful. Occasionally, the
existing forms of abstraction available in modern programming languages
become awkward for certain problems, and AOP provides a convenient
solution. That said, the advantages are routinely and blatantly
overstated on a regular basis, and a large number of people need to come
back down to Earth and get back to doing their jobs instead of hyping
AOP.
Even meeting all of your requirements it's still bad?

I'm unsure what you mean. I think I've made it continually clear that I
have no problem with AOP attached to things that have no other defined
purpose in the language; in other words, annotations -- which are sorta
defined by having no other defined purpose. It's the overloading of
significant language features that's problematic. Identifier names are
meant to be unique and communicate purpose to human beings, not to
define transaction semantics. Exceptions are used to quickly transfer
control from one bit of code to another; not to invoke logging. I just
can't imagine what could make someone think it's a good idea to be able
to make the behavior of a method change because its name starts with
some magic word... unless it's (a) an overwhelming desire to be on the
bandwagon for the next New Thing, (b) a lack of understanding of code
maintenance issues, or (c) a kind of twisted pleasure in setting land
mines for fellow programmers.
I asked in so many words in a prior post: Why are
these trade-offs not worth the benefits?

The main reason is that they are not necessary to achieve the benefits.
Why do you need to wait for others to know what you know? If the tools
already (seem to) support what you would like them do what's stopping
you from using them? Are you talking about your peers in your
organization? If so, are they using Eclipse as well, can you bring
them up to speed and catch unapproved techniques in peer reviews?

I certainly don't need to wait. However, a form of AOP that relies on
annotations instead of the existing hodgepodge of pointcut types and
patterns would be considerably more elegant in syntax and harder to get
screwed over with than the existing alternatives.

--
www.designacourse.com
The Easiest Way To Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation
 
D

ducnbyu

Chris, once again thanks for taking so much care in articulating your
thoughts on AOP. Remaining comments are in line.
On the other hand, mis-uses of AOP try to change the GOAL of
writing code, causing people to accept code that would have been
rejected otherwise.

Your comments are getting me light years ahead in considering what
might be abuses.
Put as an analogy: an index is quite helpful in using a book. However,
the index should not be used as an excuse for failing to organize the
book in a logical flow with related information grouped logically
together. Similarly, AOP programming aids should not be used as an
excuse for failing to organize code in such a way that control flow is
indicated in the source.

Agreed, as Aspects are part of the source. Other standard Java
techniques should be considered first, but not to the point of bending
over backwards to avoid AOP. Should really ask of AOP (annotions only)
and the clearest standard Java solution devised: "Which is clearer and
easier to maintain (with prejudice towards standard Java)?"
I think part of the misunderstanding is that I write "only if" and you
seem to have read that as "if and only if".
Guilty.

Let's say I throw an exception in some code, and Eclipse pops up a
little icon in the margin informing me that there's some AOP advice that
applies to this code. I click on the icon, and discover that the
exception I am throwing is going to be emailed to the development team
with its full stack trace in an automated bug report. I don't want that
to happen, so I have to go modify the pointcut and avoid it. This is
the "ideal" situation, in which I had all the tools to tell me exactly
what was going on, and they did their job.

OK, since I'm using Eclipse I'm assuming I have access to those tools.
Yet AOP was still extremely
far from harmless. Rather, it did the following:
1. Something that should have taken 15 seconds has now taken 100 times
as long.

Not sure why it would be such a large factor, but since I haven't used
AOP yet I defer to you.
2. Some single unit of code (the pointcut) is now accumulating a list of
places where non-logged exceptions are thrown. This is not useful
information, and its maintenance complicates management of the project.

This is assuming pattern matching right? (If so, ignore this next
question. If not, why can't you just remove or change an annotation?)
3. The logging code therefore becomes very unstable... as unstable as
the most unstable part of the project to which it applies.

I will need to ponder this for a while.
4. I become reluctant to throw exceptions in places where they might be
a good idea, because I don't want to deal with accidentally tripping
someone's checkpoint again.

Isn't that like being reluctant to modify a super class? If it's gotta
be done it's gotta be done.
We haven't just lost encapsulation; we've invented poor abstractions,
and then enforced them on everyone. Or, as the article said that I
originally posted, we have switched to a new language that sort of like
Java, but not really.

I think it is a smart thing to expand Java. If Java does not support
AOP and it does prove to be a major benefit in the long run then Java
will "die" (in the same sense that COBOL "died") and we all have to go
out and learn CLOS or something because a lot of people start writing
in it. If AOP proves to be more trouble than it's worth, then only the
AOP features of Java will die. It's the old railroad problem, they
thought of themselves as a railroad company rather than a
transportation company. Had they considered their real role then, when
they were at their financial peak, they could have expanded business
into trucking and air when those transportation "techniques" were
fledglings. Instead other companies sprang up and took too much of
their business away... once they lost that business they didn't have
the finances to expand. Instead they took a "that'll never happen"
stance.

I'm not saying you are taking that stance. You have said in a prior
post that you are "waiting for the moment..." and you certainly are
poised to go with a movement if one happens. I'm just saying AOP
intriguing-ly adds another dimension to programming and has to go
through the necessary growing pains to mature if it can. You may be
right it may just be current fashion like client-server was in the
early 90's until it was discovered how much workstation maintenance was
required on the fat clients. Companies that stuck with their mainframe
products died in the early 90's. Company's with client-server products
remembered that and in the late 90's saw the tides and migrated to the
web and survived. They suffered the growing pains to do it.
In this new language, which is used only in this
project.

Are you saying that each implementation of AOP is essentially defining
a new language that is project specific?
throwing an exception means two different things: control flow,
and logging. As an experienced Java developer, I feel confident writing
Java to work in someone's project... but I certainly don't feel
comfortable writing in this pseudo-Java. If I don't read through and
understand all the AOP stuff before writing ANY code for the project.

Doesn't that depend on how large your change is? If you are making a
minor change to the extent that you only need to understand the method
you are changing then you only need to understand the Aspects that are
involved in the method. Assuming you have acces to tools, which are
currently available, to point those out. If you are making a major
change to the extent that you have to understand the entire system then
you would potentially have to read much less code if AOP was, albeit,
*properly* implemented.
I
am reduced to the level of a programming novice who determines if code
is correct by compiling it... except I look for little AOP icons in the
margins of Eclipse instead.

I don't agree that this a novice-only technique. Sure, novices depend
on it for different reasons. I like to type fast and let the computer
worry about spelling. And I like when I click on a variable the IDE
color codes the same variable where it is also used. In the same way
I'm not adverse to letting the IDE point me to Aspects that will be
triggered.
(I keep using the exceptions example because I see it done a lot, and
it's horrid. Matching patterns of method names -- as in, add this code
every time I call a method starting with "test" -- is even worse, but I
think most people recognize the silliness of this and avoid it... most
of the time. Occasionally, though, I'm wrong in that last bit.)

Through this discussion I'm starting to see at least one problem with
pattern matching: It would cause me to consider naming objects and
methods such that Apsect patterns are simpler rather than naming them
for what they represent. Though another side of me wonders if they are
associated with the same aspects perhaps they should have similar
names... need to continue to ponder that.
Lets say you did, code
a cross-cutting concern into, say, 35 different classes pretty much all
the same code woven into those classes where appropriate. [...] And
another developer comes in and has to code a new requirement into the
cross-cutting concern.

[...]


Do you feel that the above error prone process is the lesser of the
evils here?

No, I feel that it's a straw man that is ridiculous to even consider.
It would be hard to come up with a programming technique that's NOT
better than what your hypothetical programmer is doing.
Let's get this straight. So he's got 35 copies of exactly the same
code, and yet he hasn't even bothered to factor that code out into a
utility method somewhere? What's wrong with him?!? I've certainly put
off work on code cleanliness to meet scheduling deadlines... but 35
copies?!? And he realizes that they are all copies, and he worries
about making sure they all stay in sink, and yet it's never occurred to
this guy that he ought to put this code in a function somewhere? The
solution to this problem is for the hypothetical programmer to leave his
job and enter the lucrative field of real estate management. They seem
to like his sort, there.

It's not 35 copies of the same code. It's 35 classes doing unique
functions that all also need to do one (or more) other same thing(s).
Yes, it is all factored to the max instantiating class variables
invoking methods as factoring allows. Inheritance is taken by another
concept and Interfaces can't be used because member properties are
required. So you have associations between classes to implement the
cross-cutting concern in standard Java. AOP can eliminate the
complexity of passing context around through method calls.
I don't mean to say that I never think AOP is useful. Occasionally, the
existing forms of abstraction available in modern programming languages
become awkward for certain problems, and AOP provides a convenient
solution.

Agreed, that's what I was trying to articulate in the 35 class example.
That said, the advantages are routinely and blatantly
overstated on a regular basis, and a large number of people need to come
back down to Earth and get back to doing their jobs instead of hyping
AOP.

Yeah, who doesn't brag about their children. Or their new truck.
I'm unsure what you mean. I think I've made it continually clear that I
have no problem with AOP attached to things that have no other defined
purpose in the language; in other words, annotations -- which are sorta
defined by having no other defined purpose.

Yeah that's where communication breaks down here. You say it's ok
under the "annotations" condition, you have tools available to use
annotations, and then you say it's bad programming, so I don't know for
sure whether you were saying pattern matching techniques are bad or all
AOP techniques are still bad even when using annotations. As I write
this still I wonder if you are going to write something in response
that I will read one way and in another spot read the other way. Not
saying it's you.
It's the overloading of
significant language features that's problematic. Identifier names are
meant to be unique and communicate purpose to human beings, not to
define transaction semantics.

Yeah I agree and commented on that above.
Exceptions are used to quickly transfer
control from one bit of code to another; not to invoke logging. I just
can't imagine what could make someone think it's a good idea to be able
to make the behavior of a method change because its name starts with
some magic word...

(With all comments regarding concerns of pattern matching and benefits
of annotions in mind.) You are not changing the behavior of the method.
You are changing the behavior of the application. Except now the
method is stripped of everything except it's core function. You are
adding a dimension to the source code. Of course it all gets compiled
down to linear VM code in the end.
unless it's (a) an overwhelming desire to be on the
bandwagon for the next New Thing, (b) a lack of understanding of code
maintenance issues, or (c) a kind of twisted pleasure in setting land
mines for fellow programmers.

or (d) restricting code in Class methods to their core function and
code in Aspects to their core function improving readability.
or (e) reducing the amount of code
I asked in so many words in a prior post: Why are
these trade-offs not worth the benefits?

The main reason is that they are not necessary to achieve the benefits.

Neither are Interfaces, nor is Inheritance, nor loops. I mean shoot
you have to go all the way over into another source file (if you can
find it) to find out what is inherited. Better to just put all code
in-line then surely everyone will be able to read it. Oh wait. The
IDE makes navigation easy and organizes source into projects. I know.
That's extreme. I guess it comes down to perception of the value of
the benefits.
I certainly don't need to wait. However, a form of AOP that relies on
annotations instead of the existing hodgepodge of pointcut types and
patterns would be considerably more elegant in syntax and harder to get
screwed over with than the existing alternatives.

This is another one of those communication break downs. You say you
don't need to wait, but then you say AOP that relies on annotations
*would be* more elegant. Don't you mean *is* more elegant? It's here
today from what I read. Yes, pattern matching is still there, but as a
developer or organization you don't have to use features that rub the
wrong way. You establish guidelines and make sure everyone follows or
has a good case for pushing the boundaries.
 
C

Chris Smith

I'll make this short. I'm afraid we're just not communicating in a few
places, so I'll address what seem to still be substantive points of
discussion.

This is assuming pattern matching right? (If so, ignore this next
question. If not, why can't you just remove or change an annotation?)

Yes. Everything I'm saying about problems with AOP is assuming the form
of AOP that defines pointcuts based on things like method calls or field
accesses or exceptions. Very little of it applies to pointcuts defined
with annotations.
Are you saying that each implementation of AOP is essentially defining
a new language that is project specific?

Yes, insofar as it overloads existing language constructs with new
meaning.
Doesn't that depend on how large your change is? If you are making a
minor change to the extent that you only need to understand the method
you are changing then you only need to understand the Aspects that are
involved in the method. Assuming you have acces to tools, which are
currently available, to point those out.

I think you're underestimating the impact of working in a language or
environment where surprising things happen. Richard Feynman famously
talked about the need for long periods of utterly predictable time to do
any important mental work. A *very* good book by Tom DeMarco and
Timothy Lister called "Peopleware" talks about the effect of phones on
software developers.

I think these concepts can be extended to the programming environment
itself, as well. It may only take a small amount of time to deal with
an issue, but if it's unexpected and interrupts what a programmer was
doing, it's costly. I'd draw an analogy to a missed CPU branch
prediction, except considerably worse because the "pipeline" of the
human brain is large and complicated. Even worse, even if I never run
into an unexpected AOP phenomenon, I just feel less comfortable working
in a language where using the whole range of language constructs means
some piece of unexpected behavior may be inserted into my code at any
time. Yes, I'll find out right away; but I shouldn't have to find out.
It's not 35 copies of the same code. It's 35 classes doing unique
functions that all also need to do one (or more) other same thing(s).

Right, so each of them contains one line of code that calls some
function. I don't see the problem. All the stuff about keeping the
copies in synch, or telling the difference between this code and the
core functionality, etc. seem rather exaggerated.
Yeah that's where communication breaks down here. You say it's ok
under the "annotations" condition, you have tools available to use
annotations, and then you say it's bad programming

No, sorry. I mean that overloading *existing* language features via AOP
is bad programming. I didn't mean for that to apply to AOP that doesn't
overload language features.
This is another one of those communication break downs. You say you
don't need to wait, but then you say AOP that relies on annotations
*would be* more elegant. Don't you mean *is* more elegant? It's here
today from what I read. Yes, pattern matching is still there, but as a
developer or organization you don't have to use features that rub the
wrong way. You establish guidelines and make sure everyone follows or
has a good case for pushing the boundaries.

I mean that AspectJ, to pick an example, would be considerably simpler
if it excluded the ability to use gazillions of types of information to
specify exactly where advice is weaved into code. If you get rid of all
that stuff about type patterns, method patterns, etc. and just define a
simple language that lets the programmer attach code to class, method,
or field accesses with a certain annotation, then you end up with a far
simpler, more elegant language.

Sure, AspectJ in its current form works (at least v5 and up), but
complexity isn't free.

--
www.designacourse.com
The Easiest Way To Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation
 
D

ducnbyu

I'll make this short.

Thanks for your thoughts. I'll try the same.
Yes, insofar as it overloads existing language constructs with new
meaning.

I kind of understand what you are meaning (talking about pattern
matching) since the names of some class and methods are specific to a
project. Some Aspects may be specific to a project with behavior
attached by names referenced in the pointcuts. So behavior is specific
to the project on those bases. Not sure I would call it a project
specific language overloading or not though, since the same compiler
can resolve all projects. That and ultimate behavior is always
specific to and pretty much the definition of a project with or without
AOP. Otherwise it wouldn't be a project because the problem had
already been solved. From those two perspectives I wouldn't attribute
such a label to AOP including pattern matching features.
I think you're underestimating the impact of working in a language or
environment where surprising things happen.

Maybe I do work in such an environment. Maybe I'm so used to it...
It's not surprising. I don't know, maybe I'm speaking out of turn
since I am still in research mode, so going out on a limb... I can get
my head around it all pattern matching or not. I don't see what the
big surprises are as long as I know Aspects are in the picture and
especially if the IDE leads me right to them.
I think these concepts can be extended to the programming environment
itself, as well. It may only take a small amount of time to deal with
an issue, but if it's unexpected and interrupts what a programmer was
doing, it's costly.

I just don't see it any worse than a method call that I have to click
on to get the definition to open up in another tab.
Right, so each of them contains one line of code that calls some
function. I don't see the problem. All the stuff about keeping the
copies in synch, or telling the difference between this code and the
core functionality, etc. seem rather exaggerated.

How is it just one call? You're having to carry additional context
around where ever you go (what ever you call).
No, sorry. I mean that overloading *existing* language features via AOP
is bad programming. I didn't mean for that to apply to AOP that doesn't
overload language features.

Ok, I'll stop "reading in" even where it seems...
I mean that AspectJ, to pick an example, would be considerably simpler
if it excluded the ability to use gazillions of types of information to
specify exactly where advice is weaved into code. If you get rid of all
that stuff about type patterns, method patterns, etc. and just define a
simple language that lets the programmer attach code to class, method,
or field accesses with a certain annotation, then you end up with a far
simpler, more elegant language.

That's where we disagree. IMHO it already is simpler because you can
choose to solve a problem with whatever constraints you want to place
on your source.
 
T

Thomas Hawtin

Chris said:
Yes. Everything I'm saying about problems with AOP is assuming the form
of AOP that defines pointcuts based on things like method calls or field
accesses or exceptions. Very little of it applies to pointcuts defined
with annotations

I kind of take the opposite point of view, in some case.

If I have a method that starts with is/get it's a getter, set it's a
setter, new/create it's creation/factory method, test it's a test, etc.
No need for a get method to be annotated as a @Get, or a test method
annotated as @Test.

The bit of AOP I really take objection to is modifying of classes. Doing
something similar, generating smart proxies seems a more comfortable way
of going about things.

Tom Hawtin
 
B

Bent C Dalager

I kind of understand what you are meaning (talking about pattern
matching) since the names of some class and methods are specific to a
project. Some Aspects may be specific to a project with behavior
attached by names referenced in the pointcuts. So behavior is specific
to the project on those bases. Not sure I would call it a project
specific language overloading or not though, since the same compiler
can resolve all projects.

That depends what you mean exactly. The problem is that this compiler
you refer to is not a Java compiler - it's an AOP Java compiler.
Presumably, the AOP part does some sort of preprocessing step to
modify your source code and then hands the result over to a proper
Java compiler. The end result is that what looks like well-known Java
code with known semantics ends up doing something completely different
that is wholly surprising for anyone expecting behaviour that conforms
to the JLS.

I could make a compiler that took the following source code line:

900 PRINT "Hello world"

and substituted it with

System.out.println("Hello world");

then ran it through a Java compiler.

Even though the end result would be what I wanted, and it had gone
through a Java compiler, that doesn't mean the original source code is
Java. It's in a different language altogether.

This is essentially what happens when you use AOP to change what the
"throw" keyword does (as an example). It may look like Java, but
"throw" no longer behaves the way in which Java "throw"s are supposed
to and so it is not actually Java.
That and ultimate behavior is always
specific to and pretty much the definition of a project with or without
AOP. Otherwise it wouldn't be a project because the problem had
already been solved.

This only seems relevant for projects that aim to create new
programming languages. Most projects do not aim to change the language
they are using(*), but rather employ it to solve some problem or
other.

* - possibly excepting overly creative use of #define in C and C++.
From those two perspectives I wouldn't attribute
such a label to AOP including pattern matching features.

The lithmus test is really quite simple: if you can take your source
code as it is and run it through a JLS-compliant Java compiler and the
end result behaves as intended, then your source files are written in
Java.

If you need to add a preprocessing step to massage your source files
before passing them to javac, then it is not.

Cheers
Bent D
 
B

Bent C Dalager

I kind of take the opposite point of view, in some case.

If I have a method that starts with is/get it's a getter,

Such as issueWarning() ?
set it's a setter,

settleDebts() ?
new/create it's creation/factory method

newscast() ?
, test it's a test, etc.

testifyOrPleadTheFifth() ?
No need for a get method to be annotated as a @Get, or a test method
annotated as @Test.

If you do project-wide pattern matching, it really is too easy to slip
up and accidentally create a symbol that just happens to match one of
your patterns.

Not to mention accidentally causing a symbol to be missed because you
mistyped its name. I have done this a few times with JUnit.

Cheers
Bent D
 
D

ducnbyu

Brent said:
That depends what you mean exactly. The problem is that this compiler
you refer to is not a Java compiler - it's an AOP Java compiler.

I will agree that AOP adds vocabulary to the Java language. Note I did
not say changes the language here. That is because you could send pure
Java through the preprocessor and it will produce the expected pure
java result. What I don't agree with (stated differently and perhaps
more accurately reflecting what I think Chris said) each project that
uses AOP is defining it's own language... kind of like a dialect I
guess he might call it. I'm of the opinion that Java with AOP used in
one project is the same as Java with AOP used in another project. Both
projects speak the same perfect Java with AOP. Not saying either of
them speaks perfect Java. They both speak the same dialect of Java
that could be called AOP Java to use your vernacular.
Presumably, the AOP part does some sort of preprocessing step to
modify your source code and then hands the result over to a proper
Java compiler. The end result is that what looks like well-known Java
code with known semantics ends up doing something completely different
that is wholly surprising for anyone expecting behaviour that conforms
to the JLS.

I disagree. From the start, the orginal does not look like
"well-known" Java. It looks like AOP Java and should be treated as
such. You will see Aspects in there and that should be a clue. Or the
IDE will indicate that an aspect has a pointcut/advice to the method
and that should be another clue. Otherwise, what are people expecting
Java semantics doing looking at AOP java? How are they getting the
assigment? Did the original programmers sneak AOP in without telling
anyone and they're all gone now? (Bad programmers, bad) Does
"management" hire people without the proper skill set to work on the
code? (Bad management, bad.) Assuming some level of management was
involved in the decision to go AOP and or at least some of the original
programmers are still around I don't see the problem.
I could make a compiler that took the following source code line:
900 PRINT "Hello world"
and substituted it with
System.out.println("Hello world");

then ran it through a Java compiler.

Even though the end result would be what I wanted, and it had gone
through a Java compiler, that doesn't mean the original source code is
Java. It's in a different language altogether.

That's Basic. And the project is the Hello World project.

You could also write

900 PRINT "Goodbye World"
which would presumably generate
System.out.println("Goodbye world");

That's also Basic. And the project is the Goodbye World project

Both projects are speaking perfect Basic (as defined by the
precompiler). Since both projects produce the expected result by the
same (pre)compiler they are using the same language. And they are not
speaking separate dialects from each other (B=A, C=A, therefore B=C).
If your are going to write in Basic you shouldn't even be worried about
the generated Java code. You shouldn't try to run the Basic code
through the Java compiler without the precompiler. In the same way,
you should not look at AOP Java with pure Java blinders on, the
original source code will not compile without having gone through the
precompiler first.
This is essentially what happens when you use AOP to change what the
"throw" keyword does (as an example). It may look like Java, but
"throw" no longer behaves the way in which Java "throw"s are supposed
to and so it is not actually Java.

And anyone given the assignment to write this code or modify it
presumably has the skill set to know the difference.
This only seems relevant for projects that aim to create new
programming languages. Most projects do not aim to change the language
they are using(*), but rather employ it to solve some problem or
other.

I agree. If you mean a project that happens to be using AOP is not
changing the language it is written in. AOP may have added to it, but
the project is innocent.

* - possibly excepting overly creative use of #define in C and C++.

That reminds me. BTW AOP seems to me is a level of abstraction beyond
#IFDEF...#DEFINE. Instead of the target method specifying which
Include files are going to be placed where. The Aspect determines
which methods it is going to target and where. It's not that much more
complicated.
The lithmus test is really quite simple: if you can take your source
code as it is and run it through a JLS-compliant Java compiler and the
end result behaves as intended, then your source files are written in
Java.

If you need to add a preprocessing step to massage your source files
before passing them to javac, then it is not.

Kind of. Would add that if you can pass any pure Java source through
the precompiler/compiler and it ultimately behaves as pure java does,
then any program that you successfully pass through the
precompiler/compiler is at most extended Java.
 
D

ducnbyu

Thomas said:
The bit of AOP I really take objection to is modifying of classes.

I know this is very subjective. I'm of the opinion that neither the
classes nor the methods of the classes are modified by AOP. Their core
function is preserved.

There's a N/C programmer and a safety engineer. The N/C programmer
arrives to code away in the machine shop. Safety engineer policing the
entrance puts a hard hat on the programmer who codes away. Doesn't
that allow the programmer to have a more focused skill set? He doesn't
have to also be a mini safety engineer. He's still a programmer, the
company hired him to be a programmer, from the company's point of view
he has not been modified.

Now consider that the same safety engineer sweeps through all the
machine shop buildings faster than a speeding bullet or 3.0GHz doing
all sorts of safety things safety engineers do. So the company is
happy everyone is safe and they only had to hire and train (and retrain
and pay) one safety guy and the programmer has no paid downtime taking
silly safety classes. The programmer is happy because he doesn't have
to absorb all the safety codes that might or might not apply to him and
his thoughts are not interrupted with silly safety concerns. The
safety engineer is happy because he did a good deed.

Don't tell me he the programmer changed into a HardHatProgrammer {}
because he didn't. Every day the programmer walks in never thinks
about hard hats because the safety engineer is always there to put one
on his head. (His hair might have been changed to HardHatHair {} but
that's another story. I.e. he wasn't hired for his hair.)
 
B

Bent C Dalager

(snipped the above since the following basically sums it up)

Kind of. Would add that if you can pass any pure Java source through
the precompiler/compiler and it ultimately behaves as pure java does,
then any program that you successfully pass through the
precompiler/compiler is at most extended Java.

I agree with this, but my position is that "extended Java" isn't
actually "Java" :)

Cheers
Bent D
 
T

Timo Stamm

Bent said:
Such as issueWarning() ?


settleDebts() ?


newscast() ?


testifyOrPleadTheFifth() ?

All of your examples could be properly recognized if you test if the
letter following the suffix (is|set|get) is uppercase. But...

If you do project-wide pattern matching, it really is too easy to slip
up and accidentally create a symbol that just happens to match one of
your patterns.

Not to mention accidentally causing a symbol to be missed because you
mistyped its name. I have done this a few times with JUnit.

.... I agree. An explicit declaration with an annotation is much more
reliable.


Timo
 
B

Bent C Dalager

All of your examples could be properly recognized if you test if the
letter following the suffix (is|set|get) is uppercase. But...

I know. I was too lazy to think up more relevant examples, but I will
give it a go. getLost() is probably not a getter for example and
newAndBetterAlgorithm() may not be a factory method :)

Cheers
Bent D
 
T

Thomas Hawtin

Bent said:
Such as issueWarning() ?


settleDebts() ?


newscast() ?


testifyOrPleadTheFifth() ?

Very clever. Starts with [when taken a word at a time, as java.beans
does] is/get.
If you do project-wide pattern matching, it really is too easy to slip
up and accidentally create a symbol that just happens to match one of
your patterns.

Needn't be project wide on its own. The test prefix is only relevant in
Test classes (in test source).

Assuming the language is not mutated, false positives are unlikely to
matter anyway. I'm not going to call getAndImprovedMethod, but it will
stick out.
Not to mention accidentally causing a symbol to be missed because you
mistyped its name. I have done this a few times with JUnit.

That's impresive.

Tom Hawtin
 
T

Thomas Hawtin

I know this is very subjective. I'm of the opinion that neither the
classes nor the methods of the classes are modified by AOP. Their core
function is preserved.

The language is mutated. Somewhere between caller and callee (possibly
the same) something happens to valid Java code that is incorrect as far
as the JLS is concerned.

Tom Hawtin
 
O

Oliver Wong

Maybe I do work in such an environment. Maybe I'm so used to it...
It's not surprising. I don't know, maybe I'm speaking out of turn
since I am still in research mode, so going out on a limb... I can get
my head around it all pattern matching or not. I don't see what the
big surprises are as long as I know Aspects are in the picture and
especially if the IDE leads me right to them.

Note though that the AspectJ language and the IDEs that support it are
relatively young and may contain bugs. In the Eclipse AspectJ plugin, for
example, you need to specifically mark a project as being an "AspectJ"
project instead of a Java project, so that the "AspectJ builder" kicks in,
and your annotations take effect. However, the plugin will happily let you
apply aspects to pointcuts that lie OUTSIDE of your AspectJ project. So when
you navigate to your regular plain vanilla Java project, you'll see a little
icon saying some aspect is taking place here, but when you actually execute
the program, the aspect won't actually kick in, and you'll have to spend
some time thinking about why.

I've submitted this as a "bug" to the AspectJ plugin team, but they've
marked it as "WILL-NOT-FIX", essentially saying that this is a limitation of
the Eclipse platform itself, rather than their plugin.

- Oliver
 
C

Chris Smith

Sorry for the delay. I'm having to think quite a bit to write on this
thread, and the last few days haven't been good ones for thinking.

I kind of understand what you are meaning (talking about pattern
matching) since the names of some class and methods are specific to a
project.

I'm talking about anywhere that an aspect applies without some
indication in the code with the sole purpose of causing that aspect to
apply there. This includes pattern matching on method names, and also
aspects on throwing or catching exceptions, and aspects on uses of
classes within some package, and so on.
Not sure I would call it a project
specific language overloading or not though, since the same compiler
can resolve all projects.

From the point of view of Java, the language is being modified in
different ways for each project. From the point of view of AspectJ, of
course, it's all one language. However, in order to incorporate all of
this into one language, AspectJ needs to be a considerably less
predictable language than Java. We return to the same issues as C++,
with that famous unanswerable question: what does "a = b + c"
actually mean... except this time, you don't need to search the entire
project for operators and implicit type conversions; you have to search
for aspects.

It's essentially semantically empty to dispute whether AspectJ is a
language, or a system for defining languages metalinguistically. Any
sufficiently powerful language supports both interpretations. The point
is that it's possible to consistently see it as the latter, and that
when you do the results are very scary.
Maybe I do work in such an environment. Maybe I'm so used to it...
It's not surprising. I don't know, maybe I'm speaking out of turn
since I am still in research mode, so going out on a limb... I can get
my head around it all pattern matching or not. I don't see what the
big surprises are as long as I know Aspects are in the picture and
especially if the IDE leads me right to them.

The concept that programmers have limited brains. Just because you are
capable of getting your head around something doesn't mean that it
should be counted as having no cost. The cognitive effort you spend
understanding your language leaves less to understand the quirks or
difficult points of the problem domain or of the algorithms you use to
solve problems. My argument here is merely that one should recognize
that... and that in the context of AOP, recognizing it means that
certain claims about the natural way AOP solves problems should be
rejected.
I just don't see it any worse than a method call that I have to click
on to get the definition to open up in another tab.

The difference is that one is explicit while the other is implicit. If
you write that method call in the first place, then you intended to
introduce that concept into the code. In the case of a method, you are
given the ability to name the abstraction you are using, in such a way
that a high percentage of the time, you don't need to open the method
declaration to see what it does (assuming good code quality). The block
of functionality is encapsulated and abstracted, given a name to express
what is happening, and referred to by that name. None of these things
are true for advice in AOP, unless they are attached to some explicit
and nameable language feature themselves.
How is it just one call? You're having to carry additional context
around where ever you go (what ever you call).

I don't understand what you mean by all this "context" stuff. Can you
provide an example?
That's where we disagree. IMHO it already is simpler because you can
choose to solve a problem with whatever constraints you want to place
on your source.

Which means that you want to use AOP without annotations, and everything
I've said to this point applies.

--
www.designacourse.com
The Easiest Way To Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,774
Messages
2,569,599
Members
45,171
Latest member
VinayKumar Nevatia__
Top