August 01, 2004
Regan Heath wrote:

> This idea is close to the 'aspect oriented programming' idea, or rather with a little extending could be used for aspect oriented programming.
> 
> The idea behind aspect oriented programming is that you take an aspect like logging or locking or .., write it once, and apply it to specified methods of a class.
> 
> Example:
> 
> aspect LockingAspect {
>   void onEnter() {
>     ..lock...
>   }
>   void onLeave() {
>     ..unlock..
>   }
> }
> 
> class Foo {
>   void fooBar() : LockingAspect {
>   }
> }
> 
> so onEnter is called when fooBar is called, and onLeave is called when it returns (and when an exception is throw).
> 
> The above is an idea of the syntax that could be used. In addition I am no expert on aspect oriented programming and what I have said above is off the top of my head.
> 
> As you have discovered it's impossible to implement without a preprocessor (or compiler support)

From what I can gather, aspects are a bit more general.  AspectJ implements them as a sort of subset of the Lisp macro concept: the programmer writes little bits of code (which form a unit called an aspect) which can be attached to classes, which attaches code before/after/within methods that match certain criteria, and so forth.

(for instance, your LockingAspect would instead be applied to a whole class, and could automatically perform the proper locking actions before and after any public method call, when an exception is thrown, and so forth)

I'm no expert myself, mind you, so a grain (or truckload) of salt is a good idea. ;)

 -- andy
August 01, 2004
Traces, aspects and what have you... I may be very wrong here, but as I see it the only proposed use for all this is to have a special event happen at the beginning and at the end of function calls. Isn't this a lot of structural and linguistic baggage to add just to accomplish this single purpose?

I liked Walters proposal of using an auto class. With for example a variadic constructor you could do something like

# class Someclass
# {
#   void foo(int arg1, char[] arg2)
#   {
#      // Log function call
#      auto Tracer = new Tracer("Someclass.foo", arg1, arg2);
#
#      ...

Since most of the other proposed methods require you to mark functions in one way or another anyway, I don't see this as too much to type.

I've done something similar in C++ once, coupled with an independant class which kept track of the function "stack" (it didn't touch the actual stack) this way. Also all exception classes I used would capture a local copy of the this stack and use this to produce an error message of the form

main
foo1
foo2 <-- caught here
foo3
foo4 <-- thrown here

Also, more importantly, the "stack" class also caught uncaught exceptions like a GPF (this was Windows) and displayed a trace. I swear this must have reduced my bug hunting time by at least a factor of 10 ;-)

Doing this in D would effectively require fixing up the Exception class though, so it would have to be part of phobos.

Nick

In article <opsb2r21w95a2sq9@digitalmars.com>, Regan Heath says...
>
>This idea is close to the 'aspect oriented programming' idea, or rather with a little extending could be used for aspect oriented programming.
>
>The idea behind aspect oriented programming is that you take an aspect like logging or locking or .., write it once, and apply it to specified methods of a class.
>
>Example:
>
>aspect LockingAspect {
>   void onEnter() {
>     ..lock...
>   }
>   void onLeave() {
>     ..unlock..
>   }
>}
>
>class Foo {
>   void fooBar() : LockingAspect {
>   }
>}


August 02, 2004
Andy Friesen wrote:
> 
>  From what I can gather, aspects are a bit more general.  AspectJ implements them as a sort of subset of the Lisp macro concept: the programmer writes little bits of code (which form a unit called an aspect) which can be attached to classes, which attaches code before/after/within methods that match certain criteria, and so forth.
> 
> (for instance, your LockingAspect would instead be applied to a whole class, and could automatically perform the proper locking actions before and after any public method call, when an exception is thrown, and so forth)

I think it could work either way.  But AOP is traditionally applied entirely separately from the original class (which is why it's so powerful).  Like say you have this structure:

void foo() {}
void bar() { foo(); }

You could use AOP to define code that should be run before and after foo is called without ever modifying the code for foo.  A very powerful technique and one which I think has tremendous potential to ease maintenance and confuse the heck out of people trying to decipher code :)

> I'm no expert myself, mind you, so a grain (or truckload) of salt is a good idea. ;)

Same here.  I've read papers on it but never used it, as I don't do much programming in Java (and AspectC++ is kinda half-baked).


Sean
August 02, 2004
Sean Kelly wrote:
> You could use AOP to define code that should be run before and after foo is called without ever modifying the code for foo.  A very powerful technique and one which I think has tremendous potential to ease maintenance and confuse the heck out of people trying to decipher code :)

Yeah, and that's what I'm worried about. That some very *nice* bugs might result from this. Not knowing about an aspect messing with you somewhere around could be a real PITA. That's why I'd rather specify explicitly that an aspect is being used somewhere with the notation void foo() : bar, where bar is the aspect. This would probably be seen well by people who are concerned by the performance of their code.
Moreover, not using the wildcard - style of function matching (the explicit way) would surely be easier to implement. Yet another D's design choice is met :)


