7 ms·
I am happy that AOP never really caught on. The idea of modifying the behaviour of a class in a completely different place of the source tree has always horrifi
by tjansen 3y ago
I am happy that AOP never really caught on. The idea of modifying the behaviour of a class in a completely different place of the source tree has always horrified me. Makes it pretty much impossible to understand code by just looking at a single file.
Admittedly, IDEs were pretty rudimentary when AOP was first introduced, and today's IDEs can display aspects right where they are applied. But I still think that annotations/decorators are a far better solution for the problem that AOP tried to solve.
- pjmlp 3y agoAnyone using Python, Ruby, Java and .NET frameworks is using AOP, how much of it depends on the framework.
- whstl 3y agoYeah, I feel the same. I think that in the surface the idea was interesting, but the final implementation, with the "weaving" involving code transformation, and also the fact that there was some "inversion" of control flow (where the COMEFROM comparison comes from) weren't really good. All that flexibility was probably a good selling point, but it just wasn't necessary IMO. I think in the end things like Python decorators follow similar ideas without the problems associated. No magic, just functions. I do like that AOP helped "Cross Cutting Concern" become a common thing in development vocabulary, though.
- marcosdumay 3y ago> but it just wasn't necessary IMO AOP makes Java style logging incredibly convenient. That was not only its main selling point, but also it's one single benefit that people managed to identify during the few years it was hyped. IMO, Java style logging is bad by itself. But surely, AOP does make Java style logging much more convenient.
- TeMPOraL 3y agoI have the opposite view. AOP didn't go far enough. At this point we're reaching limits of IDE support[0] and language design. New languages have been piling up increasingly arcane mathematical abstractions to try and squeeze in a lil' bit more stuff in the same number of characters, but they too can't get past the fundamental problem: there is only so much you can fit in a piece of plaintext. You can't cover every cross-cutting concern at the same time in the same piece of code, and keep all of them easy to understand and work with. That is, we are being limited by insisting on directly authoring and manipulating source code that's plaintext and a "single source of truth". AOP solved a lot of these issues, but it was hamstrung by being deeply embedded in that "plaintext single source of truth" code workflow. It was confusing to have "spooky action at a distance" that's invisible unless you're using a properly configured IDE, but the real problem here is that we expect everything to be local in the same piece of text. If we drop that expectation - learn to work on higher-level representations of the underlying source code - then none of it is a problem anymore. AOP becomes a subset of more general techniques of authoring software systems. -- [0] - Perhaps with exception of LLMs, which promise to be able to both write heaps of code and explain what all that code does. We can probably ride quite far in that direction, but it'll also eventually hit the same wall: no more progress until we abandon the idea of working with the plaintext source code directly.
- BlargMcLarg 3y ago>It was confusing to have "spooky action at a distance" that's invisible unless you're using a properly configured IDE This statement seems slightly ironic given the prevalence of IoC containers in the most commonly used backend languages and rampant 'interface everything' syndrome alongside it. You'd almost think such a world would embrace AOP.
- 0x445442 3y agoIf you look at something like Spring, IOC isn't the issue but annotations are.
- marcosdumay 3y agoIt's a silent change, but I think IoC is becoming commonly accepted as a bad pattern. (And I'm sure we will see a overreach at some point where people do bad things to avoid it.) The most commonly used languages are there because the most conservative people (that hire a large majority of people) pick them.
- rewmie 3y ago> but I think IoC is becoming commonly accepted as a bad pattern. I have no idea where you got that from. Inversion of control is perhaps the most important design pattern ever devised, and IoC frameworks make or break any project. Where exactly did you get your personal assertion from?
- TeMPOraL 3y agoWhich IoC? So many different things meant by it. Often overlapping with Dependency Injection. In the most basic form - passing dependencies to a function/object constructor, instead of instantiating them within said function/object constructor - I feel it's mostly a good idea, but there's something that's bugging me about this, and I'm not yet able to pinpoint what that is. The more advanced form - autowiring things with magic annotations - yeah, I hated that when I was working in Java. However, these days I think the problem isn't with the idea, but - again - with our insistence on working with the final, pre-binary, single source of truth plaintext code. That is, autowiring is the kind of stuff that really needs support from tooling able to tell you what exactly happens in a particular scenario - it feels icky, but it does so because we're not used to relying on tooling over raw plaintext. And what I'm saying is, we should ditch the plaintext and embrace the tooling, or else we'll remain forever stuck in endless debates about code style, readability, etc. - problems that, to me, seem to be fundamentally caused by hard limits on how many cross-cutting concerns you can cram into a single block of text.
- carlmr 3y ago>Makes it pretty much impossible to understand code by just looking at a single file. This always made OOP so frustrating to me. You have to go look in tons of places and build a mental model of all of them to have an idea what code does.
- hutzlibu 3y agoUnless you had a nice UML diagramm. (But then you had to keep the diagramms in sync with the code)
- rad_gruchalski 3y agoAnd someone invented BPML. So one can have diagrams and code!
- thom 3y agoAre there programming paradigms for which this isn’t the case?
- Detrytus 3y agoWell, the functional programming promise is that output is a function (pun intended) of inputs, no side effects allowed, thus you can understand any given function by reading only its code, no additional context required.
- FlyingSnake 3y agoDitto. AOP was pretty big in Enterprise Java shops in ~2007 era and I'm also glad that it never took off. It was one of those fads driven by "Architecture astronauts" and it resulted into lots of bloated code and delayed/failed projects. I vaguely remember one major project from Visa that used AOP heavily and was an unmaintainable hot potato. It was passed on to different consulting companies and everyone messed it further by adding their idea of AOP to it.
- lloeki 3y agoAs with all things, it is a tool to be used wisely, and refrain from seeing everything as a nail when you have this hammer. It is notably extremely useful as a concept for instrumenting software, which is exactly what e.g APMs are doing. ASMs can go a step further and not just gather information but take action (sanitising arguments or return values, or even interrupting calls) (disclaimer: I used to work at Sqreen, now work at Datadog) Short of having first class support for AOP we're left implementing our own solutions to hook and instrument on various languages. Some examples: https://github.com/DataDog/datadog-instrumentation-gateway-ruby https://github.com/DataDog/datadog-instrumentation-gateway-r... https://github.com/sqreen/go-agent/blob/master/doc/instrumentation.md https://github.com/sqreen/go-agent/blob/master/doc/instrumen...
- koinedad 3y agoI totally agree. A few months ago I was debugging some AOP related code and it was not a fun experience. Let’s making coding even more complicated so you don’t know what the src output will be.
- kazinator 3y agoBut you will still have a job when everyone around you is replaced by a large language model. :)
- goeiedaggoeie 3y agomacros in rust have access to the AST as well and is used a TON in language. AOP is at times tricky to debug, but super useful for cross cutting concerns.
- kazinator 3y agoSeparately from AOP being an incredibly bad idea, implementations of it contain another bad idea: using pattern-matching on symbol names to select a point cut. As a Lisp person, Kiczales should have know better than to go around splitting atoms. You're really planting a bomb when you capture not only every currently available method that begins with "Get", but any future one someone may add. Computer programs should ideally have the property, that any identifier occurring in the system can be replaced by one having a different name (other than that of some existing identifier), such that the program's behavior doesn't change. The only thing significant about identifiers is whether two identifiers are the same one or not. An identifier's name is just for debugging, and for linkage across subsystem boundaries that do not admit the passage of object identity.
- incrudible 3y agoIt is bad for changing the behavior of the programs intent (for lack of a better word), but it is good for observing it. Non-intrusive selective logging is the obvious use case. Generally though I agree, architecting your software around AOP features is a terrible idea. Strike the O in any programming paradigm and you will be better off.
- kazinator 3y agoI think AOP is basically a tool that is most valuable to people who are dealing with some monstrous legacy code base that they don't want touch (let alone fully understand), but are under pressure to deliver some solution to a new requirement. It lets you play games like "when the legacy code makes certain calls here and here, we do our thing, with our state, without disturbing anything else". If it doesn't work out, the AOP stuff can be easily backed out and disabled (or further massaged), rather than reverting some commit over 37 files of legacy code. It's kind of like the software equivalent of patching a circuit board with wires. You have a bad circuit board, already manufactured in some quantity, and need to demo the hardware tomorrow. No time to spin another rev of the board.
- kazinator 3y ago> Makes it pretty much impossible to understand code by just looking at a single file. But note the irony there! The motivation behind AOP is to have separation of concerns. For each new requirement heaped onto to the system, we can ideally just write one new module (using AOP), so that that requirement's implementation is concentrated in one place. Oh, someone wants logging for all the database calls? No problem; don't touch the database calls: let's write an AOP module which invisibly adds logging to them from a far. Then when you're looking at the database calls, you can pretend that logging of database calls doesn't exist (or not even know). When you do know there is such a thing, you have it in one place. Yay! The thing is, why is it the database calls that are at the bottom? Because they were written first? Something has to get written without AOP in order for AOP to have something to hook into. One problem in AOP is that we can't start with an empty program, and then go through a list of concerns and implement them with AOP. It's just a kind of parasite that needs a host.
- hinkley 3y agoHaving too many concerns involved with a piece of code is the problem. AOC doesn’t fix that, it makes it more likely to happen. In the time since AOP, a lot more API designs have sprouted support for closures. That’s “around” semantics and the degenerate cases of around are before and after, which covers most of the space. Async/await fills in some of the remaining gaps.
- kazinator 3y agoSpeaking of around semantics, which brings me to the CLOS topic, I first learned about AOP in 2005 at a live presentation by Kiczales. He made disparaging remarks about Lisp and said that CLOS should be pronounced "see loss". Remember, that's the author of the Art of the Metaobject Protocol, and of the Closette project (portable implementation of CLOS-like object system).