Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
Introduction to Aspect-Oriented Programming (abstractowl.github.io)
57 points by owlish on July 12, 2014 | hide | past | favorite | 48 comments


AoP strikes me as one of those things where someone just invented a bunch of terminology around a really basic concept, for no good reason.

Aspect? Advice? Joinpoint? Pointcut? Really?

As far as I've been able to understand, AoP is just hooks. You can hook something before or after a function, or 'around' it which is a combination of both. Super useful, but really not that amazing or novel. Definitely does not warrant its treatment as some kind of separate type of programming.

...

Small nitpick with the article: In the example given, the call timing uses 'around', which measures the entire function as opposed to just the part of it that the initial function was measuring, right?


>, AoP is just hooks.

Yes, that's a valid perspective. But it's an incomplete one. Your reduction of AOP is highlighting the mechanism (hooks) but ignoring the purpose (the SOC separation of concerns).

It is the goal/purpose that motivates the separate umbrella label of "AOP". The hooks happen to be one implementation detail.

I'm also not a fan of creating a barrage of neologisms (e.g. see Thomas Friedman books) but the thinking behind AOP generating its own terminology seems reasonable when compared to other concepts if we mentally separate the "hooks" from the "goal":

hooks: insert instrumentation before & after lines of code

goal: performance statistics and optimization

hooks: insert code to mark memory regions with setinels

goal: memory safety check -- detect buffer overruns and wild pointers

hooks: extern "C" ABI, or Win32 COM, or Wordpress plugin specification

goal: extend software functionality by heterogeneous programming languages, or 3rd party developers

With those examples, reducing "goal" concepts down to hooks such as "3rd-party software plugins are just hooks", and "performance instrumentation are just hooks" isn't adding information to why programmers are doing it and also doesn't explain why separate tools are created to support it. Therefore, unifying (reducing) a dozen disparate computer science concepts down to "hooks" isn't going to help us.

Getting past the "hooks" component and focusing on the larger concept (goal) in a systematic way may let us make advancements in its use (tooling, business ROI to implement, etc.)


The purpose of most work in programming language abstraction is separation of concerns, it's not like we weren't doing that before someone coined another name for modularization and a new mechanism (AOP) for doing that.


I'm not an AOP practitioner or apologist (Greek definition) but I think that AOP is emphasizing separation-of-concerns that are non-functional and non-core algorithm. Logging, audits, safety, etc. This is different emphasis of thinking from the abstraction/modularization of passing a custom compare() as a function pointer to quicksort().

I believe that speaking of AOP as an isolated concept is reasonable. Whether it reduces down to "hooks" or reduces even further down to assembly language "mov, add, jmp" instructions is not that interesting to me.

We have text editors that are 1-dimensional and linear. The programming code is not in "layers" like layers in Photoshop or AutoCAD drawings, and yet we're trying overlay N-dimensions of concerns throughout the code. We have some crude attempts such as text editors outlining collapse/expand of code regions (code folding). We have syntax coloring of programming language keywords but not of the higher-level concerns. Can the tools make this better?! Maybe. We (the computer scientists and programmers out in the real world) are trying to figure out how to interweave all this in a sane way. A focus on this issue of coding all the N-dimensional cross-cutting concerns will naturally lead to a umbrella concept that's researched in isolation.[1]

I don't believe in AOP as the The Next Big Thing. I also don't believe reducing it to just "hooks" adds to the research about it.

[1]https://www.google.com/search?q=n-dimensional+concerns+progr...


You'll get N different definitions of AOP if you ask N people for them. Separation of concerns was actually coined (aside from dijkstra's original usage) by Peri Tarr for hyperspaces, which was focusing on functional concerns (just around multiple dimensions) and not the non functional concerns of AspectJ. But for functional concerns we have lots of direct options, while for non functional concerns we also have indirect options like garbage collectors. The space is quite big and well travelled.


>You'll get N different definitions of AOP if you ask N people for them.

This is true for many computer industry concepts:

"object-oriented", "functional programming", "garbage collection", "big data", "programmer", "hacker", "technical debt", etc.

Regardless of all the fuzziness around terminology, we still try to advance knowledge forward, improve the tooling, possibly improve language syntax, codify and/or formalize best practices.


