February 09, 2011
== Auszug aus Steven Schveighoffer (schveiguy@yahoo.com)'s Artikel
> On Wed, 09 Feb 2011 16:14:04 -0500, useo <useo@start.bg> wrote:
> > I just have a problem with my variables.
> >
> > For example... my class/template just looks like:
> >
> > class Example(T) if (is(T == delegate) || is(T == function))
> > {
> >    T callback;
> >
> >    void setCallback(T cb) {
> >       callback = cb;
> >    }
> >
> > }
> >
> > This means that I need variables like Example!(void function())
> > myVariable. But is there any possibility to use variables like
> > Example myVariable? The template declaration only defines the
type of
> > a callback and perhaps one method-declaration nothing else. I
already
> > tried Example!(void*) because delegates and functions are void pointers but I always get an error. I hope there is any way to do this.
> If I understand you correctly, you don't want to declare the type
of T
> when instantiating the template?  This is not possible, templates
must
> have all parameters defined at instantiation time.
> If you just want a shorter thing to type for Example!(void function
()),
> you can do:
> alias Example!(void function()) MyType;
> MyType myVariable;
> -Steve

Yes, right, I don't want declare the template-type.

Nevertheless... thanks
February 09, 2011
== Auszug aus bearophile (bearophileHUGS@lycos.com)'s Artikel
> useo:
> > I just have a problem with my variables.
> >
> > For example... my class/template just looks like:
> >
> > class Example(T) if (is(T == delegate) || is(T == function))
> > {
> >    T callback;
> >
> >    void setCallback(T cb) {
> >       callback = cb;
> >    }
> >
> > }
> >
> > This means that I need variables like Example!(void function
())
> > myVariable. But is there any possibility to use variables like Example myVariable?
> D is not the SML language, templates are just placeholders. If
you don't instantiate a template, you have only a symbol. Example is only assignable to an alias (and in past, to a typedef):
> alias Example Foo;
> > The template declaration only defines the type of
> > a callback and perhaps one method-declaration nothing else. I
already
> > tried Example!(void*) because delegates and functions are void pointers but I always get an error. I hope there is any way
to do
> > this.
> I don't yet understand what you are trying to do.
> Other notes:
> - What if your T is a functor (a callable class/struct/union
instance that defined opCall)?
> - sizeof of a function pointer is 1 CPU word, while a delegate
is 2 CPU words (and a delegate clojure has stuff on the heap too,
sometimes).
> Bye,
> bearophile

Idea is the following:

class Example(T) if (is(T == delegate) || is(T == function)) {

   T callback;

   void setCallback(T cb) {
      callback = cb;
   }

   void opCall() {
      callback();
   }

}

other file:

import example;

private {

   Example variable;

}

void setExampleVariable(Example ex) {
   variable = ex;
}

void callCurrentExampleVariable() {
   variable();
}
February 09, 2011
On Wed, 09 Feb 2011 16:41:25 -0500, useo <useo@start.bg> wrote:

> == Auszug aus bearophile (bearophileHUGS@lycos.com)'s Artikel
>> useo:
>> > I just have a problem with my variables.
>> >
>> > For example... my class/template just looks like:
>> >
>> > class Example(T) if (is(T == delegate) || is(T == function))
>> > {
>> >    T callback;
>> >
>> >    void setCallback(T cb) {
>> >       callback = cb;
>> >    }
>> >
>> > }
>> >
>> > This means that I need variables like Example!(void function
> ())
>> > myVariable. But is there any possibility to use variables like
>> > Example myVariable?
>> D is not the SML language, templates are just placeholders. If
> you don't instantiate a template, you have only a symbol. Example
> is only assignable to an alias (and in past, to a typedef):
>> alias Example Foo;
>> > The template declaration only defines the type of
>> > a callback and perhaps one method-declaration nothing else. I
> already
>> > tried Example!(void*) because delegates and functions are void
>> > pointers but I always get an error. I hope there is any way
> to do
>> > this.
>> I don't yet understand what you are trying to do.
>> Other notes:
>> - What if your T is a functor (a callable class/struct/union
> instance that defined opCall)?
>> - sizeof of a function pointer is 1 CPU word, while a delegate
> is 2 CPU words (and a delegate clojure has stuff on the heap too,
> sometimes).
>> Bye,
>> bearophile
>
> Idea is the following:
>
> class Example(T) if (is(T == delegate) || is(T == function)) {
>
>    T callback;
>
>    void setCallback(T cb) {
>       callback = cb;
>    }
>
>    void opCall() {
>       callback();
>    }
>
> }
>
> other file:
>
> import example;
>
> private {
>
>    Example variable;
>
> }
>
> void setExampleVariable(Example ex) {
>    variable = ex;
> }
>
> void callCurrentExampleVariable() {
>    variable();
> }