And no, I wouldn't like writing:
debug auto Tracer T = new Tracer("foo()", bar);

for every function that I wanted use the 'aspect'. Imagine changing the Tracer's interface after you've made a hundred functions use it. Hell... and one of the reasons AOP has emerged in the first way. IMO, it wouldn't be that bad to add these ': traced' or whatever else to the function and never care about it.

this.not an expert
this.only read papers ;)
August 02, 2004
"h3r3tic" <h3r3tic@dev.null> wrote in message news:ceii92$1vk7$1@digitaldaemon.com...
> ok, let me try your approach for a second... is there a function in D which checks if an exception has been thrown ?

No, but there is the catch() statement.

> like the
> uncaught_exception() in c++ ?


August 02, 2004
On Sun, 01 Aug 2004 16:34:02 -0700, Andy Friesen <andy@ikagames.com> wrote:

> Regan Heath wrote:
>
>> This idea is close to the 'aspect oriented programming' idea, or rather with a little extending could be used for aspect oriented programming.
>>
>> The idea behind aspect oriented programming is that you take an aspect like logging or locking or .., write it once, and apply it to specified methods of a class.
>>
>> Example:
>>
>> aspect LockingAspect {
>>   void onEnter() {
>>     ..lock...
>>   }
>>   void onLeave() {
>>     ..unlock..
>>   }
>> }
>>
>> class Foo {
>>   void fooBar() : LockingAspect {
>>   }
>> }
>>
>> so onEnter is called when fooBar is called, and onLeave is called when it returns (and when an exception is throw).
>>
>> The above is an idea of the syntax that could be used. In addition I am no expert on aspect oriented programming and what I have said above is off the top of my head.
>>
>> As you have discovered it's impossible to implement without a preprocessor (or compiler support)
>
>  From what I can gather, aspects are a bit more general.  AspectJ implements them as a sort of subset of the Lisp macro concept: the programmer writes little bits of code (which form a unit called an aspect) which can be attached to classes, which attaches code before/after/within methods that match certain criteria, and so forth.
>
> (for instance, your LockingAspect would instead be applied to a whole class, and could automatically perform the proper locking actions before and after any public method call, when an exception is thrown, and so forth)
>
> I'm no expert myself, mind you, so a grain (or truckload) of salt is a good idea. ;)

The only knowledge I have of it came from "Christopher Diggins" article in the August 2004 DrDobbs Journal. In it he described a thing called a 'Point Cut' which defined the methods to apply the Aspect to.

I think being able to apply certain Aspects to specified methods give awesome flexibility eg.

aspect Locking {
}

aspect Logging {
}

cass Foo {
  void Bar() : Locking {
  }
  void Baz() : Logging {
  }
}

so both aspects are used, Locking for Bar and Logging for Baz.

In fact the more I look at this syntax the more I like it.

Regan.

-- 
Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/
August 02, 2004
On Sun, 01 Aug 2004 17:09:15 -0700, Sean Kelly <sean@f4.ca> wrote:
> Andy Friesen wrote:
>>
>>  From what I can gather, aspects are a bit more general.  AspectJ implements them as a sort of subset of the Lisp macro concept: the programmer writes little bits of code (which form a unit called an aspect) which can be attached to classes, which attaches code before/after/within methods that match certain criteria, and so forth.
>>
>> (for instance, your LockingAspect would instead be applied to a whole class, and could automatically perform the proper locking actions before and after any public method call, when an exception is thrown, and so forth)
>
> I think it could work either way.  But AOP is traditionally applied entirely separately from the original class (which is why it's so powerful).  Like say you have this structure:
>
> void foo() {}
> void bar() { foo(); }
>
> You could use AOP to define code that should be run before and after foo is called without ever modifying the code for foo.  A very powerful technique and one which I think has tremendous potential to ease maintenance and confuse the heck out of people trying to decipher code :)

Doh! I completely forgot about that particular aspect (pun intended) or it.
To revise my syntax...

aspect Locking {
  onBefore()       {..etc..}
  onAfter()        {..etc..}
  onProceedQuery() {..etc..}
  onException()    {..etc..}
  onFincally()     {..etc..}
}

aspect Logging {
  onBefore()       {..etc..}
  onAfter()        {..etc..}
  onProceedQuery() {..etc..}
  onException()    {..etc..}
  onFincally()     {..etc..}
}

class originalFoo {
  void Foo() {..etc..}
  void Bar() {..etc..}
}

class derivedFoo : originalFoo {
  void Foo() : Locking;   //apply Locking, keep base class function
  void Bar() : Logging {  //apply logging, override base class function
    super.Bar();
    ..etc..
  }
}

