Jump to page: 1 2
Thread overview
Class Type Parameters
Jan 17, 2008
bearophile
Jan 17, 2008
doob
Jan 21, 2008
Christopher Wright
Jan 21, 2008
naryl
January 17, 2008
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
January 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
January 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

January 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:
> 
>> 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
> 


I think you can, look here: http://www.digitalmars.com/d/1.0/template.html under Specialization
January 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).


January 21, 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).
> 
> 

January 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).
> > 
> > 
> 

January 21, 2008
Hans-Eric Grönlund wrote:
>> 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!

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.
January 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 ;)


January 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?
« First   ‹ Prev
1 2