I don't think you want templates.  What you want is a tagged union (and a struct is MUCH better suited for this):

// untested!

struct Example
{
   private
   {
      bool isDelegate;
      union
      {
         void function() fn;
         void delegate() dg;
      }
   }

   void setCallback(void function() f) { this.fn = f; isDelegate = false;}
   void setCallback(void delegate() d) { this.dg = d; isDelegate = true;}

   void opCall()
   {
      if(isDelegate)
         dg();
      else
         fn();
   }
}

-Steve
February 09, 2011
== Auszug aus Steven Schveighoffer (schveiguy@yahoo.com)'s Artikel
> On Wed, 09 Feb 2011 16:41:25 -0500, useo <useo@start.bg> wrote:
> > == Auszug aus bearophile (bearophileHUGS@lycos.com)'s Artikel
> >> useo:
> >> > I just have a problem with my variables.
> >> >
> >> > For example... my class/template just looks like:
> >> >
> >> > class Example(T) if (is(T == delegate) || is(T ==
function))
> >> > {
> >> >    T callback;
> >> >
> >> >    void setCallback(T cb) {
> >> >       callback = cb;
> >> >    }
> >> >
> >> > }
> >> >
> >> > This means that I need variables like Example!(void
function
> > ())
> >> > myVariable. But is there any possibility to use variables
like
> >> > Example myVariable?
> >> D is not the SML language, templates are just placeholders.
If
> > you don't instantiate a template, you have only a symbol.
Example
> > is only assignable to an alias (and in past, to a typedef):
> >> alias Example Foo;
> >> > The template declaration only defines the type of
> >> > a callback and perhaps one method-declaration nothing
else. I
> > already
> >> > tried Example!(void*) because delegates and functions are
void
> >> > pointers but I always get an error. I hope there is any way
> > to do
> >> > this.
> >> I don't yet understand what you are trying to do.
> >> Other notes:
> >> - What if your T is a functor (a callable class/struct/union
> > instance that defined opCall)?
> >> - sizeof of a function pointer is 1 CPU word, while a
delegate
> > is 2 CPU words (and a delegate clojure has stuff on the heap
too,
> > sometimes).
> >> Bye,
> >> bearophile
> >
> > Idea is the following:
> >
> > class Example(T) if (is(T == delegate) || is(T == function)) {
> >
> >    T callback;
> >
> >    void setCallback(T cb) {
> >       callback = cb;
> >    }
> >
> >    void opCall() {
> >       callback();
> >    }
> >
> > }
> >
> > other file:
> >
> > import example;
> >
> > private {
> >
> >    Example variable;
> >
> > }
> >
> > void setExampleVariable(Example ex) {
> >    variable = ex;
> > }
> >
> > void callCurrentExampleVariable() {
> >    variable();
> > }
> I don't think you want templates.  What you want is a tagged
union (and a
> struct is MUCH better suited for this):
> // untested!
> struct Example
> {
>     private
>     {
>        bool isDelegate;
>        union
>        {
>           void function() fn;
>           void delegate() dg;
>        }
>     }
>     void setCallback(void function() f) { this.fn = f;
isDelegate = false;}
>     void setCallback(void delegate() d) { this.dg = d;
isDelegate = true;}
>     void opCall()
>     {
>        if(isDelegate)
>           dg();
>        else
>           fn();
>     }
> }
> -Steve