Just wanted to agree, kudos to better tooling support being an important enabler of AOP (beyond research prototypes, that is). It is not separation of, but cross cutting concerns what is highlighted, i18n, logging, error handling, target platform, etc., all with potential variations. While these commonalities are usually dealt with by throwing them to a library, the interactions of the alternative layers (there will be since they are going to be heavily coupled by the very definition of "cross cutting") is better dealt with, or could potentially hurt less using some version of AOP ideas (EDIT deleted FODA reference).


Right. The main question in our field is whether the term "AOP" is useful or not. The current popular thinking is that it is not very useful, but modularity, as always, is a great concept.


It really reminds me of Wordpress' hook system... And that makes me want to run away screaming, as the maintenance and testing nightmare that that entails has easily removed a decade off my lifespan.


We use a lot of AOP at work and explaining all the arcane terminology to new engineers is always a nightmare .. but it's necessary to work with basic libraries. So I totally agree.


I think a lot of the research around AOP was doing all this stuff, but with static checking. Which gets less trivial pretty quickly, and the distinctions become necessary.

But I agree in spirit.


So this is a fair point. With the dynamic / runtime variety it is not an issue. If you really needed the static variety (which is fair if you have a billion points hooked), I think that's a tiny subset of a more generalized problem about a language's static-analyzability, which matters in many other contexts anyway, like in-editor linting.


well, in AOP you can describe situations such as "when f is called within g". I think it's a lot more complex than just hooks.

Whether this extra descriptive capability is a positive thing is an open question (well, considering AOSD (Aspect-Oriented Software Developement) confernce changed to Modularity, maybe the question has been answered negatively)


In science you give something a name so you can reason about it more easily. So yes, really.


urggh...is this still a thing?

AOP is an idea that sounds wonderful as a concept - "Hey wouldn't you love not to be peppering your code with logic unrelated to the business logic in your code?"

Great idea...however, every implementation I have seen is terrible. It makes code nearly impossible to test and audit and, in addition, creates a whole other set of code that needs to be tested and audited.

Taking the example at hand. From the first function I have a clear idea of what to expect, when I should see logging and what the failure cases and responses are.

Now instead of a 1 line log statement, the article proposes the 7 line meld definition is much cleaner. Where does this code live?

Another 7 lines to track the length of the call, opposed to 3 lines in the function. And now I have a hidden entry to my function - before the calling path was clear...calling dial() meant I called dial() now calling dial() means I actually call some random function which, assuming it has been written correctly, calls dial()

The error handling is possibly the one redemption here, but still - OO provides you with the tools to encapsulate retry logic just fine without resorting to AOP.

I didn't like AOP when I first came across it at University, I didn't like it when I came across some code at a previous employer, and I don't like it now.

Nice write up though.


> urggh...is this still a thing?

No, fortunately. AOP was relegated to the museum of programming history, section 'ideas that didn't work out' (the largest section in the museum, BTW).

> I didn't like AOP when I first came across it at University, I didn't like it when I came across some code at a previous employer, and I don't like it now.

Amen.


I guess a few people are still talking about it because it sounds significant, the name sounds as if it's competing with OOP, instead of being the gimmick that it is.

We do the same thing in OOP (without the "spooky action from distance" you've noticed) with the Decorator & Strategy patterns, very simple patterns, even those who don't know about patterns are probably using them without knowing.


There are people, who prefer pure C, without OOP's "spooky action from distance". Just like language support for OOP concepts, AOP gives you a higher level of abstraction to solve complex problems.


Apart from logging, it would be good to see a variety of examples where AOP is clearly preferable to dependency injection/IoC. AOP has a bit of a feel of "spooky action at a distance" to it. Extra code is inserted in your code, without you inserting some markers at that point as a clue to the reader.

I could see wider adoption for a variant of AOP where the join points needed to be explicitly annotated in the code. However, this would just seem to be first-class language support/syntactic sugar for dependency injection/IoC.

There may well be great use cases for AOP, but people need to see examples that justify overcoming the unfamiliarity of AOP. Logging by itself hasn't been a compelling enough use case, and several of the other use cases are almost as well served by dependency injection/IoC without introducing the cognitive load of an unfamiliar programming paradigm.

Also, presumably the cognitive load of AOP goes down with familiarity, but how much does the cognitive load really go down? It seems very difficult to reason about code being arbitrarily inserted at arbitrarily defined join points, without the join points being annotated in the code.

Are there editors with really good AOP support, so that when programming in the large, programmers can easily see the active join points in their programs and expand them? Without good editor support, AOP seems (at least from my shallow understanding) to be a feature that's very useful in the small, but very easy to over-use in the large.


The software my team works on at work is java based, and make pretty extensive use of aspects with Spring AOP. Generally, I've learned two lessons to reduce the 'what the Fuck just happened here?' problem.

First, the method being given the aspect should be annotated. @LogsArgs or @Transactional. None of this 'oh we just use an auto proxy to apply this to every method' bullshit. Tell me you're doing something.

Second, the annotation should be and to tell you exactly what it's doing with just the name. @LogRequestAndResponse. What does it do? Exactly what it says. If you can't describe the end result easily, then how will the next guy have a clue what just happened?

Whenever I've followed these, I don't regret aspects very often. When I stop following them, people get confused.


Annotating the Methods seems like an anti-AOP pattern to me. Of the comments become code and get filled with AOP stuff, it's not an different Form putting the calls into the methods themself, beside some performance improvements when running the code without annotations. But the code will be littered with stuff that should be outside of it.


It makes into a slightly different but still invaluable pattern. I'd rather have code that says what it does, but says it in the most concise way possible, than code that just has black magic running on it in the background.


It's a little different:

1) Reduce 'soft' duplication. Overhead of having many small logging calls everywhere is probably higher than we all want to admit 2) Reduce small variances. Common logging format is useful (as a baseline-- additional logging is probably also useful)

