digitalmars.D.learn - Template for function or delegate (nothing else)
- useo (7/7) Feb 09 2011 Is it possible to create a template which only accepts functions or
- Steven Schveighoffer (6/13) Feb 09 2011 class Example(T) if (is(T == delegate) || is(T == function))
- useo (4/22) Feb 09 2011 ())..
- useo (8/26) Feb 09 2011 ())..
- Steven Schveighoffer (6/32) Feb 09 2011 Yes, but you have the order mixed up.
- useo (9/45) Feb 09 2011 ()...
- useo (16/16) Feb 09 2011 I just have a problem with my variables.
- Steven Schveighoffer (9/25) Feb 09 2011 If I understand you correctly, you don't want to declare the type of T
- useo (8/38) Feb 09 2011 already
- bearophile (9/31) Feb 09 2011 D is not the SML language, templates are just placeholders. If you don't...
- useo (30/61) Feb 09 2011 you don't instantiate a template, you have only a symbol. Example
- Steven Schveighoffer (26/87) Feb 09 2011 I don't think you want templates. What you want is a tagged union (and ...
- useo (14/114) Feb 09 2011 function
- spir (15/114) Feb 10 2011 Waow, very nice solution.
- Steven Schveighoffer (19/59) Feb 10 2011 A function pointer is compatible with a C function pointer. C does not ...
- useo (13/13) Feb 10 2011 I implemented all I wanted and it works perfectly ;).
- Steven Schveighoffer (5/18) Feb 10 2011 Please post a full example that creates the error. From that error
- useo (16/40) Feb 10 2011 with a
- useo (11/51) Feb 10 2011 match
- Steven Schveighoffer (7/20) Feb 10 2011 Found this invalid bug. Apparently, this is expected (!) behavior:
- useo (5/31) Feb 10 2011 || is
- spir (40/97) Feb 10 2011 Right.
- Steven Schveighoffer (7/129) Feb 10 2011 This is the way it is in C, and D purposely does not do this to avoid
- bearophile (4/7) Feb 09 2011 void foo(T)(T x) if (is(T == delegate) || is(T == function)) { ... }
Is it possible to create a template which only accepts functions or delegates like this example: class Example(T : void function()) { // or ..(T : void delegate()).. T callback; } Where T is a function or a delegate... Thanks for every suggestion!
Feb 09 2011
On Wed, 09 Feb 2011 14:35:42 -0500, useo <useo start.bg> wrote:Is it possible to create a template which only accepts functions or delegates like this example: class Example(T : void function()) { // or ..(T : void delegate()).. T callback; } Where T is a function or a delegate... Thanks for every suggestion!class Example(T) if (is(T == delegate) || is(T == function)) { T callback; } -Steve
Feb 09 2011
== Auszug aus Steven Schveighoffer (schveiguy yahoo.com)'s ArtikelOn Wed, 09 Feb 2011 14:35:42 -0500, useo <useo start.bg> wrote:orIs it possible to create a template which only accepts functions())..delegates like this example: class Example(T : void function()) { // or ..(T : void delegateWow, works great - THANKS :)T callback; } Where T is a function or a delegate... Thanks for every suggestion!class Example(T) if (is(T == delegate) || is(T == function)) { T callback; } -Steve
Feb 09 2011
== Auszug aus Steven Schveighoffer (schveiguy yahoo.com)'s ArtikelOn Wed, 09 Feb 2011 14:35:42 -0500, useo <useo start.bg> wrote:orIs it possible to create a template which only accepts functions())..delegates like this example: class Example(T : void function()) { // or ..(T : void delegateIs there any chance to do the same for methods like: void example(T)() { } ... something like: void bindEvent(T)(if (is(T == delegate) || is(T == function)))()...T callback; } Where T is a function or a delegate... Thanks for every suggestion!class Example(T) if (is(T == delegate) || is(T == function)) { T callback; } -Steve
Feb 09 2011
On Wed, 09 Feb 2011 14:59:33 -0500, useo <useo start.bg> wrote:== Auszug aus Steven Schveighoffer (schveiguy yahoo.com)'s ArtikelYes, but you have the order mixed up. void bindEvent(T)() if (is...) In general form, a template constraint goes after the declaration, but before the body of the template. -SteveOn Wed, 09 Feb 2011 14:35:42 -0500, useo <useo start.bg> wrote:orIs it possible to create a template which only accepts functions())..delegates like this example: class Example(T : void function()) { // or ..(T : void delegateIs there any chance to do the same for methods like: void example(T)() { } ... something like: void bindEvent(T)(if (is(T == delegate) || is(T == function)))()...T callback; } Where T is a function or a delegate... Thanks for every suggestion!class Example(T) if (is(T == delegate) || is(T == function)) { T callback; } -Steve
Feb 09 2011
== Auszug aus Steven Schveighoffer (schveiguy yahoo.com)'s ArtikelOn Wed, 09 Feb 2011 14:59:33 -0500, useo <useo start.bg> wrote:functions== Auszug aus Steven Schveighoffer (schveiguy yahoo.com)'s ArtikelOn Wed, 09 Feb 2011 14:35:42 -0500, useo <useo start.bg> wrote:Is it possible to create a template which only accepts()...or())..delegates like this example: class Example(T : void function()) { // or ..(T : void delegateIs there any chance to do the same for methods like: void example(T)() { } ... something like: void bindEvent(T)(if (is(T == delegate) || is(T == function)))T callback; } Where T is a function or a delegate... Thanks for every suggestion!class Example(T) if (is(T == delegate) || is(T == function)) { T callback; } -SteveYes, but you have the order mixed up. void bindEvent(T)() if (is...) In general form, a template constraint goes after the declaration,butbefore the body of the template. -SteveAh, okay... I already tried the if-statement after the declaration but I always got an error like this: "... semicolon expected following function declaration" I just removed ( and ) from the if-statement and it's working, thanks in again!
Feb 09 2011
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.
Feb 09 2011
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
Feb 09 2011
== Auszug aus Steven Schveighoffer (schveiguy yahoo.com)'s ArtikelOn Wed, 09 Feb 2011 16:14:04 -0500, useo <useo start.bg> wrote:type ofI 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 thealreadya callback and perhaps one method-declaration nothing else. Iof Ttried 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 typewhen instantiating the template? This is not possible, templatesmusthave 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; -SteveYes, right, I don't want declare the template-type. Nevertheless... thanks
Feb 09 2011
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
Feb 09 2011
== Auszug aus bearophile (bearophileHUGS lycos.com)'s Artikeluseo:())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 functionyou don't instantiate a template, you have only a symbol. Example is only assignable to an alias (and in past, to a typedef):myVariable. But is there any possibility to use variables like Example myVariable?D is not the SML language, templates are just placeholders. Ifalias Example Foo;alreadyThe template declaration only defines the type of a callback and perhaps one method-declaration nothing else. Ito dotried Example!(void*) because delegates and functions are void pointers but I always get an error. I hope there is any wayinstance that defined opCall)?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- sizeof of a function pointer is 1 CPU word, while a delegateis 2 CPU words (and a delegate clojure has stuff on the heap too, sometimes).Bye, bearophileIdea 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(); }
Feb 09 2011
On Wed, 09 Feb 2011 16:41:25 -0500, useo <useo start.bg> wrote:== Auszug aus bearophile (bearophileHUGS lycos.com)'s ArtikelI 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(); } } -Steveuseo:())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 functionyou don't instantiate a template, you have only a symbol. Example is only assignable to an alias (and in past, to a typedef):myVariable. But is there any possibility to use variables like Example myVariable?D is not the SML language, templates are just placeholders. Ifalias Example Foo;alreadyThe template declaration only defines the type of a callback and perhaps one method-declaration nothing else. Ito dotried Example!(void*) because delegates and functions are void pointers but I always get an error. I hope there is any wayinstance that defined opCall)?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- sizeof of a function pointer is 1 CPU word, while a delegateis 2 CPU words (and a delegate clojure has stuff on the heap too, sometimes).Bye, bearophileIdea 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(); }
Feb 09 2011
== Auszug aus Steven Schveighoffer (schveiguy yahoo.com)'s ArtikelOn Wed, 09 Feb 2011 16:41:25 -0500, useo <useo start.bg> wrote:function))== Auszug aus bearophile (bearophileHUGS lycos.com)'s Artikeluseo: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!(voidlike())myVariable. But is there any possibility to use variablesIfExample myVariable?D is not the SML language, templates are just placeholders.Exampleyou don't instantiate a template, you have only a symbol.else. Iis 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 nothingvoidalreadytried Example!(void*) because delegates and functions aredelegateto dopointers but I always get an error. I hope there is any wayinstance that defined opCall)?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- sizeof of a function pointer is 1 CPU word, while atoo,is 2 CPU words (and a delegate clojure has stuff on the heapunion (and asometimes).I don't think you want templates. What you want is a taggedBye, bearophileIdea 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(); }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(); } } -SteveLooks really interesting and seems to work. Thanks in advance!
Feb 09 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: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== Auszug aus bearophile (bearophileHUGS lycos.com)'s ArtikelI 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(); } }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 functionyou don't instantiate a template, you have only a symbol. Example is only assignable to an alias (and in past, to a typedef):myVariable. But is there any possibility to use variables like Example myVariable?D is not the SML language, templates are just placeholders. Ifalias Example Foo;alreadyThe template declaration only defines the type of a callback and perhaps one method-declaration nothing else. Ito dotried Example!(void*) because delegates and functions are void pointers but I always get an error. I hope there is any wayinstance that defined opCall)?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- sizeof of a function pointer is 1 CPU word, while a delegateis 2 CPU words (and a delegate clojure has stuff on the heap too, sometimes).Bye, bearophileIdea 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(); }
Feb 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: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.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?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
Feb 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?
Feb 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
Feb 10 2011
== Auszug aus Steven Schveighoffer (schveiguy yahoo.com)'s ArtikelOn Thu, 10 Feb 2011 09:09:03 -0500, useo <useo start.bg> wrote:errors.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 otherwith aWhat'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 playreal example to be sure. -SteveI 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.
Feb 10 2011
== Auszug aus useo (useo start.bg)'s Artikel== Auszug aus Steven Schveighoffer (schveiguy yahoo.com)'s Artikelget: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 alwaysmatchError: template instance Example!(void function()) does noterrorerrors.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 otherWhat's wrong with my code?Please post a full example that creates the error. From thatplaymessage, it appears that your code is correct, but I'd have towith adoesreal example to be sure. -SteveI 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())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.
Feb 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
Feb 10 2011
== Auszug aus Steven Schveighoffer (schveiguy yahoo.com)'s ArtikelOn Thu, 10 Feb 2011 09:48:14 -0500, useo <useo start.bg> wrote:doesI 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())|| isnot match template declaration Example(T) if (is(T == delegate)function))(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) ==Ugly, I know, but I guess that's what we got to work with. -SteveYes, looks a bit unusual but it works, thanks!
Feb 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: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.comOn 02/09/2011 11:05 PM, Steven Schveighoffer wrote: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.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?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...
Feb 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: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?).On Thu, 10 Feb 2011 08:39:13 -0500, spir <denis.spir gmail.com> wrote: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;On 02/09/2011 11:05 PM, Steven Schveighoffer wrote: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.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?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...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
Feb 10 2011
useo:... something like: void bindEvent(T)(if (is(T == delegate) || is(T == function)))()...void foo(T)(T x) if (is(T == delegate) || is(T == function)) { ... } Bye, bearophile
Feb 09 2011