digitalmars.D - Sick proposal!
- h3r3tic (37/37) Jul 30 2004 Ok, call me insane, but I think it would be really nice to have
- h3r3tic (8/8) Jul 30 2004 actually it would be better to follow the class way:
- Ant (6/33) Jul 30 2004 An IDE for D could easely add and remove the print outs and/or
- h3r3tic (15/17) Jul 30 2004 Yeah, I know, but the code gets very clumsy really fast. It's again
- Walter (17/24) Jul 31 2004 It's no problem at all. Write an auto class:
- h3r3tic (3/3) Aug 01 2004 ok, let me try your approach for a second... is there a function in D
- pragma (36/58) Aug 01 2004 Actually just allowing "super()" outside of the constructor would probab...
- h3r3tic (51/78) Aug 01 2004 Yeah, it's even better. Though I'd add a new available block type to the...
- h3r3tic (5/7) Aug 01 2004 Damn. Note to self: first think, then think, then think a lil bit more,
- Regan Heath (29/66) Aug 01 2004 This idea is close to the 'aspect oriented programming' idea, or rather
- Andy Friesen (12/44) Aug 01 2004 From what I can gather, aspects are a bit more general. AspectJ
- Sean Kelly (13/26) Aug 01 2004 I think it could work either way. But AOP is traditionally applied
- h3r3tic (19/23) Aug 01 2004 Yeah, and that's what I'm worried about. That some very *nice* bugs
- Regan Heath (7/31) Aug 01 2004 What do you think of my revised syntax (posted as response to the messag...
- h3r3tic (2/4) Aug 01 2004 I llllove it :)
- Regan Heath (30/56) Aug 01 2004 Doh! I completely forgot about that particular aspect (pun intended) or ...
- Regan Heath (21/65) Aug 01 2004 The only knowledge I have of it came from "Christopher Diggins" article ...
- Nick (32/50) Aug 01 2004 Traces, aspects and what have you... I may be very wrong here, but as I ...
- Regan Heath (8/74) Aug 01 2004 Perhaps.. grab a copy of DrDobbs Journal Aug 2004 and read the article b...
-
Stewart Gordon
(8/14)
Aug 02 2004
- h3r3tic (5/16) Aug 02 2004 that was not the point !(g)... yea, it should've been
Ok, call me insane, but I think it would be really nice to have something along these lines supported in D: functype traced { version (debug) { in { // writefln("Entering ", name); } out { // writefln("Exiting ", name); } except(Object x) { writefln("Exception caught in function ", name); } } } And then write: void foo() traced { } It wouldn't be that hard thing to do, although the parsing rules for functions would have to be altered to support the additional type specifier. The in and out blocks could actually be added to the function's in and out blocks and if any except block was defined in the functype, the function could be wrapped in a try block and then the exceptions could be handled. name would be replaced by the function name, in this one case, "foo". Moreover, the functype thingie might also take some optional parameters. Probably not a 1.0 thing though ;) but I can see no other way to have nice traces of where an error has occured (unless we get nice stack traces) and this could prove to be useful after all. If I don't get a similar feature or stack traces that can nicely print a function call tree, I'm writing a preprocessor for D. There are so many cool things that can be done with it that sometimes the lack of a preprocessor in D is a real hit...
Jul 30 2004
actually it would be better to follow the class way: void foo() : traced { } that way, there could be a list of functype's, like void foo() : traced, logged("myLog.txt") { }
Jul 30 2004
On Sat, 31 Jul 2004 02:00:26 +0200, h3r3tic wrote:Ok, call me insane, but I think it would be really nice to have something along these lines supported in D: functype traced { version (debug) { in { // writefln("Entering ", name); } out { // writefln("Exiting ", name); } except(Object x) { writefln("Exception caught in function ", name); } } } And then write: void foo() traced { }An IDE for D could easely add and remove the print outs and/or the in and out blocks. Ant my editor for D: http://leds.sourceforge.net
Jul 30 2004
An IDE for D could easely add and remove the print outs and/or the in and out blocks.Yeah, I know, but the code gets very clumsy really fast. It's again about hiding the implementation, so I can just say: void foo() : traced { ... } instead e.g. void foo() { debug { auto CallTrace trace__ = new CallTrace("foo"); } ... } I think the first one is more eye-friendly
Jul 30 2004
"h3r3tic" <h3r3tic dev.null> wrote in message news:ceeufl$e8n$1 digitaldaemon.com...Probably not a 1.0 thing though ;) but I can see no other way to have nice traces of where an error has occured (unless we get nice stack traces) and this could prove to be useful after all. If I don't get a similar feature or stack traces that can nicely print a function call tree, I'm writing a preprocessor for D. There are so many cool things that can be done with it that sometimes the lack of a preprocessor in D is a real hit...It's no problem at all. Write an auto class: auto class Tracer { char[] name; this(char[] name) { this.name = name; fwriteln("entry ", name); } ~this() { fwriteln("exit ", name); } } And use it like: void foo() { Tracer T = new Tracer("foo"); ... } You can add some complexity to it to track the stack frames. Or, you can compile with -gt and look at how the trace code figures it out. www.digitalmars.com/ctg/trace.html
Jul 31 2004
ok, let me try your approach for a second... is there a function in D which checks if an exception has been thrown ? like the uncaught_exception() in c++ ?
Aug 01 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++ ?
Aug 01 2004
Walter wrote:"h3r3tic" <h3r3tic dev.null> wrote in message news:ceii92$1vk7$1 digitaldaemon.com...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()... :/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++ ?
Aug 01 2004
In article <ceeufl$e8n$1 digitaldaemon.com>, h3r3tic says...Ok, call me insane, but I think it would be really nice to have something along these lines supported in D: functype traced { version (debug) { in { // writefln("Entering ", name); } out { // writefln("Exiting ", name); } except(Object x) { writefln("Exception caught in function ", name); } } } And then write: void foo() traced { }Actually just allowing "super()" outside of the constructor would probably be all that's needed to get this to work inside classes. Its still an interesting idea, but wouldn't this work better if it were treated like class inheritance? void baseFunction() in{ writefln("base in"); } body{ writefln("base body"); } out{ writefln("base out"); } // concreteFunction "inherits" baseMethod void concreteFunction(): baseFunction in{ writefln("concrete in"); } body{ super(); writefln("concrete body"); } out{ writefln("concrete out"); } // test void main(){ concreteFunction(); } Which would generate the output: base in concrete in base body (via opional call to super()) concrete body base out concrete out It'd be interesting to see what someone could do if this syntax were allowed to "rewire" a class' v-table by specifying overrides on a method-by-method basis. (I'd imagine the result to be a gross perversion of D's method inheritance rules) I'd also reckon that Typeinfo would have to go through some contortions to allow a method's inheritance to be discovered. Is D's stack tracing code (+gt) in phobos at all, or is this done inside the compiler only? If phobos could also contain an implicit base method/function much like Object is for classes, that utilizes this mechanism, could that feature be more easily maintained? - Pragma
Aug 01 2004
pragma <EricAnderton at yahoo dot com> wrote:Its still an interesting idea, but wouldn't this work better if it were treated like class inheritance? void baseFunction() in{ writefln("base in"); } body{ writefln("base body"); } out{ writefln("base out"); } // concreteFunction "inherits" baseMethod void concreteFunction(): baseFunction in{ writefln("concrete in"); } body{ super(); writefln("concrete body"); } out{ writefln("concrete out"); } // test void main(){ concreteFunction(); } Which would generate the output: base in concrete in base body (via opional call to super()) concrete body base out concrete outYeah, it's even better. Though I'd add a new available block type to the design by contract thingie for functions, so that one could do: void foo() in { ... } out { ... } body { ... } catch(...) {...} on the whole function level so that exception handling could be inherited as well. Let me now write some hypothetical "D with function inheritance code" void guarded() body { } catch(Exception err) { writefln("Exception caught in func ", thisfunc.name); throw; } void foo() : guarded { bar(); } void bar() : guarded { throw Exception("FUBAR"); } void main() { try { foo(); } catch(Exception err) { writefln(err); // here typeinfos are repaired so I don't have to type err.toString() ;) } } Which would produce: Exception caught in func bar Exception caught in func foo Exception <- or whatever Exception.toString() produces Hmmmmmm... wouldn't function inheritance be the great one feature that other languages don't have ? How to do it ? I'm not a compiler writer buy in my opinion, Python's approach is nice: def foo(): some code the def statement just creates a new object whose opCall is set to execute the code given. This could work more or less the same in D. Any oppinions/comments/flames/bitchslaps ?
Aug 01 2004
Hmmmmmm... wouldn't function inheritance be the great one feature that other languages don't have ?Damn. Note to self: first think, then think, then think a lil bit more, ONLY then post here... This couldn't be a killer feature. There isn't too much to inherit but the DbC blocks (+ the proposed throw block) so it would rather be an extension to the DbC, not a killer... sorry ;)
Aug 01 2004
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) Regan On Sat, 31 Jul 2004 02:00:26 +0200, h3r3tic <h3r3tic dev.null> wrote:Ok, call me insane, but I think it would be really nice to have something along these lines supported in D: functype traced { version (debug) { in { // writefln("Entering ", name); } out { // writefln("Exiting ", name); } except(Object x) { writefln("Exception caught in function ", name); } } } And then write: void foo() traced { } It wouldn't be that hard thing to do, although the parsing rules for functions would have to be altered to support the additional type specifier. The in and out blocks could actually be added to the function's in and out blocks and if any except block was defined in the functype, the function could be wrapped in a try block and then the exceptions could be handled. name would be replaced by the function name, in this one case, "foo". Moreover, the functype thingie might also take some optional parameters. Probably not a 1.0 thing though ;) but I can see no other way to have nice traces of where an error has occured (unless we get nice stack traces) and this could prove to be useful after all. If I don't get a similar feature or stack traces that can nicely print a function call tree, I'm writing a preprocessor for D. There are so many cool things that can be done with it that sometimes the lack of a preprocessor in D is a real hit...-- Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/
Aug 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
Aug 01 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
Aug 01 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 ;)
Aug 01 2004
On Mon, 02 Aug 2004 02:25:05 +0200, h3r3tic <h3r3tic dev.null> wrote:Sean Kelly wrote:What do you think of my revised syntax (posted as response to the message this is also a response to).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 ;):) Regan. -- Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/
Aug 01 2004
Regan Heath wrote:What do you think of my revised syntax (posted as response to the message this is also a response to).I llllove it :)
Aug 01 2004
On Sun, 01 Aug 2004 17:09:15 -0700, Sean Kelly <sean f4.ca> wrote:Andy Friesen wrote: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.. } }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 :)-- Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/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
Aug 01 2004
On Sun, 01 Aug 2004 16:34:02 -0700, Andy Friesen <andy ikagames.com> wrote:Regan Heath wrote: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/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. ;)
Aug 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 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 { } }
Aug 01 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. ReganI liked Walters proposal of using an auto class. With for example a variadic constructor you could do something like 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...-- Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/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 { } }
Aug 01 2004
h3r3tic wrote:Ok, call me insane, but I think it would be really nice to have something along these lines supported in D: functype traced { version (debug)<snip> That would be no good. debug is a keyword. Which you should be using for debugging code, not version. Stewart. -- My e-mail is valid but not my primary mailbox. Please keep replies on the 'group where everyone may benefit.
Aug 02 2004
Stewart Gordon wrote:h3r3tic wrote:that was not the point !(g)... yea, it should've been debug { ... }functype traced { version (debug)<snip> That would be no good. debug is a keyword. Which you should be using for debugging code, not version.
Aug 02 2004