digitalmars.D - Mixin Aspect-Orientation: Comments please!
- Tony (41/41) Jan 16 2011 Here is a quick outline of an idea of how the aspect-oriented programmin...
- Ary Borenszweig (12/12) Jan 16 2011 You can already do that:
- Tony (7/22) Jan 16 2011 Hi, thanks for your reply but what you suggest is not enough.
- Ary Borenszweig (18/18) Jan 17 2011 Say you have this:
- Simen kjaeraas (10/20) Jan 17 2011 D, by its static and compiled nature, does not support what you
Here is a quick outline of an idea of how the aspect-oriented programming paradigm could be incorporated into D. What I’d like to propose is picking only the most useful features of AOP while keeping D as lean as it is. The big promise of AOP is the potential of keeping your code very clean even as it grows by having your orthogonal concerns kept apart. The extensions to the current D syntax that would be needed may not be that many: Suppose you have this class: class Foo { int fun( int x ) { } } Now let’s create some advice. Advice is code that is injected to handle some specific concern. One reason complex programs easily become cluttered is that they usually have many different concerns with little bits and pieces of them everywhere. AOP solves this by abstracting concerns into separate units instead of having each concern scattered all over the code. It’s a kind of modularity. mixin template AdviceX() { int fun( int x ) scope( entry ) { } scope( exit ) { } scope( failure ) { // undo changes here. } scope( success )( returnValue ) { // const access to return value. } } The new thing here would be the ability to append statements to the beginning and end of a scope. By using the excellent scope construct different advice are kept separate and yet well integrated with the rest of the code. Any exception will be dealt with properly. Here is how you would include the mixin advice: class Foo { mixin AdviceX; mixin AdviceY; int fun( int x ) { // not replaced. } } The order in which the mixin advice are specified determines their nesting order. Please comment!
Jan 16 2011
You can already do that: mixin template AdviceX() { int fun(int x) { ... return fun_without_advice(); } } class Foo { mixin AdviceX; int fun_without_advice(int x) { } }
Jan 16 2011
Hi, thanks for your reply but what you suggest is not enough. With your solution you cannot add new advice without breaking stuff elsewhere. You don't want to clutter the namespace with lots of new function names. What you would want is to actually inject the code into the present functions. What would make this even more modular is if you could use the mixin statement outside of the scope that you want to inject into by specifying the location: mixin acme.nuclear.Lollipop SomeAdvice; That way you could extend code without touching its source. Tony Ary Borenszweig Wrote:You can already do that: mixin template AdviceX() { int fun(int x) { ... return fun_without_advice(); } } class Foo { mixin AdviceX; int fun_without_advice(int x) { } }
Jan 16 2011
Say you have this: class Bar { int foo() { ... } } And you have your aspect-oriented mixin: mixin template Aspect { int foo() { ... } } and you want to change foo's behaviour. You can't change Bar's source code. How can you change Bar#foo's behaviour like that? At least you have to put the "mixin Aspect!" somewhere. So that means this approach for aspect oriented features doesn't work. What I realized some days ago is that many people here (including me :-P) try to get or have features from other languages, mostly dynamic or "cool" languages, but that won't work here since everything is statically compiled and determined once you compile your code. So you can't later "inject" new funcionality, you can't modify the funcionality of what it is compiled.
Jan 17 2011
Tony <tq tq.tq> wrote:Hi, thanks for your reply but what you suggest is not enough. With your solution you cannot add new advice without breaking stuff elsewhere. You don't want to clutter the namespace with lots of new function names. What you would want is to actually inject the code into the present functions. What would make this even more modular is if you could use the mixin statement outside of the scope that you want to inject into by specifying the location: mixin acme.nuclear.Lollipop SomeAdvice; That way you could extend code without touching its source.D, by its static and compiled nature, does not support what you ask of it. :( There are however ways to do it. First thing that comes to my mind is a template that creates a subclass wherein member functions are wrapped in functions that mixin the wanted functionality. This functionality could then include function pointers or delegates that may be changed at runtime. -- Simen
Jan 17 2011