digitalmars.D.learn - Class Type Parameters
- =?ISO-8859-1?Q?Hans-Eric_Gr=f6nlund?= (4/4) Jan 17 2008 How could I declare a class type parameter in D? I'd like to be able to ...
- bearophile (17/21) Jan 17 2008 Do you mean something like this?
- =?ISO-8859-1?Q?Hans-Eric_Gr=f6nlund?= (13/41) Jan 17 2008 Cool, not exactly what I was looking for, but I can use it to solve the ...
- doob (3/52) Jan 17 2008 I think you can, look here:
- Jarrett Billingsley (14/28) Jan 17 2008 Depends on what you want to do. Do you want to do compile-time stuff? ...
- =?ISO-8859-1?Q?Hans-Eric_Gr=f6nlund?= (10/47) Jan 21 2008 Ah, you're right. I should have been more specific.
- =?ISO-8859-1?Q?Hans-Eric_Gr=f6nlund?= (3/64) Jan 21 2008 I of course meant
- Christopher Wright (14/40) Jan 21 2008 Closest you could come, if you really didn't want to use a template, is:
- Jarrett Billingsley (20/32) Jan 21 2008 The only possible issue I could see with that would be if an exception w...
- naryl (3/7) Jan 21 2008 Isn't _d_dynamic_cast implementation specific?
- Jarrett Billingsley (3/10) Jan 21 2008 Probably. :\
- =?ISO-8859-1?Q?Hans-Eric_Gr=f6nlund?= (2/46) Jan 23 2008
- Jarrett Billingsley (52/57) Jan 24 2008 :D
How could I declare a class type parameter in D? I'd like to be able to do something like this: do_something_with_class(SomeClass); How would I declare the do_something_with_class function? Thank you on beforehand
Jan 17 2008
Hans-Eric Grönlund:How could I declare a class type parameter in D? I'd like to be able to do something like this: do_something_with_class(SomeClass); How would I declare the do_something_with_class function?Do you mean something like this? import std.stdio; class C1 { int i; } class C2 { float f; } void manage(TyClass)() { auto c = new TyClass; writefln(c); } void main() { manage!(C1); manage!(C2)(); } Note that manage is a templated function. D types seem almost first-class things, so you can manage them, with care. Bye, bearophile
Jan 17 2008
Cool, not exactly what I was looking for, but I can use it to solve the problem - a little differently than I'd expected. Just out of curiosity: In Delphi (Object Pascal) one can assign a class type to a variable, like so: type TAClass = class ... end; TAClassClass = class of TAClass; procedure do_something_with_class(AClass: TAClassClass); begin ... end; Can something similar be done in D? bearophile Wrote:Hans-Eric Grönlund:How could I declare a class type parameter in D? I'd like to be able to do something like this: do_something_with_class(SomeClass); How would I declare the do_something_with_class function?Do you mean something like this? import std.stdio; class C1 { int i; } class C2 { float f; } void manage(TyClass)() { auto c = new TyClass; writefln(c); } void main() { manage!(C1); manage!(C2)(); } Note that manage is a templated function. D types seem almost first-class things, so you can manage them, with care. Bye, bearophile
Jan 17 2008
Hans-Eric Grönlund wrote:Cool, not exactly what I was looking for, but I can use it to solve the problem - a little differently than I'd expected. Just out of curiosity: In Delphi (Object Pascal) one can assign a class type to a variable, like so: type TAClass = class ... end; TAClassClass = class of TAClass; procedure do_something_with_class(AClass: TAClassClass); begin ... end; Can something similar be done in D? bearophile Wrote:I think you can, look here: http://www.digitalmars.com/d/1.0/template.html under SpecializationHans-Eric Grönlund:How could I declare a class type parameter in D? I'd like to be able to do something like this: do_something_with_class(SomeClass); How would I declare the do_something_with_class function?Do you mean something like this? import std.stdio; class C1 { int i; } class C2 { float f; } void manage(TyClass)() { auto c = new TyClass; writefln(c); } void main() { manage!(C1); manage!(C2)(); } Note that manage is a templated function. D types seem almost first-class things, so you can manage them, with care. Bye, bearophile
Jan 17 2008
"Hans-Eric Grönlund" <hasse42g gmail.com> wrote in message news:fmnv6b$1hi6$1 digitalmars.com...Cool, not exactly what I was looking for, but I can use it to solve the problem - a little differently than I'd expected. Just out of curiosity: In Delphi (Object Pascal) one can assign a class type to a variable, like so: type TAClass = class ... end; TAClassClass = class of TAClass; procedure do_something_with_class(AClass: TAClassClass); begin ... end; Can something similar be done in D?Depends on what you want to do. Do you want to do compile-time stuff? Then templates are the way to go. Do you want to something at runtime with the class? Then RTTI is the way to go. typeid(AnyTypeReally) gets you an instance of the TypeInfo class which is automatically generated for every type in your program. Runtime introspection and stuff is currently really weak in D, since the compile-time stuff is (usually) sufficient, more expressive, and faster. "What do you want to _do_?" is probably the most important question here. Asking how to mechanically translate a piece of code from another language into D is not necessarily the best way to go about it, especially if the source language is one that not many people have experience with (Delphi is _reasonably_ popular but I doubt many people here have used it).
Jan 17 2008
Ah, you're right. I should have been more specific. What I wanted to do was to imitate a ruby-method that accepts a code block, runs it and retries n times if an exception is thrown. Like the ruby-method, I wanted to let the user decide what type of exception to catch by giving it as an argument. I explain it in more detail on my weblog: http://www.hans-eric.com/2008/01/17/loop-abstractions-in-d/ For that reason, I guess the compile time solution (templates) is to prefer in this case, although as a user of the function, I would have preferred a non-template syntax. Like this retryable(SomeExceptionClass, args...); over this retryable(SomeExceptionClass)!(args...); Cheers! Jarrett Billingsley Wrote:"Hans-Eric Grönlund" <hasse42g gmail.com> wrote in message news:fmnv6b$1hi6$1 digitalmars.com...Cool, not exactly what I was looking for, but I can use it to solve the problem - a little differently than I'd expected. Just out of curiosity: In Delphi (Object Pascal) one can assign a class type to a variable, like so: type TAClass = class ... end; TAClassClass = class of TAClass; procedure do_something_with_class(AClass: TAClassClass); begin ... end; Can something similar be done in D?Depends on what you want to do. Do you want to do compile-time stuff? Then templates are the way to go. Do you want to something at runtime with the class? Then RTTI is the way to go. typeid(AnyTypeReally) gets you an instance of the TypeInfo class which is automatically generated for every type in your program. Runtime introspection and stuff is currently really weak in D, since the compile-time stuff is (usually) sufficient, more expressive, and faster. "What do you want to _do_?" is probably the most important question here. Asking how to mechanically translate a piece of code from another language into D is not necessarily the best way to go about it, especially if the source language is one that not many people have experience with (Delphi is _reasonably_ popular but I doubt many people here have used it).
Jan 21 2008
retryable(SomeExceptionClass)!(args...);I of course meant retryable!(SomeExceptionClass)(args...); Hans-Eric Grönlund Wrote:Ah, you're right. I should have been more specific. What I wanted to do was to imitate a ruby-method that accepts a code block, runs it and retries n times if an exception is thrown. Like the ruby-method, I wanted to let the user decide what type of exception to catch by giving it as an argument. I explain it in more detail on my weblog: http://www.hans-eric.com/2008/01/17/loop-abstractions-in-d/ For that reason, I guess the compile time solution (templates) is to prefer in this case, although as a user of the function, I would have preferred a non-template syntax. Like this retryable(SomeExceptionClass, args...); over this retryable(SomeExceptionClass)!(args...); Cheers! Jarrett Billingsley Wrote:"Hans-Eric Grönlund" <hasse42g gmail.com> wrote in message news:fmnv6b$1hi6$1 digitalmars.com...Cool, not exactly what I was looking for, but I can use it to solve the problem - a little differently than I'd expected. Just out of curiosity: In Delphi (Object Pascal) one can assign a class type to a variable, like so: type TAClass = class ... end; TAClassClass = class of TAClass; procedure do_something_with_class(AClass: TAClassClass); begin ... end; Can something similar be done in D?Depends on what you want to do. Do you want to do compile-time stuff? Then templates are the way to go. Do you want to something at runtime with the class? Then RTTI is the way to go. typeid(AnyTypeReally) gets you an instance of the TypeInfo class which is automatically generated for every type in your program. Runtime introspection and stuff is currently really weak in D, since the compile-time stuff is (usually) sufficient, more expressive, and faster. "What do you want to _do_?" is probably the most important question here. Asking how to mechanically translate a piece of code from another language into D is not necessarily the best way to go about it, especially if the source language is one that not many people have experience with (Delphi is _reasonably_ popular but I doubt many people here have used it).
Jan 21 2008
Hans-Eric Grönlund wrote:Closest you could come, if you really didn't want to use a template, is: void retryable(ClassInfo info, int times, void delegate() totry) { for (int i = 0; i < times; i++) { try { totry(); break; } catch (Exception e) { if (e.classinfo is info) continue; else throw e; } } } retryable(AbandonedMutexException.classinfo, 5, {writefln("Hi!");}); Typeid wouldn't work; it goes by the declared type, IIRC.retryable(SomeExceptionClass)!(args...);I of course meant retryable!(SomeExceptionClass)(args...); Hans-Eric Grönlund Wrote:Ah, you're right. I should have been more specific. What I wanted to do was to imitate a ruby-method that accepts a code block, runs it and retries n times if an exception is thrown. Like the ruby-method, I wanted to let the user decide what type of exception to catch by giving it as an argument. I explain it in more detail on my weblog: http://www.hans-eric.com/2008/01/17/loop-abstractions-in-d/ For that reason, I guess the compile time solution (templates) is to prefer in this case, although as a user of the function, I would have preferred a non-template syntax. Like this retryable(SomeExceptionClass, args...); over this retryable(SomeExceptionClass)!(args...); Cheers!
Jan 21 2008
"Christopher Wright" <dhasenan gmail.com> wrote in message news:fn2bqa$25rl$1 digitalmars.com...Closest you could come, if you really didn't want to use a template, is: void retryable(ClassInfo info, int times, void delegate() totry) { for (int i = 0; i < times; i++) { try { totry(); break; } catch (Exception e) { if (e.classinfo is info) continue; else throw e; } } } retryable(AbandonedMutexException.classinfo, 5, {writefln("Hi!");});The only possible issue I could see with that would be if an exception were thrown that was derived from the type that you passed in, which, according to normal exception behavior, should still be caught. What you have to do then is perform a dynamic cast. There's no syntax for this, but you can hack around with some of the runtime functions to do the same thing. Place: extern(C) Object _d_dynamic_cast(Object o, ClassInfo c); somewhere in your module, then in the catch clause of retryable: catch(Exception e) { if(_d_dynamic_cast(e, info)) continue; else throw e; } That _should_ work. It's doing the same thing as the cast operator would but without the pretty syntax. Also, this function would be a great place to use a lazy void parameter for the toTry parameter ;)
Jan 21 2008
On Mon, 21 Jan 2008 18:57:34 +0300, Jarrett Billingsley <kb3ctd2 yahoo.com> wrote:if(_d_dynamic_cast(e, info)) continue; else throw e;Isn't _d_dynamic_cast implementation specific?
Jan 21 2008
"naryl" <cy ngs.ru> wrote in message news:op.t5auwulcqr3u58 iriwka...On Mon, 21 Jan 2008 18:57:34 +0300, Jarrett Billingsley <kb3ctd2 yahoo.com> wrote:Probably. :\ But it at least exists in both phobos and Tango.if(_d_dynamic_cast(e, info)) continue; else throw e;Isn't _d_dynamic_cast implementation specific?
Jan 21 2008
Also, this function would be a great place to use a lazy void parameter for the toTry parameter ;)Pardon me for being ignorant, but could you elaborate a little on this subject? Jarrett Billingsley Wrote:"Christopher Wright" <dhasenan gmail.com> wrote in message news:fn2bqa$25rl$1 digitalmars.com...Closest you could come, if you really didn't want to use a template, is: void retryable(ClassInfo info, int times, void delegate() totry) { for (int i = 0; i < times; i++) { try { totry(); break; } catch (Exception e) { if (e.classinfo is info) continue; else throw e; } } } retryable(AbandonedMutexException.classinfo, 5, {writefln("Hi!");});The only possible issue I could see with that would be if an exception were thrown that was derived from the type that you passed in, which, according to normal exception behavior, should still be caught. What you have to do then is perform a dynamic cast. There's no syntax for this, but you can hack around with some of the runtime functions to do the same thing. Place: extern(C) Object _d_dynamic_cast(Object o, ClassInfo c); somewhere in your module, then in the catch clause of retryable: catch(Exception e) { if(_d_dynamic_cast(e, info)) continue; else throw e; } That _should_ work. It's doing the same thing as the cast operator would but without the pretty syntax. Also, this function would be a great place to use a lazy void parameter for the toTry parameter ;)
Jan 23 2008
"Hans-Eric Grönlund" <hasse42g gmail.com> wrote in message news:fn9csm$109r$1 digitalmars.com...:D void retryable(ClassInfo info, int times, lazy void totry) { for(int i = 0; i < times; i++) { try { totry(); break; } catch(Exception e) { if(_d_dynamic_cast(e, info)) continue; else throw e; } } } Notice that the body of the function has not changed, we still call totry as a function. Lazy parameters are sort of syntactic sugar. You put "lazy T" on a parameter, it is implicitly a "T delegate()". The magic happens when the function is actually called. With the old version that took a delegate, we had to write: retryable(typeid(Exception), 5, { connectToDB(); }); But lazy parameters allow us to use a normal-looking expression there: retryable(typeid(Exception), 5, connectToDB()); The compiler sees that that's a lazy parameter and implicitly converts it to a delegate literal with that code in it. If you want to have more code in the lazy parameter, it gets a bit tricky: retryable(typeid(Exception), 5, { func1(); func2(); func3(); }()); // <<< notice extra set of parens here! The reason we have to have that extra set of parens is that the compiler will wrap this in another delegate literal, leaving us (internally) with something like: void __temp1() { { func1(); func2(); func3(); }(); } If we don't put the call at the end of the delegate literal, your lazy parameter just defines a function and does nothing else.Also, this function would be a great place to use a lazy void parameter for the toTry parameter ;)Pardon me for being ignorant, but could you elaborate a little on this subject?
Jan 24 2008