February 10, 2011
On Thu, 10 Feb 2011 09:48:14 -0500, useo <useo@start.bg> wrote:


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

Found this invalid bug.  Apparently, this is expected (!) behavior:

http://d.puremagic.com/issues/show_bug.cgi?id=3464

So use this instead:

class Example(T) if (is(T == delegate) || is(typeof(*T.init) == function))

Ugly, I know, but I guess that's what we got to work with.

-Steve
February 10, 2011
== Auszug aus Steven Schveighoffer (schveiguy@yahoo.com)'s Artikel
> On Thu, 10 Feb 2011 09:48:14 -0500, useo <useo@start.bg> wrote:
> > 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.
> Found this invalid bug.  Apparently, this is expected (!) behavior:
> http://d.puremagic.com/issues/show_bug.cgi?id=3464
> So use this instead:
> class Example(T) if (is(T == delegate) || is(typeof(*T.init) ==
function))
> Ugly, I know, but I guess that's what we got to work with. -Steve

Yes, looks a bit unusual but it works, thanks!
February 10, 2011
On 02/10/2011 02:51 PM, Steven Schveighoffer wrote:
> 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...

Right.

I had not thought at the C-compatibility issue. So, let us say the func/dg distinction must remain in the language, on programmer-side, because of that. Then, is there anything that prevent the above cast to be implicit? Then, programmers would only have to define a single interface, using delegate everywhere; and not care about where and how user funcs are defined.
(because as you know presently whether a ref'ed func becomes a func pointer or a delegate depends on /where/ it is defined...)

Second point. I would like referencing of functions/delegates passed as arguments to be implicite. After all, conceptually, what we pass is a "function object". Not a pointer. That the implementation needs to "point" them is just this, implementation. The '&' just pollutes the code meaninglessly; and it's absence creates weird bugs:

void f0 (     ) { writeln(1); }
void f1 (int i) { writeln(i); }
void do0 (void function (   ) f) { f( ); }
void do1 (void function (int) f) { f(3); }

unittest {
    // Error: function __trials__.do0 (void function() f) is not callable
    // using argument types (void)
    do0(f0);

    // __trials__.d(46): Error: function __trials__.f1 (int i) is not callable
    // using argument types ()
    do1(f1);

    do0(&f0);   // ok
    do1(&f1);   // ok
}

Error messages are difficult to interpret for a diagnosis, I guess. Note that the first one concerns the caller, while the second one concerns the callee...
Implicite referencing would solve that issue /and/ match semantics /and/ be more consistent /and/ make code nicer. About consistency, I mean that functions are already implicitely dereferenced: do1 does not need to call its arg f using
	(*f)(3);
(this version works as well, indeed)

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

February 10, 2011
On Thu, 10 Feb 2011 12:04:28 -0500, spir <denis.spir@gmail.com> wrote:

> On 02/10/2011 02:51 PM, Steven Schveighoffer wrote:
>> 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...
>
> Right.
>
> I had not thought at the C-compatibility issue. So, let us say the func/dg distinction must remain in the language, on programmer-side, because of that. Then, is there anything that prevent the above cast to be implicit? Then, programmers would only have to define a single interface, using delegate everywhere; and not care about where and how user funcs are defined.
> (because as you know presently whether a ref'ed func becomes a func pointer or a delegate depends on /where/ it is defined...)
>
> Second point. I would like referencing of functions/delegates passed as arguments to be implicite. After all, conceptually, what we pass is a "function object". Not a pointer. That the implementation needs to "point" them is just this, implementation. The '&' just pollutes the code meaninglessly;

This is the way it is in C, and D purposely does not do this to avoid ambiguity (did you want to call the function or get it's address?).

> and it's absence creates weird bugs:
>
> void f0 (     ) { writeln(1); }
> void f1 (int i) { writeln(i); }
> void do0 (void function (   ) f) { f( ); }
> void do1 (void function (int) f) { f(3); }
>
> unittest {
>      // Error: function __trials__.do0 (void function() f) is not callable
>      // using argument types (void)
>      do0(f0);
>
>      // __trials__.d(46): Error: function __trials__.f1 (int i) is not callable
>      // using argument types ()
>      do1(f1);
>
>      do0(&f0);   // ok
>      do1(&f1);   // ok
> }
>
> Error messages are difficult to interpret for a diagnosis, I guess. Note that the first one concerns the caller, while the second one concerns the callee...
> Implicite referencing would solve that issue /and/ match semantics /and/ be more consistent /and/ make code nicer. About consistency, I mean that functions are already implicitely dereferenced: do1 does not need to call its arg f using
> 	(*f)(3);
> (this version works as well, indeed)

When properties are properly implemented, I expect this error message to be different.  Currently, it thinks you are trying to call the function f0 and pass its result to do0.

-Steve
1 2 3
Next ›   Last »