>> I'm no expert myself, mind you, so a grain (or truckload) of salt is a good idea. ;)
>
> Same here.  I've read papers on it but never used it, as I don't do much programming in Java (and AspectC++ is kinda half-baked).
>
>
> Sean



-- 
Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/
August 02, 2004
On Mon, 02 Aug 2004 02:25:05 +0200, h3r3tic <h3r3tic@dev.null> wrote:
> Sean Kelly wrote:
>> You could use AOP to define code that should be run before and after foo is called without ever modifying the code for foo.  A very powerful technique and one which I think has tremendous potential to ease maintenance and confuse the heck out of people trying to decipher code :)
>
> Yeah, and that's what I'm worried about. That some very *nice* bugs might result from this. Not knowing about an aspect messing with you somewhere around could be a real PITA. That's why I'd rather specify explicitly that an aspect is being used somewhere with the notation void foo() : bar, where bar is the aspect. This would probably be seen well by people who are concerned by the performance of their code.
> Moreover, not using the wildcard - style of function matching (the explicit way) would surely be easier to implement. Yet another D's design choice is met :)

What do you think of my revised syntax (posted as response to the message this is also a response to).

> And no, I wouldn't like writing:
> debug auto Tracer T = new Tracer("foo()", bar);
>
> for every function that I wanted use the 'aspect'. Imagine changing the Tracer's interface after you've made a hundred functions use it. Hell... and one of the reasons AOP has emerged in the first way. IMO, it wouldn't be that bad to add these ': traced' or whatever else to the function and never care about it.
>
> this.not an expert
> this.only read papers ;)

:)

Regan.

-- 
Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/
August 02, 2004
Walter wrote:
> "h3r3tic" <h3r3tic@dev.null> wrote in message
> news:ceii92$1vk7$1@digitaldaemon.com...
> 
>>ok, let me try your approach for a second... is there a function in D
>>which checks if an exception has been thrown ?
> 
> 
> No, but there is the catch() statement.
> 
> 
>>like the
>>uncaught_exception() in c++ ?

then do this:

auto class Foo()
{
    ~this()
    {
        catch(Exception blah)
        {
            writefln("exc caught");
        }
    }
}

void bar()
{
    auto Foo X = new Foo;
    throw Exception("geez");
}

void main()
{
    bar();
}

and see what happens

I REALLY meant an utility with the functionality of uncaught_exception()...  :/
August 02, 2004
On Sun, 1 Aug 2004 23:35:12 +0000 (UTC), Nick <Nick_member@pathlink.com> wrote:
> Traces, aspects and what have you... I may be very wrong here, but as I see it
> the only proposed use for all this is to have a special event happen at the
> beginning and at the end of function calls. Isn't this a lot of structural and
> linguistic baggage to add just to accomplish this single purpose?

Perhaps.. grab a copy of DrDobbs Journal Aug 2004 and read the article by Christopher Diggins, that's all I have read on the subject, and my impression is that it could be quite useful.

Regan

> I liked Walters proposal of using an auto class. With for example a variadic
> constructor you could do something like
>
> # class Someclass
> # {
> #   void foo(int arg1, char[] arg2)
> #   {
> #      // Log function call
> #      auto Tracer = new Tracer("Someclass.foo", arg1, arg2);
> #
> #      ...
>
> Since most of the other proposed methods require you to mark functions in one
> way or another anyway, I don't see this as too much to type.
>
> I've done something similar in C++ once, coupled with an independant class which
> kept track of the function "stack" (it didn't touch the actual stack) this way.
> Also all exception classes I used would capture a local copy of the this stack
> and use this to produce an error message of the form
>
> main
> foo1
> foo2 <-- caught here
> foo3
> foo4 <-- thrown here
>
> Also, more importantly, the "stack" class also caught uncaught exceptions like a
> GPF (this was Windows) and displayed a trace. I swear this must have reduced my
> bug hunting time by at least a factor of 10 ;-)
>
> Doing this in D would effectively require fixing up the Exception class though,
> so it would have to be part of phobos.
>
> Nick
>
> In article <opsb2r21w95a2sq9@digitalmars.com>, Regan Heath says...
>>
>> This idea is close to the 'aspect oriented programming' idea, or rather
>> with a little extending could be used for aspect oriented programming.
>>
>> The idea behind aspect oriented programming is that you take an aspect
>> like logging or locking or .., write it once, and apply it to specified
>> methods of a class.
>>
>> Example:
>>
>> aspect LockingAspect {
>>   void onEnter() {
>>     ..lock...
>>   }
>>   void onLeave() {
>>     ..unlock..
>>   }
>> }
>>
>> class Foo {
>>   void fooBar() : LockingAspect {
>>   }
>> }
>
>



-- 
Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/