Looks really interesting and seems to work. Thanks in advance!
February 10, 2011
On 02/09/2011 11:05 PM, Steven Schveighoffer wrote:
> On Wed, 09 Feb 2011 16:41:25 -0500, useo <useo@start.bg> wrote:
>
>> == Auszug aus bearophile (bearophileHUGS@lycos.com)'s Artikel
>>> useo:
>>> > I just have a problem with my variables.
>>> >
>>> > For example... my class/template just looks like:
>>> >
>>> > class Example(T) if (is(T == delegate) || is(T == function))
>>> > {
>>> > T callback;
>>> >
>>> > void setCallback(T cb) {
>>> > callback = cb;
>>> > }
>>> >
>>> > }
>>> >
>>> > This means that I need variables like Example!(void function
>> ())
>>> > myVariable. But is there any possibility to use variables like
>>> > Example myVariable?
>>> D is not the SML language, templates are just placeholders. If
>> you don't instantiate a template, you have only a symbol. Example
>> is only assignable to an alias (and in past, to a typedef):
>>> alias Example Foo;
>>> > The template declaration only defines the type of
>>> > a callback and perhaps one method-declaration nothing else. I
>> already
>>> > tried Example!(void*) because delegates and functions are void
>>> > pointers but I always get an error. I hope there is any way
>> to do
>>> > this.
>>> I don't yet understand what you are trying to do.
>>> Other notes:
>>> - What if your T is a functor (a callable class/struct/union
>> instance that defined opCall)?
>>> - sizeof of a function pointer is 1 CPU word, while a delegate
>> is 2 CPU words (and a delegate clojure has stuff on the heap too,
>> sometimes).
>>> Bye,
>>> bearophile
>>
>> Idea is the following:
>>
>> class Example(T) if (is(T == delegate) || is(T == function)) {
>>
>> T callback;
>>
>> void setCallback(T cb) {
>> callback = cb;
>> }
>>
>> void opCall() {
>> callback();
>> }
>>
>> }
>>
>> other file:
>>
>> import example;
>>
>> private {
>>
>> Example variable;
>>
>> }
>>
>> void setExampleVariable(Example ex) {
>> variable = ex;
>> }
>>
>> void callCurrentExampleVariable() {
>> variable();
>> }
>
> I don't think you want templates. What you want is a tagged union (and a struct
> is MUCH better suited for this):
>
> // untested!
>
> struct Example
> {
> private
> {
> bool isDelegate;
> union
> {
> void function() fn;
> void delegate() dg;
> }
> }
>
> void setCallback(void function() f) { this.fn = f; isDelegate = false;}
> void setCallback(void delegate() d) { this.dg = d; isDelegate = true;}
>
> void opCall()
> {
> if(isDelegate)
> dg();
> else
> fn();
> }
> }

Waow, very nice solution.
I really question the function/delegate distinction (mostly artificial, imo) that "invents" issues necessiting workarounds like that. What does it mean, what does it bring?
Right, there is one pointer less for funcs. This save 4 or 8 bytes, so to say, nothing; who develops apps with arrays of billions of funcs? There are written in source ;-) Even then, if this saving of apointer was of any relevance, then it should be an implementation detail that does not leak into artificial semantic diff, creating issues on the programmer side. What do you think?

Denis
-- 
_________________
vita es estrany
spir.wikidot.com

February 10, 2011
On Thu, 10 Feb 2011 08:39:13 -0500, spir <denis.spir@gmail.com> wrote:

> On 02/09/2011 11:05 PM, Steven Schveighoffer wrote:

>> I don't think you want templates. What you want is a tagged union (and a struct
>> is MUCH better suited for this):
>>
>> // untested!
>>
>> struct Example
>> {
>> private
>> {
>> bool isDelegate;
>> union
>> {
>> void function() fn;
>> void delegate() dg;
>> }
>> }
>>
>> void setCallback(void function() f) { this.fn = f; isDelegate = false;}
>> void setCallback(void delegate() d) { this.dg = d; isDelegate = true;}
>>
>> void opCall()
>> {
>> if(isDelegate)
>> dg();
>> else
>> fn();
>> }
>> }
>
> Waow, very nice solution.
> I really question the function/delegate distinction (mostly artificial, imo) that "invents" issues necessiting workarounds like that. What does it mean, what does it bring?

A function pointer is compatible with a C function pointer.  C does not have delegates, so if you want to do callbacks, you need to use function pointers.  There is no way to combine them and keep C compatibility.

> Right, there is one pointer less for funcs. This save 4 or 8 bytes, so to say, nothing; who develops apps with arrays of billions of funcs? There are written in source ;-) Even then, if this saving of apointer was of any relevance, then it should be an implementation detail that does not leak into artificial semantic diff, creating issues on the programmer side. What do you think?

What you want is already implemented.  There is a relatively new phobos construct that builds a delegate out of a function pointer.  In fact, my code could use it and save the tag:


// again, untested!

import std.functional : toDelegate;

struct Example
{
   private void delegate() dg;

   void setCallback(void function() f) { this.dg = toDelegate(f); }
   void setCallback(void delegate() d) { this.dg = d; }

   void opCall() { dg(); }
}

Note that toDelegate doesn't appear on the docs because of a doc generation bug...

-Steve
February 10, 2011
I implemented all I wanted and it works perfectly ;).