I'm not terribly familiar with AOP but the cognitive overhead IMO is reduced if you just have to act as a client to logging (via annotation) than bespoke implementations at each call site.


This is good advice. You do lose the transparency of the approach in this case, but you are otherwise stuck in a higher-order form of callback hell if you don't.

Though one wonders if they could get rid of even this if they just had some dynamic scoping.


We use AOP at my job for an ASP.NET project (disclaimer: I introduced itt) and it works well for our purposes. We have custom authentication/authorization mechanism and AOP fits the need well. The base class of controllers are annotated with decorators and these rules filter down to all derived classes and action methods. These rules can be overridden at the method level by applying an alternate annotation that overrides the inherited one. This combined with automatic model binding allows us to automatically check access to any resource without performing explicit checks in every method. Security by default is a huge win.


From what I understand, AOP is mainly useful for modifying code at runtime that you can't modify before compile time. So for adding logging to your app, meh. For adding logging around a closed source third party lib? Awesome.


Not really, AOP can be compile time - e.g. PostSharp.


Compile time around third party code, or just yours? Because I was trying to extract a point of difference where AOP does something you couldn't do otherwise.


AFAIK - PostSharp modifies your code based on annotations you specified on whole assemblies, namespaces or just classes during compilation to do stuff that otherwise would be impossible


> Every time you use CSS, you’re doing Aspect-Oriented Programming

Uhm...no. I don't really get how someone could convolute declarative rule-based programming with AOP. Granted, they both deal with modularization (aka separation of concerns), but almost all work in PL does! There is a good reason why the AOSD conference was renamed Modularity.

I loathe the day when AOP comes back in style as a 2nd-run fad.


I agree that CSS is not AOP, but not for the reason you state. From my perspective both CSS and AOP incorporate a declarative rule based programming language. (At least most AOP does).

The difference relevant here between the two is that CSS applies its rules over data, and AOP applies its rules over code. (another big difference ofc is that CSS is a DSL whereas AOP is a general purpose technique)


Not all systems that have referred to themselves as AOP are rule-based...mostly AspectJ and some annotation based systems are (e.g. Spring). Some systems apply rules over execution, but this is just applying it over code in a different phase (think static vs. dynamic type checking).

AOP is not generally described as being limited to rule-based techniques.


I don't see why you can't have both declarative rule-based programming and AOP.


Sure, the only question is "what is AOP?"


Could monadic types solve the same problem in codebases, by letting you compose "business" and "implementation" functions?


That's the idea behind the Reader pattern: http://blog.originate.com/blog/2013/10/21/reader-monad-for-d...

Essentially, your business logic operations return a function of Implementation => Result, rather than just your Result, and you then call the function with whatever implementation you need at the edges of your application.


Multi-Dimensional Separation of Concerns is more useful and can easily be modelled in standard oo without tools. In a game for example you can have three dimensions, data, features and system dimensions. Where each is a folder hierarchy in your solution. Here you use the standard oo cross dimension with interfaces. Like system dimension export interface IGUI which exposes return actions and info functions that features and the data dimension classes can implement.

