Slashdot Mirror


Aspect-Oriented Programming Considered Harmful

kupci writes "The 'x considered harmful' cry is a little overused, but there is a Forrester report that discusses some of the pro's and con's of Aspect-oriented Programming, and includes some interesting links. It is mainly based on papers from the University of Passau. It's worth it just for Clark's 'COME FROM' article." From the article: "Aspect-oriented programming (AOP) is intended to address common problems that object-oriented programming (OOP) doesn't address well, plus some problems that OOP itself created. However, AOP is a risky solution: It is a very generic mechanism for solving some very specific concerns and has been likened to a kind of "GOTO" statement for OOP. Like GOTO, it can cause more harm than good."

80 of 470 comments (clear)

  1. Of course by ravenspear · · Score: 4, Funny

    The only thing worse would be GOTO + OOP, which of course = C++

    1. Re:Of course by Dwonis · · Score: 2, Informative
      "Goto", on the other hand, is an abomination.

      Quick! Somebody start a petition to demand that Intel drop the JMP instruction from its processors! It's an abomination!

    2. Re:Of course by Anonymous Coward · · Score: 3, Informative

      Last I checked, assembler wasn't a high-level language.

      And? High level languages have immediate targetted transfer of control instructions as well that one cannot easily get rid of. For example, C has break, continue, and the closing squiggles of for and while statements.

      "High" level languages makes programmers not as aware as they should be when they're moving a different value into the instruction pointer, but their programs are still doing precisely that at various points.

      One could argue that C and other compiled languages are low level, like machine code and assembler, and that interpreted things such as Java, C#, and BASIC are high level, but it wouldn't have much bearing on the difficulty of living without unconditional transfer.

    3. Re:Of course by drsquare · · Score: 3, Insightful

      Well, assembly is hardly a language that encourages large, well-organised programming projects, so you've pretty much supported his point.

    4. Re:Of course by Anonymous Coward · · Score: 2, Informative

      Procedures are for doing reusable or at least logically separate things, not for pure code formatting.


      Different branches of an if statement are, by definition, logically separate.


      You don't want proc that calls proc1 and proc2 (because there are no meaningful names for what they are doing) with 10 arguments each.


      Splitting code into procedures provides an opportunity to invent meaningful names and write documentation. More often that not, both can be constructed for otherwise nameless code blocks and improve their readability.


      Functionality unique to your application often can not be and, as long as it's not reusable, there is no reason to waste time thinking about it.


      Apart from the readability argument, there is another benefit from extracting a chunk of code into a procedure: It is natural to attach specifications to procedures, much less common to do it for code blocks. Provided that the specification is easier to understand than its implementation (often, but not always the case), your code becomes easier to comprehend:

      1. The newly introduced procedure can be read, analysed and tested without its original invocation context.
      2. The invocation context can be reasoned about without the need to understand the procedure's implementation (the specification alone will do).

      You can also check the specification by including runtime assertions. Entry and exit points of procedures are a perfect location for such checks.

      Your statement that procedures are for avoiding code duplication is correct. However, there also have other legitimate purposes, which I hope you will recognize when assigned the task of understanding and testing other people's code.

      Concerning your remark about passing a big number of parameters, you should use the opportunity to encapsulate sets of semantically related parameters into a named data structure or class (if using an OO language).

      Are you familiar with the "Design By Contract" concept? If not, I can heartily recommend reading up about it.
    5. Re:Of course by Dachannien · · Score: 3, Insightful

      For example, C has break, continue, and the closing squiggles of for and while statements.

      But all of those statements are used in the context of some logical block, and in some sense "operate" on that block. GOTO is/does not - in C/C++, at least, the only restriction is that you must GOTO a label that's in scope at the time.

      "High" level languages makes programmers not as aware as they should be when they're moving a different value into the instruction pointer,

      High level languages also relieve the programmer of the need of thinking about things like stack frames, heap management, and register usage. A programmer should in a general sense understand how these things work, but there doesn't need to be a constant awareness of those factors, because the compiler is designed to take care of them instead. Programmers working on hardcore optimization might have an interest in those low-level details, but a good optimizing compiler will take care of most of that before the programmer even starts to think about optimization.

      The point in my original comment was that, in assembler, not using JMP reminds one of, "You can't get very far in life without saying 'is'". But the last time I've needed a GOTO was when I was a teenager naively programming in BASIC on my old C-64.

    6. Re:Of course by Anonymous+Brave+Guy · · Score: 2, Interesting
      My original point was that extracting code into procedures should be a heuristic rule, a second-nature of a good programmer, and that branches are an excellent starting point. Polymorphism was introduced in OO languages based on similar premises.

      Indeed, and now inheritance and polymorphism are probably the most over-used programming language features on the planet.

      I'm not saying you're wrong to try to isolate self-contained and independent blocks of code -- you're not -- I'm just saying that it's not always possible, even when you look at "obvious" dividers like branches or loop bodies.

      --
      If you disagree, post your argument. (-1, Overrated) isn't your personal censorship tool for views you don't like.
  2. For those unfamiliar with AOP by ravenspear · · Score: 5, Informative

    Wikipedia linkage

    In computing, the programming paradigm of aspect-oriented programming (AOP) centers on constructs called aspects, which treat concerns of objects, classes, or methods. The aim of AOP is to separate program code related to the main purposes of the application (its core concerns) from code related to secondary purposes (cross-cutting concerns).

    For example, a telecommunications application might have a core concern of routing calls, while code for timing and billing those calls would crosscut the whole object hierarchy. AOP aims to separate the billing concerns from the core concern. It moves code not related to solving the domain problem from the business logic into a separate module. The application code no longer contains pieces of crosscutting concerns scattered across modules; instead, programmers maintain crosscutting concerns in aspects; this makes it easier to maintain both core and crosscutting concerns.

    Any program has principled points (join points) where programmers can identify and modify the program semantics. In AOP, programmers specify join points using a language feature called a pointcut, and specify the behavior to join those points by using advice such as methods or functions. Some variants of AOP allow programmers to extend the types in the system. These features enable aspects to implement behavior for concerns that crosscut the core concern of the application.

    1. Re:For those unfamiliar with AOP by starling · · Score: 5, Insightful

      Any program has principled points (join points) where programmers can identify and modify the program semantics. In AOP, programmers specify join points using a language feature called a pointcut, and specify the behavior to join those points by using advice such as methods or functions. Some variants of AOP allow programmers to extend the types in the system. These features enable aspects to implement behavior for concerns that crosscut the core concern of the application.

      Excuse me, but was that supposed to mean something?

    2. Re:For those unfamiliar with AOP by Keeper · · Score: 2, Insightful

      It's an example, geeze. It is obviously going to be contrived and simple so that someone unfamiliar with the concepts being demonstrated will be able to understand it.

    3. Re:For those unfamiliar with AOP by Keeper · · Score: 4, Insightful

      Let's say you've got objects a, b, and c.

      Objects a and b do something useful (the core of the application)

      Object c (an aspect) wants to perform an operation when something happens in object a (a concern).

      Object c (an asepct) also wants to do different things when something happens in object a and b (crosscutting a concern).

      I look at this as a really complicated event notification system. Comments calling this 'goto for OOP' also seems rather appropriate.

    4. Re:For those unfamiliar with AOP by snorklewacker · · Score: 4, Informative

      If you want something to happen when a certain thing occurs, wouldn't you just call a function or a method when that whatever occurs? Why would you want a goto style statement there?

      The whole idea of AOP is that it's not a GOTO. The "interceptor" (or whatever the jargon of the week is) gets called, does its thing, returns, and your original function runs. This is nothing, lisp does this with defadvice, even emacs lisp can do this (and indeed emacs lisp makes good use of it).

      The neat thing about aspects is that you define them in ONE place. So you tell it "I want function setup_db_connection() and teardown_db_connection() called before every method on any Person, Room, and Resource" (imagine it's a scheduling app). This is just like subclassing, but you don't have to rewrite anything else in the app. In fact, VB programmers who did this sort of hook trickery actually did call it subclassing. If you use a factory pattern, you can do this sort of thing without AOP, but the idea of AOP is to not force you to rewrite everything to use factory patterns -- you just define the "aspect" once, in one place, and it affects everything you tell it to.

      I find AOP is a great way to impose "external" conditions like debugging, extra asserts, and tests. I don't think it's necessarily a great way to structure an entire program, though someone with more experience in the methodology might make it work. As a new methodology, it's rife with shoddy implementations, buzzwords, overuse, poor use, and general immaturity. This is how all methodologies start out however -- even structured programming went overboard when it was first introduced to the mainstream.

      --
      I am no longer wasting my time with slashdot
    5. Re:For those unfamiliar with AOP by mysticgoat · · Score: 3, Insightful

      A better example might be a computerized patient record system (CPRS).

      In a CPRS, it is clear that the core concerns involve information related to the patient's health. However if the institution is going to stay in business, there is a strong secondary concern with regard to diagnosis and treatment costs, billing, and so on. Obviously a healthy hospital has to deal with both of these.

      AOP's promise in this situation is to allow these two mission-critical concerns to be temporarily divorced from each other, so that in a medical emergency the patient will get the treatment he needs in a timely way, without doctors and nurses having to deal with billing and cost issues (Clippy: "It looks like you want to defibrillate the patient. Would you like me to compare the costs of alternate treatment modalities?")

      I've not run into this "AOP" thingee before. My impression is that the problems it is supposed to solve would be better approached by a change in the object hierarchy-- that its use would be sort of like adding epicycles to epicycles when a Copernican revolution is really needed. In the CPRS example, rather than having a PATIENT object with healthcare and billing concerns, it might work better to have TREATMENT and BILLING objects that were separate components of the PATIENT object.

      I'm not convinced that the problems AOP is intended to solve couldn't be finessed by refactoring into a different hierarchy of objects.

  3. $249 by Anonymous Coward · · Score: 4, Interesting

    who is going to shell out that cash for 5 pages?

    1. Re:$249 by Bodrius · · Score: 2, Interesting

      Well, the papers linked in the psot describe the basic problem well enough and they're not charging 250 bucks for the pdfs... not sure what other research results are included in the forrester report, but I doubt there's much you wouldn't find in published academic material if your time is worth less than that... or if you just enjoy reading the research itself.

      --
      Freedom is the freedom to say 2+2=4, everything else follows...
    2. Re:$249 by bryan986 · · Score: 2, Funny

      Our Money-Back Gurantee If you are not completely satsified with your research document for any reason, you can return it for a full refund within three weeks of your online purchase.

      --
      There is no sig
  4. Oh gee by Anonymous Coward · · Score: 5, Interesting

    "Powerful language constructs can be dangerous when misused"

    Thank you for the wonderful advice and welcome to 1971!!

    As for the GOTO comparison, it is disingenuous. The problem with GOTO is not that it is a flow control change, the problem is that it is an [i]unstructured[/i] flow control change. AOP is nothing if not structured, in fact its potential flaw lies in that the structures it represents can be so complicated the programmer can lose track. It's the absolute opposite of GOTO.

    1. Re:Oh gee by Bodrius · · Score: 4, Insightful

      No, the problem with GOTO is that, as a consequence of being an unstructured flow control change, it makes it impossible to trust your reasoning about code because it destroys your ability to scope it.

      To quote: "... it becomes terribly hard to find a meaningful set of coordinates in which to describe the process progress ..."

      I think Dijkstra's point was that any construct that does this is harmful.

      Structured constructs are typically less liable to do this, but only because they are visible and the structure is known.

      AOP does have the ability to inject arbitrary code in your function that can change its semantics and you cannot see this when reading the affected code.

      No matter how structured that change is, its invisibility makes it impossible to fully understand your code from the source code without 'weaving in' all the aspects explicitly. Like GOTO, it destroys your ability to scope your reasoning of the code to the local view.

      As much as I love AOP for a class of problems, this is a very valid concern that needs to be addressed.

      It's certainly not the first language featureset that faces this problem; OOP can deal with its own issues with design by contract, either through documented best practices or by enforcing it in the language. I haven't seen much in AOP there, beyond the absence of problematic examples (which would typically come from real-world use).

      --
      Freedom is the freedom to say 2+2=4, everything else follows...
    2. Re:Oh gee by maraist · · Score: 2, Insightful

      AOP does have the ability to inject arbitrary code in your function that can change its semantics and you cannot see this when reading the affected code.

      Well, except that AOP can only modify code in a structured way.. You can replace a method (no more obscure than method over-loading), you can wrap a method, turning it's body into a nested scope (again similar to a method which calls super). Yes they have before and after methods, but these are mere conviniences to the wrapping of a method.

      My argument is only that while AOP does hurt readibility, it's not MUCH different than holding a reference to a base class, and not realizing that your instance is really a derived class which over-loads your method. If you don't have the proper tools to warn you that a method is over-loaded (IntelliJ's Idea, or I believe eclipse), then you aren't privy to the details of execution. Moreoever, there ARE AOP analysis tools which can warn you that an aspect has wrapped this method. Thus, provided sufficiently intelligent tools v.s. sufficiently obscure inheretance points of basic OOP, the whole readibility point is moot.

      My only concern with AOP is in definine an aspect that is more than you can chew. It may initially solve your problem VERY elegantly, but as the scope of the aspect grows, you can find more and more hacks which dramatically reduce understandibility of the code. And worse, can allow obscure bugs to appear. As I've said in other posts, I prefer aspects which do not directly affect the ability of a code block to do as it conceptually is designed to do. They must have side-effects which are useful to the aspect, and nothing else. Logging/tracing are perfect examples. Problem is to find other examples. Moreoever, these are "aspects" which could easily be implemented by a given VM.

      --
      -Michael
  5. Considered... Harmful? by Mancat · · Score: 3, Funny

    Really, I did read the article, but the headline is kind of discomforting. I mean, how is it harmful? If I were reading this headline while writing aspect-oriented code, should I stop immediately? I wouldn't want to die, you know. If I'm going to die, Slashdot, you need to let me know!

    --
    hello dear sirs my name is jamesh i are india (bihar) can u guide me install red had linux 9?
  6. NEWS FLASH by ZorbaTHut · · Score: 3, Funny

    Useful technique, chemical, or product can be dangerous when misused! With this groundbreaking announcement, aspect-oriented programming joins up with jet planes, oxygen, razor blades, and almonds. Scientists urge all Americans to avoid anything that could, in any way, be harmful to anyone, and the government will begin production of mandatory Full Isolation Spheres (tm) within the week.

    --
    Breaking Into the Industry - A development log about starting a game studio.
  7. Re:Good primer on aspect-oriented programming? by Alien+Being · · Score: 5, Funny
  8. Angry Flower by maxjenius22 · · Score: 3, Funny
    1. Re:Angry Flower by wootest · · Score: 2, Funny

      Or "Angry Flowers Considered Harmful".

  9. A bit sketchy to be called an article by Goosey · · Score: 3, Informative

    The one-paragraph 'article' is just a tagline for a 250 dollar document. Quite dissapointing to read that lead in and find that I won't actually be aquiring any new information on the topic. :\

    --
    --- "End Of Line" - MCP
  10. Executive Whining by idsfa · · Score: 5, Insightful

    There's a new idea in field I am incapable of getting a job in that is gaining in popularity among people I wish cared about my opinions. Buzzword I am dissing is intended to address common problems that buzzword everyone likes doesn't address well, plus something into which I have no insight. However, buzzword I am dissing is a risky solution: Complaint which betrays my ignorance and has been likened to somthing everyone hates. attack by analogy. Buzzword I am dissing will find some uses among people I secretly envy, but for the needs of (me) typical application developers, language gurus would do better to write something I can understand. My paper is important, pay me $50/page to read it.

  11. I'm missing something. by Lord+Kano · · Score: 2, Insightful

    There IS a GOTO statement in C++, an OOP language.

    So how can AOP be like GOTO for OOP when GOTO is already the GOTO for OOP?

    LK

    --
    "Hi. This is my friend, Jack Shit, and you don't know him." - Lord Kano
  12. I like GOTO! by Wabbit+Wabbit · · Score: 5, Insightful

    At the risk of being modded troll, nuking my karma, being yelled at, laughed at, and otherwise folded, spindled, and mutilated, I'm gonna say it:

    I like GOTOs. GOTO has it's place. Even in C++. Sorry all you purists, but there are times when it just plain works.


    *runs and puts on Chinese wicker fighting suit and hides, trembling, behind a flame-retardant wall*

    --
    Nothing is inexplicable; only unexplained -Tom Baker, Doctor Who
    1. Re:I like GOTO! by William+Robinson · · Score: 2
      Yeah, I agree with you. Not sure whether your comment will be modded as offtopic or mine...but here we go

      GOTO statements are *BAD*, I had been taught. But there are places, I had to use it. Being hardcore fan of OO... I hated it. But no options.

      There are more shocks you see when u switch languages. Had big pains to implement frameworks in C++ while keeping options of callbacks. (If somebody knows, I will appreciate it) But I was shocked to see that CALLBACKS were put down by C++ purists, which is so common in any OO language (including Java, Object Pascal etc).

      Dunno where, I had read.."When I was young, I used to think the world is black and white. When I grew up, I found everything is grey".

    2. Re:I like GOTO! by evvk · · Score: 5, Interesting

      Plain C:

      void foo()
      {
      do some thing
      if(error)
      goto err1;

      do something more;
      if(error)
      goto err2; ....

      return;

      err2:
      free stuff
      err1:
      free more stuff
      }

      For anything else I shun goto.

    3. Re:I like GOTO! by Keeper · · Score: 4, Informative

      The goto operation can be rather useful if used sparingly and correctly. If I see a goto jump up (earlier in the function) instead of down, I tend to get worried. But it is useful to break out of nested loops or complicated logic statements.

      It is also exceedingly useful for error handling, in that it allows you to skip the bulk of a function and still hit the cleanup section of the function. This gives you two things:
      1) you avoid a deep, deep mess of nested if statements
      2) you eliminate duplication of code in error handlers (and the bugs that occur later on when someone forgot to update one of those handlers to release some resource they just added)

    4. Re:I like GOTO! by Kupek · · Score: 2, Informative

      Read some Linux kernel code, particularly the system calls. Most of them are structured in such a way that they do lots and lots of error checking, and do a goto to near the end of the function that performs cleanup (mainly, deallocation of structures) if any of the error checks fail. It's really the most elegant and obvious way to accomplish the task.

    5. Re:I like GOTO! by Keeper · · Score: 4, Insightful

      Gotos in C++ are limited to the same method, so no stack problems there.

      Exceptions incur an obscene performance hit, and should be used for 'exceptional' conditions and not expected/handled errors. You also have to worry about the case where someone else adds another exception handler that inadvertantly 'catches' your thrown exception (which makes for maintainance problems later down the road).

    6. Re:I like GOTO! by evvk · · Score: 3, Insightful

      The example was in __plain C__. And besides, exceptions are worthless in a non-garbage collected language. (Ugly kludges in C++ don't count as proper GC.) You have to catch them at every point to free stuff, and the nested structures become even uglier than gotos.

    7. Re:I like GOTO! by zorander · · Score: 2, Interesting

      Goto only has a place because C++ is a weak language. If c++ had a proper runtime exception mechanism or support for continuations (which can be used to implement the former but generally only serve to obfuscate code), then gotos would be wholely unneccesary.

      Yes it works, but it's not clean. The only reason I use gotos in c/c++ code is to break out of multiple levels of scope or for a basic 'goto end' pattern in a long/complex routine that needs to ensure cleanup before returning. I suppose I'd also use it for performance reasons if I was that desperate, but I've never been there.

      The fact that it works, though, isn't enough to make me use it except in the situations where there's no other choice. I see a lot of gotos in peoples' code where they don't need to be. The creators of C/C++ left goto in for a reason--there are times when there's no other practical choice.

      A quick grep of 20klocs of code I wrote for a client indicates 12 uses of goto in 2 routines. One was a parser with a lot of multilevel stuff to break out of. The other was a non-blocking i/o routine that needed to ensure some state cleanup before returning from a lot of places, again in a nested hierarchy. Both were relatively long routines.

    8. Re:I like GOTO! by evvk · · Score: 2, Interesting

      The idea in that construct is to let the first error handler continue to the second, so that the freeing code does not need to be duplicated. Breaking the freeing code into functions is a bit heavy solution, having to pass them all the variables to be freed and so on, and it would only increase the amount of code.

      A function longer than a screenfull is too long, I never have such.

    9. Re:I like GOTO! by Keeper · · Score: 2, Interesting

      You could, if you want hard to read slower code...

    10. Re:I like GOTO! by top_down · · Score: 3, Interesting

      But I was shocked to see that CALLBACKS were put down by C++ purists

      ???

      Callbacks are everywhere in C++ although these days they are often function objects instead of function pointers. Somebody who puts down callbacks is certainly no C++ purist.

      --
      Anyone who generalizes about slashdotters is a typical slashdotter.
    11. Re:I like GOTO! by top_down · · Score: 5, Informative

      You have to catch [execeptions] at every point to free stuff, and the nested structures become even uglier than gotos.

      The freeing of resources, all resources not just memory, is automatic in C++ once you learn to use RAII.

      Look it up. It is one of major improvements of standard C++ over C/C++.

      --
      Anyone who generalizes about slashdotters is a typical slashdotter.
    12. Re:I like GOTO! by top_down · · Score: 4, Informative
      Show me code how to assign callbacks.

      Sure. This is an example using the boost::function and boost::bind libraries which have both been available for a long time and are in the process of becoming part of the standard C++ library.
      #include <iostream>
      #include <boost/function.hpp>
      #include <boost/bind.hpp>

      using namespace std;
      using boost::function;
      using boost::bind;

      void hello() { cout << "hello from function" << endl; }

      struct Object {
      void hello() { cout << "hello from member function" << endl; }
      };

      int
      main()
      {
      // callback with a normal function
      function<void()> f(hello);
      f();

      // callback with a member function
      Object o;
      f = bind(&Object::hello, &o);
      f();
      }
      If you don't want to use libraries just assign function objects or static class functions.

      If you want to do several callbacks at once check out one of the many available signal/slot libraries.

      --
      Anyone who generalizes about slashdotters is a typical slashdotter.
    13. Re:I like GOTO! by Keeper · · Score: 2, Interesting

      As the goto statement does not exist in Java, it is a given that we're talking about C++.

      While anything allocated on the stack will be destroyed when an exception is thrown, any resources allocated during execution will leak (ex: handles or memory allocated on the heap). As the data on the stack is deallocated (the very items which were referencing the afore mentioned resources), you never get an opportunity to clean up after the error condition. To make matters worse, you never get an opportunity to rollback the state of the operation when you throw the exception.

      Not to mention the complications that arise when SEH is thrown into the mix (destructors are never called on objects allocated within an SEH block)...

      Obviously you can write code to work around that. However, it is far more complicated and error prone than ensuring that the flow of execution always hits the end of the method.

      Then, there is the overhead of actually throwing an exception ... making a pure virtual function call is cheap in comparison.

    14. Re:I like GOTO! by maxwell+demon · · Score: 3, Informative
      Callbacks are everywhere in C++ although these days they are often function objects instead of function pointers

      Great! I am looking for an example.

      Ok, here you go:
      #include <vector>
      #include <iterator>
      #include <algorithm>
      #include <iostream>
      #include <cmath>

      bool is_negative(double x) { return x < 0; }

      int main()
      {
      std::vector<double> v;

      // read numbers from standard input
      std::copy(std::istream_iterator<double>(std::cin),
      std::istream_iterator<double>(),
      std::back_inserter(v));
      // those iterators are actually callbacks packed into an iterator interface:
      // istream_iterator encapsulates the input operator on streams,
      // back_insert_iterator (the iterator which the function back_inserter
      // returns) encapsulates a callback to a container's push_back member function

      // replace all negative numbers with zero
      std::replace_if(v.begin(), v.end(), is_negative, 0.0);
      // is_negative is of course a classic callback (alternatively,
      // a function object obtained by binding the second argument
      // of std::less<double> to 0.0 could have been used)

      // calculate square_roots
      std::transform(v.begin(), v.end(), std::sqrt);
      // and here we have a classic callback to std::sqrt

      // sort from largest to smallest
      std::sort(v.begin(), v.end(), std::greater<double>);
      // std::greater<T> is a function object which just encapsulates
      // the greater than operator

      // output the results
      std::copy(v.begin(), v.end(),
      std::ostream_iterator<double>(std::cout);
      // the ostream_iterator again is just a callback to stream output,
      // encapsulated in an iterator interface
      }
      All standard C++, using the C++ standard library. And also it's all genuine C++ code, not just C code moved to C++.

      Show me code how to assign callbacks.

      I don't know what it gives you, but here you are:
      callback = f;
      I'm of course assuming that callback and f are of compatible types.

      These example should be pure OO.

      Why? If you haven't yet found out, C++ is not a pure object-oriented language, but a multi-paradigm language. The code I've shown actually uses generic programming (ok, it just scratches at the surface of GP, since it only uses the STL algorithms, but doesn't define one on it's own).

      But then, if you want a typical OO version of callback, just look up the observer pattern. (And no, I'm not going to show that here as well, it's already hard enough to get the above code through Slashdot's lame[ness] filter!)

      NO C global functions. (Every function is part of some object.)

      Well, in the example above, I've had only 3 C global functions: is_negative (but this would probably be better done with standard function objects and binding anyway), std::sqrt (the standard library just has this as function, but it could be encapsulated as object as well), and main (whiuch you just cannot avoid in C++ anyway). The rest are either function templates or objects (which is typical for generic programming).
      --
      The Tao of math: The numbers you can count are not the real numbers.
    15. Re:I like GOTO! by antientropic · · Score: 3, Informative

      While anything allocated on the stack will be destroyed when an exception is thrown, any resources allocated during execution will leak (ex: handles or memory allocated on the heap).

      Wow, this is stunningly wrong. That's what destructors are for - they will free any resources that your local objects allocated/acquired. That's the resource acquisition is initialisation paradigm, and it ensures that resources are always freed when you leave a scope. This is contrary to using a goto for error handling, where you still have to be careful that every execution path goes through the cleanup code. And of course, how are you going to ensure that some future maintainer doesn't add a "return" somewhere, bypassing your cleanup code altogether?

      This is one of the really nice features of C++, by the way. It's much cleaner than finally blocks.

    16. Re:I like GOTO! by marcosdumay · · Score: 2, Informative

      GOTOs can destroy compiler optimization. Also, it destroys the flow logic of most of the programs that uses it, making it harder to read (but not all programs).

      Exceptions are what was created to avoid GOTOs on error handling, it solves problems 1 and 2 that you point, but C doesn't have them (C is old, C++ has).

      Several people use GOTOs on interruption handling, it makes their code a mess and very hard to maintain. But slightly faster.

      So, if you know how to use GOTOs (and most important, how to not use), go ahead and use them. But if you are just an old BASIC programer that dont want to take time to learn how to program on a real structurate language, get out of the way.

    17. Re:I like GOTO! by Pete · · Score: 3, Insightful
      ur comment Callbacks are everywhere in C++ although these days gives an impression as if, callbacks are part of standard C++ way.

      Well, callbacks are a fairly straightforward concept. They're most commonly used in things like GUI programming, where you do a lot of (asynchronous) event handling.

      But more generally, callbacks are just a very specific example of functional programming, which is just another style of programming that emphasises functions as first-class elements. And because C++ supports several programming paradigms, you can do object-oriented programming, functional programming and/or generic programming - often all at the same time.

      Just like in Perl, there's more than one way to do it. And there isn't any one "correct" way - whatever gets the job done is fine.

      If u r aware, OOP was first implemented on pascal (rather than C).

      No.

      Object-oriented programming is widely recognised as first being implemented on a language called Simula in the 1960s. 1962 to be precise - for Simula I - though Bjarne Stroustrup based C++ most closely on the OO concepts in Simula 67 (1967).

      Pascal was first implemented in 1970, though the original Pascal didn't support object-oriented programming.

      And Pascal had inherent capability, while C++ did not.

      I'm not quite sure what you mean by that. Most implementations of Pascal don't support object-oriented programming at all, much less have "inherent capability". Those implementations that do support OO-style programming usually aren't called Pascal - eg. Delphi, Oberon, Modula-2.

      I could go with the list of many things. For example: C++ did not provide any mechanism to identify whether this object is instance of *THAT CLASS*.

      You're using your terminology confusingly here, so it's difficult to work out exactly what you're saying. But I can say that I've only seen a few occasions where it'd be useful to work out if Base* p is actually pointing at a Derived object, and usually those cases arise when you've started out with a bad design or bad logic. Usually the whole point of having a (pointer-to) Base is that you're supposed to rely on using Base functionality. You're not supposed to care if it might actually be a Derived, the only thing that should matter is that it is substitutable-for a Base. If you need to access Derived functionality, you should have a Derived.

      But anyway, in those cases where you're dealing with someone else's badly designed code, a dynamic_cast should be enough to get around it. Take your Base* and try to dynamic_cast it to a Derived* - if that fails, you haven't got a valid pointer-to-Derived. Go find the person that built the code you're using and kick them. Hard. :-)

    18. Re:I like GOTO! by maraist · · Score: 2, Interesting

      More and more languages support named continue/break statements. Don't remember if gcc supported it yet. Such statements are more powerful than goto because they imply cleanup code that may or may not be implied by a goto. For example, you know that the for-post code block will be invoked on a labeled continue, as well as running the conditional.

      FOO: for(..) {
      BAR: for (..) {
      if (..)
      continue FOO;
      if (..)
      break BAR;

      Perl was nice because it had even more flow-control statements for clearity.. "redo", for example would go to the start of the loop-block without running those two for-blocks. This is nothing particular to perl, just a conspectual-clearity which was valued by the compiler writer; to avoid justifying use of a goto.

      --
      -Michael
    19. Re:I like GOTO! by Keeper · · Score: 2, Interesting

      I use RAII to free resources in a deterministic order all the time. You might not have total control, you still have a lot of control. And if you really need total you control you can just handcode it.

      And in the process your code just got a lot more complicated. Because now you use RAII in some places, and hand coding in other places. It gets worse if you do both in the same function, as then there is a large amount of confusion about when, where, and how certain resources are being removed. And don't get me started about what happens when someone manually cleans up RAII objects to enforce ordering, which tends to confuse the living hell out of people (ie: code maintainability and clarity is reduced).

      Something else that hasn't been mentioned is side effects of RAII objects can sometimes be non-obvious. People tend to get used to treating them as the primitive types that they are, when really they are a wrapper class for a primative type. Sometimes the operations performed on that primative type have a non-obvious side effect, which leads to 'mysterious' bugs that people spend hours tracking down.

      A good example of this is using RAII to manage a BSTR type. If you pass the RAII object into some method and a copy constructor is called to clone the object, you start off ok. The problem is once that method completes, the destructor on the RAII object is called. This calls a system method that overwrites the last error result, which was just set by the method you called. So your code ends up reporting a failure of ERROR_SUCCESS because you used an RAII type. This type of problem isn't limited to RAII types, but it is most unexpected with this sort of type due to the expectations of a person using it.

      There are other variations of this problem involved with trashing the results of method calls you can make (imagine your function has a BSTR RAII type in it, and you set the last error information before you return; the destructor for that RAII type will trash your last error result).

      When resources are interdependent than this should reflect in the design: they probably should be released in the same destructor.

      Once you exceed a certain level of functionality, you're not using RAII -- you're writing a class framework. While I'm not opposed to writing class frameworks to wrap complicated functionality and represent it in a simple fashion, I am opposed to writing class frameworks to manage simple operations.

    20. Re:I like GOTO! by Keeper · · Score: 2, Insightful

      Here is what happens in your scenario:

      void MyFunction()
      {
      char *szString = new char[25]; // do something

      if (somethingfailed)
      return; // do something else

      delete [] szString;
      }

      szString leaks.

      Now, that can be modified as follows:

      void MyFunction()
      {
      char *szString = new char[25]; // do something

      if (somethingfailed)
      {
      delete [] szString;
      return;
      } // do something else

      delete [] szString;
      }

      Now imagine you've got 20 "somethingfailed" type conditions in your method. Now imagine that the cleanup code is non-trivial. And then imagine you need to make a change in that cleanup code... This gets ugly very fast.

      There are lots of ways to 'work around' this sort of problem. All of them, IMO, are unacceptable for various reasons. Either they perform poorly, are hard to maintain, can have unobvious side effects, don't work in all but simple cases, or are obtuse (ie: result in WTF comments from people trying to figure out what is happening).

    21. Re:I like GOTO! by top_down · · Score: 2, Informative

      Resource acquisition is allocation is a technique, not a language facet.

      Of course, check out http://c2.com/cgi/wiki?ResourceAcquisitionIsInitia lization

      it works perfectly well in C.

      How does it work without destructors?

      --
      Anyone who generalizes about slashdotters is a typical slashdotter.
  13. It's not considered in the context of OOP by ravenspear · · Score: 3, Funny

    Because OOP purists would mysteriously erupt in convulsive fits mixed with violent outbursts of anger resembling a sex crazed bigfoot/unicorn hybrid if you actually used a GOTO statement while writing OOP code.

  14. best tool for the task by sfcat · · Score: 5, Interesting
    I like OO but is isn't great for every task. For instance, logging (which is the default example for AOP) is really bad in OO. This is because you have to add something like

    Log.printLog("some message " + someObject.toString());

    everywhere you want to log something. But with AOP you can used kleen operators (*, +, ?, etc) to add Log.printLog() to certain methods of certain objects. Aspects allow you to inject code into method call boundaries. But like all programming constructs it can be abused. This is because you might get an exception stack trace that indicates a specific method call has thrown an exception when the exception came from code inserted by an aspect. But other languages can be abused too (Perl anyone). So I think this type of critism of aspects says more about the critic than about the programming construct. I don't use C++ to implement logic evaluators (I would use Prolog or another logic or unification based language). Nor do I try to write OO code in LISP (despite the horrid OO extensions for LISP) because each language has it strengths and weaknesses. For each application choose the language that best suites the task.

    On another note, I think these types of critisms are really from people who are afraid of learning new languages or skills. They have worked long and hard to get good at C (or Java or some other language) and don't want to have to learn another language. Well suck it up, there aren't many Fortran programmers anymore and if you want to keep working, you must keep learning new languages and skills. Not that you should jump on every bandwagon, but if I'm writing something that needs to be really, really fast I use C. If I'm writing something that needs to be maintainable forever and speed isn't that important I use Java. The best tool for the task.

    --
    "Those that start by burning books, will end by burning men."
    1. Re:best tool for the task by AuMatar · · Score: 2, Informative

      1)Only C++ uses like that. Not all language are C++
      2)Even in C++ a lot of people avoid that usage. Its an example of everything thats wrong with operator overloading. ab means left shift a by b bits. Overriding it to now mean write to a stream is a horrible and confusing idea. Would you override + to mean something totally different than addition?

      --
      I still have more fans than freaks. WTF is wrong with you people?
    2. Re:best tool for the task by Bodrius · · Score: 2, Insightful

      Funny, this is not the first time I heard of this complaint and, for example, I wouldn't think Anders Hejlsberg was afraid of learning a new language feature considering his career... (the question on AOP is asked within the first two mins if you don't want to watch the whole thing).

      The concern predates the report for quite a bit, and from some reliable sources. This is not a surprise, as I would think the role of companies like forrester is to communicate trends like these, not to create them out of the blue.

      You are right, programmers should choose the best tool for the task. But an issue with AOP as commonly proposed is that you can use the wrong tool and do the wrong task whether you choose it or not, because the weaving is not happening on your request (pointcut), but on the aspect's (advice).

      Depending on the approach of the AOP framework this could be a risk at the team level (static weaving), or at the user level (dynamic weaving) because keeping track of all the aspects introduced by other people in your code is hard/impossible.

      AOP based on declarative annotations could help a lot, but for dynamic weaving (which still can be extremely useful) the main problem doesn't go away.

      Maybe providing limitations to the semantics of an aspect (in terms of invariants it must keep) would be a solution, but that would limit AOP to a non-general programming model, and for that we would have to define the classes of problems where it may be 'useful' or 'harmful', or provide a general way to define these limitations by the application (since we assume they are domain-specific).

      In any case, this does not seem to me like the kind of criticism coming from people afraid of a "new thing".

      Rather, it seems the kind of criticism a new technology faces when applied to 'real world' problems and projects, which is a good sign that AOP is taken seriously enough by mainstream development teams, and that there will be people working on solutions to these problems.

      --
      Freedom is the freedom to say 2+2=4, everything else follows...
    3. Re:best tool for the task by 10am-bedtime · · Score: 2, Insightful

      if you don't try to write OO code in lisp, how do you know it cannot be done (and done well)?

      hint: AOP is just half-assed CLOS.

      (no worries, i don't use any of this stuff, either. ;-)

    4. Re:best tool for the task by pkhuong · · Score: 2, Insightful

      You lost your credibility when you wrote: "Nor do I try to write OO code in LISP (despite the horrid OO extensions for LISP) because each language has it strengths and weaknesses." Given that Common Lisp is actually CLOS, an object-oriented language (one of the first ones, and one that has been called one of the few real OO language by Kay), I find it difficult to consider the standard as an "horrid extension".

      I think that, a priori, we should read criticism as an opportunity to improve concepts, not merely dismiss them. The "each language has its strengths and weaknesses" PoV, while often true, makes it easy to fall into a trap where each language or concept evolves in a vacuum, instead of becoming better and unifying concepts together by generalisation.

      --
      Try Corewar @ www.koth.org - rec.games.corewar
    5. Re:best tool for the task by maraist · · Score: 2, Insightful

      It's very rare that java code at least doesn't call a million functions to perform even the most basic operations.. Want to iterate over a collection.. Most likely you use collections instead of arrays anymore for EVERYTHING.. Why? because there are a million tools which enhance collections, filters, queries, dynamic expansion/contraction, nice default toString capability, arbitrary nesting, etc. So if what you're trying to do is print something in a while loop, you can custom taylor your aspect to capture the exact looping point.

      Likewise with the dozens of other "no-function-is-larger-than-a-screen" operations. If you want a logging point, make sure you throw it into a method.

      Ok, what about the overhead of calling functions in loops.. Got you covered, it's called JIT. Performance is no longer the reason to use C over VM's. A good C compiler might not know the optimal time to inline code verses leave functions separate. But a JIT can.. Sure it'll take many iterations to figure it out.

      This applies to aspects as well. Even though you're adding large amounts of code each each method (entry/exit points), it's likely that the most commonly used points will be inlined, re-arranged for optimal execution, etc.

      That being said, I haven't been happy with using aspects for anything that directly affects functionality.. So the example of grabbing a semephor would make me ill.. In a previous life, we used aspects as a security model.. Every method invocation of a certain category had it's returned contents acess-control-restricted. The problem was that functionality started relying on it. We wouldn't redundantly check for things, but that meant that there was magic in the code.. We justified it by saying that we're effectively segregating the database.. You physically can't get to data that you don't directly or indirectly own, so you can simplify your programming assuming that you have access to everything. Of coures this doesn't translate into SQL calls that return counts, and what-have you, so the limitations creapt up too often..

      But logging has no direct affect on an application. Statistics gathering, or run-time debugging of hard-to-reach code. Trace-paths. Possibly even event generators. Things that at the very least don't affect the operation of what a class logically wants to do or provide. Afterall most event generators are hidden from the general work-flow. They have internal fireXEvent, and side-interfaces which expose registerX or what-have-you.

      That being said, current AOP adoption is too shaky.. Either you have to manually wrap objects with proxies, or you have to run a post-compiler, which plays havoc with other post-compilers (like cactus).. You can only really safely have one post compiler, and so you should probably have no post-compilers; it's a broken concept. Something like jboss with it's class-loader runtime bytecode enhancement is cool, but not everybody wants to run under jboss.

      So unless the language itself adopts it, I'm not a huge fan of AOP right now.

      --
      -Michael
  15. $250 to read the article by LadyLucky · · Score: 2, Informative
    What the submitter failed to mention is that to read this article you have to stump up with $250. The comment in the submission is merely from the executive summary.

    'It's worth it'. Come on, how many people here read the article, let alone will pay $250 for it?

    --
    dominionrd.blogspot.com - Restaurants on
  16. Buy this document? 249.00??? by the-build-chicken · · Score: 3, Insightful

    Two fifty to hear some twat tell you that a new technology is good, but only in the right circumstances used by trained people.

    What bollocks.

    Do any CIOs still buy this crap? Do the sensationalist headlines do the job and actually sell this bs? "AOP considered harmful"...be afraid...be very afraid!

    I personally don't have a week go by when we don't find another great use for AOP...and we write financial apps...so that blows his 'frameworks only' theory out of the water.

    But I suppose "AOP, useful sometimes in the right circumstances if you make sure you train your people on how to use it, not so useful in others" doesn't exactly sell those $250 a pop articles, does it Carl

  17. Patented by matria · · Score: 2

    Looks to me like the most harmful part of it is that it's patented, or at least parts of it are.

  18. Re:Good primer on aspect-oriented programming? by devillion · · Score: 2, Informative
  19. Side effects++ by evvk · · Score: 5, Insightful

    The bad thing about AOP is that it adds lots of side effects to function calls and can thus make the program very hard to reason about. This is completely orthogonal to (purely) functional programming that intends to remove side effects thus making it easier to reason about programs.

    Functional programming: f(1) == f(1) always, with no other effects to "global state" etc.

    Imperative programming without AOP: f(1) != f(1) necessarily at every point of the code, as the function can access globals. It can also change the global state, so its effect is more than returning its value; it can have side effets.

    Imperative programming with AOP: Same as above, plus the side effects may happen somewhere unrelated to the definition of f itself.

  20. 10 GOTO 10 by John+Bokma · · Score: 3, Interesting

    GOTO doesn't cause harm (or its syntax sugared grandchildren), it's the programmer who is not able to understand when to use it or not. Such programmers are a harm by themselves :-)

  21. Re:AOP?! by sv0f · · Score: 3, Insightful

    OP is not specific to Java -- I've seen it done with Python

    And it was invented by Kizcales working in Common Lisp. For example, see this brief history.

    Those [like the grandparent] who do not know history...

  22. Re:Reminds me of my teen years by Fjornir · · Score: 3, Funny

    C:\>copy con autoexec.bat
    @echo off
    echo ^G^GSYSTEM ERROR
    autoexec.bat
    ^Z
    1 file(s) copied.
    C:\>copy con t.bat
    echo Fuck you.
    t.bat
    ^Z
    1 file(s) copied.
    C:\>t.bat

    --
    I want a new world. I think this one is broken.
  23. DSL? by tepples · · Score: 2, Funny

    What haskell infact lets you do with its IO monad is construct instructions for a separate IO interpreter (that is not pure) within the Haskell runtime. It is a kind of DSL (domain-specific language), a concept that is used a lot in Haskell programs.

    Then what are the impure languages? Dial-up?

  24. Forrester is just another clueless IT consultancy by tyates · · Score: 5, Insightful

    The big IT consultancies like Forrestor, Meta, gartner, etc are intellectually bankrupt. If you want an example, read the free article off of Forrestor's web page on IT metrics. It's absolutely worthless. Believe it not, it says that you should evaluate your IT department based on a balanced scorecard that is calculated by, among other things, the number of steering commitee meetings you have. Yes, you read that right, the more meetings the better your department is.
    These consultancies ran out of ideas a long time ago, and are trying to turn IT ito some Six Sigma pseudo-science. It doesn't work, but idiots still buy into it because it sounds impressive.

    --
    Tristan Yates
  25. $50 per copied page??? by po8 · · Score: 2, Interesting

    How do I get suckers^H^H^H^H^H^H^Hfolks to pay $250 for my 5 page speculations on computer science topics? Seriously. I'm an academic, and I write 20+ pages per month of this stuff for free. If I could get even 100 people to pay $50 per page each for it, that would be $100K per month: that's way more than I make in a year at my current job. Leaving aside the question of the price of my immortal soul, it doesn't sound like too bad a gig.

    I started to list my qualifications, but got tired of typing. Suffice it to say that they're way more than that Forrester guy has. Let me know folks: if 100 of you pay me $50 per page each, I'll research pretty much whatever you want.

  26. classic newbie blunder by Anonymous Coward · · Score: 5, Funny

    You've attempted to assign C++ to a complex left-hand-side expression (GOTO+OOP). This is a classic blunder. What you probably meant was: "GOTO"+"OOP" == "C++".

    In addition, you're overloading the use of strings to have orthogonal meanings, which is frowned upon. After all, using the standard string operator overloading, your left-hand-side "GOTO"+"OOP" is simply "GOTOOOP", which is clearly not equal to "C++" -- a good comment compiler would notify you that this expression always evaluates to false. A further refinement would be to introduce your own class and write the expression as:
    LanguageFeature("GOTO")+LanguageFeature("OOP") == LanguageFeature("C++").

    In the future, I hope slashdot will provide a better comment compiler that can automatically detect such simple mistakes.

  27. Very true. That's what i told them at IBM HRL by dharmax · · Score: 4, Interesting
    When i worked at IBM research labs, i criticized AspectJ using almost exactly the same words: they try to solve specific issues (logging, persistency, etc), that deserve specific solutions, using a completely generic approach. They failed to provide more examples for those specific problems that AspectJ will solve. Of course, i was silenced - because that's the way it works in IBM Haifa - they just can't deal with criticism :)

    The concepts behind AspectJ, TMO, are not bright. They break encapsulation, they are too ambitious and far from real-world understanding of programming concerns. All in all, they introduce too many problems.

    TMHO,Aspect Oriented Programming should be different, and should be based on something much simpler, much more down-to-earth ideas and more consistent with real-world needs.

    Today it is easily possible to do using Java Annotations, that will specify class member's affinity with an aspect, and thus provide:

    A) a mechanism by which the compiler could limit access (errors & warnings) to members according to their affinity with a common aspect or aspects (common to it and its caller);

    B) a programmer, using a proper IDE, can view a breakdown of his code according to aspects.

    C) in runtime, the current aspect should be visible to the program thus extending the ability to: I) log, and trace errors; II) affect work-flow according to the aspect in action (that's an intense feature so im not too sure about that)

    Doing more than the above, looks to be like an abuse of proper programming concepts.

    The Annotation mechanism introduced in Java 5 is quite powerful and maybe already provide all that is needed for the job, including hierarchical arrangement of aspects (slash annotations), attributes, etc. Very little is needed in order to implement what i propose.

    Maybe i'll propose is to the JCP. What'd ya think?

  28. Quite confused by t_allardyce · · Score: 2, Interesting

    So let me get this straight..

    AOP basically means that when an object is created, or a method is called you wan't to run some code?

    So if we tried to put this into a non-OOP example you would basically be calling something else whenever certain functions were called? Eg calling a 'save', 'load' or 'start' function would result in running the 'logging' function too?

    But as I gather (and its pretty hard to find a simple explanation around here) the idea of AOP is that it allows you to do this without having to put any function calls in your code, ie it 'captures events'. So if for example you had to implement some security checks but you were worried that someone in your project would forget to put the 'if(secure)' lines into their modules you could rest assured that AOP would be on the case.

    Then theres COME FROM which is basically an event handler that says 'when you get to this line/label in your code, come over here and run me.

    I see no problem with this in a relatively high-level environment where the goal is to write less code and where so much crap is going on in the background anyway (dynamic this and managed that) that another overlay is just going to make things look simpler.

    Isn't this however almost exactly the same as an interrupt?

    --
    This comment does not represent the views or opinions of the user.
  29. To paraphrase Mr Heston... by andrewjhall · · Score: 2, Insightful

    All these arguments about different methodologies and techniques being harmful or not boil down to one thing:

    "There are no good constructs, there are no bad constructs; a compiler in the hands of a bad programmer is a bad thing, a compiler in the hands of a good programmer is no threat to anyone - except the patent system."
  30. Software Patents Considered Harmful by Minna+Kirai · · Score: 5, Interesting

    And since Aspect-Oriented programming is a patented technique, basically nobody can legally use it unless you're a personal friend of the inventor.

    So, who really cares if its theoretically any good, when legally it is worthless?

  31. AOP sound in principle by triksox · · Score: 5, Interesting

    I've been following AOP (cautiously) for some years now. Here's a few salient points for those who don't have $250 to splash out.

    The underlying principle of AOP is about "separation of concerns", a term introduced by Dijkstra back in 1974. Separation of concerns is a Good Thing[tm], but there's more than one way to do it. It's a conceptual thing more than it is any one particular implementation technique.

    Both structured and OO programming offer techniques that allow the hacker to more clearly separate concerns: by organising their code into subroutines, modules, objects, methods and so on. The problem with OOP is that real world problems don't always break down into a set of clearly defined, independant object classes. In some cases you can end up with a problem fragmented into so many small pieces that you can no longer see the wood for the trees.

    AOP tries to address this by allowing you to identify those concerns that don't fit neatly into an object model. These "cross-cutting" concerns are typically things like logging, debugging and security that affect many of the objects in your system. If you decide to change the way logging is handled, for example, you don't want to have to go and edit every single object that generates logging information. But that's often what happens in OO based systems - you design your class hierarchy with Products, Customers, Orders and other real-world entities in mind and implement them as "black-boxes" with internal functionality neatly hidden away. That's fine when the functionality really is local to the object, but not when it relates to a system-wide aspect like logging, etc. These are the kind of undesirable artifacts that can arise from the decomposition of a problem into objects.

    However, that's not to say that there aren't ways of achieving the good parts of AOP in a non-AOP language. Many Design Patterns are examples of separating concerns. The Model/View/Controller and Model/Visitor patterns come immediately to mind. Going back to the early logging example, we could implement this in AOP fashion in an OO language, by creating a "Logger" object which implements all the logging functionality. Just make sure all your other objects delegate to the logger for logging rather than trying to do it themselves. Now you have all your logging code in one place, and you just have to worry about how you're going to pass the logger object around so that all your other objects can call on it... (and this is often the start of the rest of the problems...)

    So AOP-a-like can be done in OO languages, but most OO languages aren't really cut out for it - you have to code the magic manually if you want it. Hence the rise of AOP languages (usually just bolt-on syntax additions to existing languages) that make this process that little bit easier.

    AOP in Java does smell a little like GOTO, IMHO. In brief, it uses "join points" to connect different aspects together (e.g. call this logging method just before calling that other method). One can certainly argue that it's a more structured form of GOTO, but I believe the same fundamental problems remain: control flow jumping all over the place, with actions-at-a-distance waiting to catch out the unsuspecting programmer.

    So my advice on AOP would be to treat it like OOP, XML, Java, and all the other "silver bullets" that over the years have claimed to be the next big thing that will save our collective software sanity. Recognise the problem that it's trying to solve, realise the benefits of the particular solution(s) presented, and ignore all the hype!

  32. Re:Where are all the aspect gurus? by Hast · · Score: 3, Informative

    When I tried AOP a few years back it was before they added terms like joint and concern. The principle is the same though.

    We were doing a compiler in that project and that was a very good time to use AOP. From the CC programs you get a bunch of object code, but you don't want to edit these files as they are generated by other programs. Instead we used aspects which are then "weaved" into the generated code (this is what is called joints and concerns now). In reality it's pretty much a bunch of pre-compiler steps.

    Eg we did an Aspect of the compiler code called Interpret. This aspect added a method "interpret()" in all classes, and you can easily define it's default behaviour as well as adding specific behaviours for some classes. So in our case we defined expressions to return their values and print statements to do a println and so on.

    Run the pre-compiler steps, then compile and you've got a compiler that can parse and interpret code. Now add a new stamtement type to the grammar, and do it again and you have a new compiler working. No need to hand edit a bunch of files.

    Naturally since this was in the early stages one problem was that looking for compiler errors in generated code was a bit of a bother. All in all it was a great help.

  33. Objective-C has these, and no one bats an eyelash. by israfil_kamana · · Score: 5, Informative

    A very well respected (if a bit obscure) OO language is Objective-C. It has a few features that are analogous to aspects.

    First it has categories, which allow you to add new methods, or replace the implementation of a method in a given class. You add a category to that class that includes, say, a replacement description method, and the new implementation replaces the old. Or you can add a path utility methods to the String class, as another example.

    It also has "poseAs", which allows you to insert an object into a hierarchy. Say you have Class B which extends Class A. But you want custom behaviour to be accessible to all As children (including, for example, B). You create Class C, which extends A, and make it poseAs Class A. Now the runtime hooks all clesses that inherit A off of C, which replaces A. A still exists, but is in the background, providing normal inherited functionality to C.

    These abilities were one of the things that made Objective C a very powerful OO language. In particular, it allows a particular kind of reuse, by virtue of allowing one to patch someone else's library without having source. So if you want to add the aforementioned path utilities to NSString, you just added a Category in your own code, and your code would run with the extended functionality in NSString (no one elses would, unless they used your category too). This means that often you can make the most out of someone else's code without a complete rewrite.

    It isn't all powerful. There are access and visibility restrictions. It is also used to partition code for ease of organization and better modularization. Here's the point:

    Because it is a well known feature of the language, you think in terms of categories, and you know to look for categories. This can be aided by tools, but you most definitely need to pay attention to them. But because of this, they are only "dangerous" if you aren't paying attention. And guess what! That's true of programming, period.

    --
    i - This sig provided by /dev/random and an infinite number of monkeys at keyboards.
  34. Re:Objective-C has these... by israfil_kamana · · Score: 2, Informative

    Woops, forgot to add a C2 Wiki entry for Objective-C.

    --
    i - This sig provided by /dev/random and an infinite number of monkeys at keyboards.
  35. AOP has its uses (without going to production!) by bsletten · · Score: 4, Informative

    AOP is not the answer to everything, but one of the main points of a talk I give at the NFJS show is that you can find tons of uses w/ development aspects without ever having to migrate them into production.

    You can enforce (and detect violations of) various architectural decisions (i.e. no direct JDBC connectivity without going through a facade), define and enforce contracts (and leave them out of production), detect threading issues (How would you find all Swing thread abuse cases in a large, multi-threaded application?), get a sense of code coverage, etc. around any arbitrary cut of your system.

    If you take the time to build around interfaces and support Object decoration via some variant of factories, you can do some of these things using Decorator and Dynamic Proxies, but you don't always have that luxury.

    Tool support has been fundamentally lacking until things like recent versions of the AJDT. It still isn't perfect, but should serve to answer many of the early critics complaining about debuggability and losing track of what is going on.

    I am an advocate of AOP in production systems, but you don't have to drink the whole glass to find aspects tremendously useful in development alone. With support for Ant-based builds and whatnot, it isn't even really an onerous task to give it a try.

    Don't use AOP for things it isn't a good fit for, but there are quite a few things that can't be done as easily and elegantly without it (at least in Java). As others have pointed out, languages like Lisp and Objective-C have support for AOPish things built in.

  36. This doesn't deserve to be a Slashdot article by PleaseDontBeTaken · · Score: 2, Insightful

    A story that refers people primarily to a uninformative abstract on a $249 for-purchase paper simply isn't worthy of being an article on Slashdot.

    If I could mod down the story choice, I would.

    Sorry to be a downer, but this needed to be said.

    --
    --
  37. AOP is a two edged sword by MemoryDragon · · Score: 2, Insightful

    Just like goto, which I would not totally consider harmful. Goto has its place in programs which need a precise command which maps directly to a processor jump instruction, therefore goto or similar constructs are widely used in system near programming.

    I have to admit, I stayed away from AOP for a long time, but that stuff can be really useful if applied in the proper manner. The usual application has lots of sideconstraints which basically stain your algorithms up to a point, where you end up having 2/3rd side constraint code, 1/3rd algorithmic code. The side constraint is constantly the same over and over again, only altered slightly according to the state of the algorithm.

    Now if you move that code in a well documented and clean manner into aspects, you can gain a lot. Aspects however are a deadly construct, if you go the AOP is everywhere manner and dont limit yourself to the basic rule, use it seldom and use it wisely but use it whenever you can achieve a cleaner code with it. If you go the aspect here aspect there route, you end up in a bigger mess than with a huge spaghetti code and 100 gotos in there.

    Perfect examples for AOP are, to move the error handling code of checked exceptions out of the algorithms into aspects, another one would be to get a clean semi automatic transactional scope in methods which are called from the outside. Both things can be achieved with aspects in a much cleaner way, than with traditional programming, but if you use this stuff in that manner, document it and comment it, otherwise the persons who will follow you cannot see that the method is in a transactional scope.

    So aspects are definitely worthwile using (I learned that once I jumped over the wall of considering it a deadly construct), but you really have to be careful to limit it to a few problem domains.

  38. My Take on Aspects by nimblebrain · · Score: 2, Interesting

    Aspects 'inject' behaviour into your classes. This is fine if the behaviour is completely orthogonal to the workings of your class, e.g. you're injecting enter/exit logging. If you start to inject functionality, however, the workings of the class can be substantially obscured. A number of the examples I've seen can be as properly done with more broken-down normal methods and a naming convention (e.g. before_x, after_x).

    That said, chances are that the true benefits of aspect-oriented programming are not going to come from it being a mere curiosity to add to object-oriented programming. Someone is going to have to discover how to program in AOP where the focus is on AOP.

    Possibly, it will have a journey like object-oriented programming. Started out with being used as object-based programming (just a more convenient way to associate data with functions), grew to some standard uses, then exploded into class libraries and eventually patterns.

    Even 'interface-oriented programming' requires a slightly different tack than plain object-oriented programming does.

    That's not to say that AOP will be the next actual big thing, or even really find its niche. There are plenty of good ideas that never really 'made it'. Time, and a whole passel of people with a lot of on their hands, will tell :)

    --
    Binary geeks can count to 1,023 on their fingers :)