But I'm using the "if (is(T == delegate) || is(T == function))"-
statement in another class/template.

class Example(T) if (is(T == delegate) || is(T == function)) {
...
}

Now, when I declare Example!(void function()) myVar; I always get:

Error: template instance Example!(void function()) does not match
template declaration Example(T) if (is(T == delegate) || is(T ==
function))
Error: Example!(void function()) is used as a type

When I declare myVar as Example!(function), I get some other errors.

What's wrong with my code?
February 10, 2011
On Thu, 10 Feb 2011 09:09:03 -0500, useo <useo@start.bg> wrote:

> I implemented all I wanted and it works perfectly ;).
>
> But I'm using the "if (is(T == delegate) || is(T == function))"-
> statement in another class/template.
>
> class Example(T) if (is(T == delegate) || is(T == function)) {
> ...
> }
>
> Now, when I declare Example!(void function()) myVar; I always get:
>
> Error: template instance Example!(void function()) does not match
> template declaration Example(T) if (is(T == delegate) || is(T ==
> function))
> Error: Example!(void function()) is used as a type
>
> When I declare myVar as Example!(function), I get some other errors.
>
> What's wrong with my code?

Please post a full example that creates the error.  From that error message, it appears that your code is correct, but I'd have to play with a real example to be sure.

-Steve
February 10, 2011
== Auszug aus Steven Schveighoffer (schveiguy@yahoo.com)'s Artikel
> On Thu, 10 Feb 2011 09:09:03 -0500, useo <useo@start.bg> wrote:
> > I implemented all I wanted and it works perfectly ;).
> >
> > But I'm using the "if (is(T == delegate) || is(T == function))"-
> > statement in another class/template.
> >
> > class Example(T) if (is(T == delegate) || is(T == function)) {
> > ...
> > }
> >
> > Now, when I declare Example!(void function()) myVar; I always get:
> >
> > Error: template instance Example!(void function()) does not match
> > template declaration Example(T) if (is(T == delegate) || is(T ==
> > function))
> > Error: Example!(void function()) is used as a type
> >
> > When I declare myVar as Example!(function), I get some other
errors.
> >
> > What's wrong with my code?
> Please post a full example that creates the error.  From that error message, it appears that your code is correct, but I'd have to play
with a
> real example to be sure.
> -Steve

I created a complete, new file with the following code:

module example;

void main(string[] args) {
	Example!(void function()) myVar;
}

class Example(T) if (is(T == delegate) || is(T == function)) {
}

And what I get is:

example.d(4): Error: template instance Example!(void function()) does
not match template declaration Example(T) if (is(T == delegate) || is
(T == function))
example.d(4): Error: Example!(void function()) is used as a type

I'm using the current stable version 2.051.
February 10, 2011
== Auszug aus useo (useo@start.bg)'s Artikel
> == Auszug aus Steven Schveighoffer (schveiguy@yahoo.com)'s Artikel
> > On Thu, 10 Feb 2011 09:09:03 -0500, useo <useo@start.bg> wrote:
> > > I implemented all I wanted and it works perfectly ;).
> > >
> > > But I'm using the "if (is(T == delegate) || is(T == function))"-
> > > statement in another class/template.
> > >
> > > class Example(T) if (is(T == delegate) || is(T == function)) {
> > > ...
> > > }
> > >
> > > Now, when I declare Example!(void function()) myVar; I always
get:
> > >
> > > Error: template instance Example!(void function()) does not
match
> > > template declaration Example(T) if (is(T == delegate) || is(T ==
> > > function))
> > > Error: Example!(void function()) is used as a type
> > >
> > > When I declare myVar as Example!(function), I get some other
> errors.
> > >
> > > What's wrong with my code?
> > Please post a full example that creates the error.  From that
error
> > message, it appears that your code is correct, but I'd have to
play
> with a
> > real example to be sure.
> > -Steve
> I created a complete, new file with the following code:
> module example;
> void main(string[] args) {
> 	Example!(void function()) myVar;
> }
> class Example(T) if (is(T == delegate) || is(T == function)) {
> }
> And what I get is:
> example.d(4): Error: template instance Example!(void function())
does
> not match template declaration Example(T) if (is(T == delegate) ||
is
> (T == function))
> example.d(4): Error: Example!(void function()) is used as a type
> I'm using the current stable version 2.051.

I noticed, that this error only occurs when I use function as
template-type. When I use Example!(void delegate()) myVar; it
compiles without any error. With function - Example!(void function())
myVar; I get the error(s) above.