But you can also make a feature cross dimensional by using partial classes. So if you want to add a new feature, let's say Move you add a behaviour class in the feature dimension, in a new folder, which implements interfaces from the system dimension like Igui and Igamestate and uses a TroopDataClass from the data dimension. Then you make a new folder in the data dimension and make a partial class for TroopDataClass where you add move based data like petrol. Now that whole feature is isolated, you can easily remove both Move folders and nothing will break everything will compile just as before.

The advantage is that you get rid of the spiderweb dependencies you get if Move where a standard class with combined data and behaviour. For data that still is feature crosscutting like ActionPoint or Position on the map, you can still use inheritance and standard oo techniques within the Data dimension, so TroopDataClass inherits from MapObjectClass or something similar, then all features will have access to them.

http://www.cs.bilkent.edu.tr/~bedir/CS586-AOSD/Syllabus/NDeg...


Or you could use mixin layers or virtual classes, or open class patterns. There is literally a million ways to do this. Today, I use partial classes and approximated mixins (C# doesn't have real mixins).


Nice writeup, though I was struck by the author's funny use of the word "concerns":

> Remember that AOP aims to separate concerns from business logic ... It turns out that nearly half our function code is devoted to concerns!

Separation of concerns is about separating concerns from each other, not from business logic. Business logic and logging are both concerns.

It doesn't ruin the article or anything, it's just an interesting mistake.


I've bought into the AOP thing a couple times, and every time it has bitten me (or my coworkers) in the ass.

I fully admit that it may be too much power for mine (and colleagues) small brains, but has anyone ever actually seen AOP work, in practice?

It sometimes reduces coding efforts, but it is the living embodiment of the saying, "If you're as smart as you can be when you write it, how will you ever debug it?"

It's just too much magic spread over too wide an area. I'd much rather have more explicit patterns being used that people can understand, find, reason about, and debug - code reuse is a means to an end, not the end itself.

Again, maybe I'm just not enlightened enough.


I've applied the technique in a project once with a pretty nice effect. I think the key requirement for AOP is that your code really is very clean, and to never influence logic in your main code in any other way than stopping it.

I.E, if you insist on catching exceptions in your crosscuts, don't go trying to fix the exception by modifying state. Either kill the thread, or let the original logic deal with it.

Our project was a bit of a laboratory environment. It was a university course that meant to test our ability to apply Patterns of Software Development (i.e. GoF) by having us implement a board game called Bohnanza (basically a heavily simplified Magic: The Gathering).

Our approach was to fully focus on implementing the business logic in a correct and test-driven fashion. In the weeks we spent on implementing the business logic we never implemented any GUI.

Then when it was done instead of polluting the business logic with the traditional MVC architecture, we designed a GUI that was layered on top of the business logic through AOP.

The GUI was just observing through cross cuts the transitions of the games state machine, rendering the relevant game elements and making available the valid inputs. We were one of the few teams who managed to have both a correct game logic and a fully functioning GUI as well as a test suite with good coverage.


So much AOP negativity on here. I haven't specifically used AOP in a project, but I do recognize huge value in its concepts. Many of the techniques here also have other names in other traditions, but if you get past the rather awkward terminology, the concept of factoring separate concerns into reusable and independently testable chunks is really useful, by any name.


My negativity comes from experience. I also like the theory and concept of it, but I haven't found it to help in other than very specific circumstances, and quite destructive in time and understanding when used even slightly outside those.

Terminology had nothing to do with the issue, in my particular experience.


Once had a job interview at a software consulting company. They had a number of finished projects for high profile customers and they claimed that they use AOP for their projects. Turned down the offer though because I didn't like the people too much. ;)


I've found myself wanting at times to keep logging outside the fuction, but then I realized I would have to write a lot of extra comments to fill in for the documentation the logging itself provides.

As long as the logging logic itself is kept elsewhere, having logging instructions within the code is not an obstruction. Logging events themselves can have semantic value, as they would often mark some key point in the execution.


I've always wondered why only Java seems to have this concept.

I haven't quite dug into a "real" macro system (I don't mean the c macro system) but is it that a good macro system is able to replace("emulate") AOP?


The first time I met AOP is I use Spring framework. AOP is a good thing for logging or authorization check, very powerful.


It would be cool to see a comparison between AOP and the monad stacks of Haskell.




Consider applying for YC's Summer 2026 batch! Applications are open till May 4

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: