D - Delegates
- Walter (35/35) Apr 02 2002 A first crack at a proposal.
- Pavel Minayev (23/58) Apr 02 2002 object
- J. Daniel Smith (20/46) Apr 03 2002 [ moved to this thread from the "new D site" thread ]
- Richard Krehbiel (13/17) Apr 03 2002 Um - The paranoid part of me thinks, Walter, that you should delete that
- J. Daniel Smith (15/52) Apr 03 2002 I think the provision "You may use any information in intangible form th...
- Russ Lewis (6/6) Apr 02 2002 Looks really good!
- OddesE (13/48) Apr 02 2002 object
- Pavel Minayev (3/7) Apr 02 2002 Well, yes =)
- J. Daniel Smith (24/32) Apr 04 2002 The way C# goes about implementing delegates is interesting: the compile...
- roland (9/11) Apr 04 2002 i don't know why, but i feel delegate initialisation can be nicer:
- Roland (6/9) Apr 04 2002 rectification: as function args are declared with delegate, there is no
- Richard Krehbiel (11/15) Apr 05 2002 Type information (typically) does not flow left-to-right across assignme...
- Walter (13/16) Apr 05 2002 I had the same thought, but I still haven't figured out what to do in
- Russell Borogove (7/16) Apr 05 2002 Hey, I'm not following the discussion of delegates too
- Pavel Minayev (14/17) Apr 05 2002 Imagine:
- Russell Borogove (10/37) Apr 05 2002 This language design thing is hard. :) Like you, I'd
- Pavel Minayev (14/22) Apr 05 2002 It isn't proper way since D strings are not 0-terminated,
- Russell Borogove (13/34) Apr 05 2002 Ohhh, crap. Well, I lobbied for padding (at least char
- Walter (4/8) Apr 05 2002 Actually, D does 0 terminate them when it can, for just that reason. But...
- Pavel Minayev (6/10) Apr 06 2002 Literals are terminated with 0 in memory. However, 0 is not considered
- Walter (4/14) Apr 06 2002 That's right. It's a bit of a hack, but a hack that works for the most
- Pavel Minayev (4/11) Apr 06 2002 It's also great when interfacing with APIs and such. Well, it just works...
- Pavel Minayev (14/25) Apr 05 2002 I guess it shouldn't. The reason is, you will probably define a wchar
A first crack at a proposal. ---------------------------------- A delegate is conceptually a function pointer coupled with an object reference. If the function is a non-member or a static function, the object reference is null. There are three things to do with delegates 1) declaring them 2) initializing them and 3) calling them. 1. Declaring Delegates A delegate needs a return type and a parameter list. Introduce the keyword 'delegate' and declare mydelegate as: int delegate(int x, int y) mydelegate; An array of delegates would be: float delegate(int *p)[] foo; // foo is array of delegates Delegates can be typedef'd: typedef int delegate(int x, int y) bar; bar x; // x is a delegate 2. Initializing Delegates Delegates are initialized with an object and a function signature. They are initialized with a DelegateExpression: class Abc { int func(int,int); } Abc a = new Abc(); int delegate(int, int) x; x = delegate(a, func(int,int)); The first argument to delegate(object, function signature) is the object reference. A delegate to a non-member or static function can be initialized by using null as the object: int xyzzy(int, int); x = delegate(null, xyzzy(int, int)); 3. Calling Delegates Delegates are called as if they are normal functions: x(3,4); // call delegate x
Apr 02 2002
"Walter" <walter digitalmars.com> wrote in message news:a8d501$2far$1 digitaldaemon.com...A first crack at a proposal. ---------------------------------- A delegate is conceptually a function pointer coupled with an object reference. If the function is a non-member or a static function, theobjectreference is null.Seems like the best solution.There are three things to do with delegates 1) declaring them 2) initializing them and 3) calling them. 1. Declaring Delegates A delegate needs a return type and a parameter list. Introduce the keyword 'delegate' and declare mydelegate as: int delegate(int x, int y) mydelegate;Pretty fine. Looks more like variable declaration, and is much better than C function pointers;An array of delegates would be: float delegate(int *p)[] foo; // foo is array of delegatesConsistent.Delegates can be typedef'd: typedef int delegate(int x, int y) bar; bar x; // x is a delegateAs well.2. Initializing Delegates Delegates are initialized with an object and a function signature. They are initialized with a DelegateExpression: class Abc { int func(int,int); } Abc a = new Abc(); int delegate(int, int) x; x = delegate(a, func(int,int)); The first argument to delegate(object, function signature) is the object reference.Just a suggestion: if object is omitted, assume "this" where applicable: class Form { Button OK; void OK_Click(int x, int y) { ... } this() { OK.onClick = delegate(OK_Click(int, int)); } } Pointers to methods of "this" are 90% of all, anyhow.A delegate to a non-member or static function can be initialized by using null as the object: int xyzzy(int, int); x = delegate(null, xyzzy(int, int));Why not just function pointers? x = &xyzzy(int, int); Or, allow to omit Object, assuming null when outside class.3. Calling Delegates Delegates are called as if they are normal functions: x(3,4); // call delegate xYep.
Apr 02 2002
[ moved to this thread from the "new D site" thread ] compiler to do a "typedef" of "System.MulticastDelegate"; then it looks like there is some additional checking to be sure that new "delegate" type is only used with the "event" keyword to declare a variable: public delegate void Foo(int); // typedef System.MulticastDelegate Foo; public event Foo ptr; // Foo ptr; Of course, things are a bit more complicated than that since all the Objects. Microsoft has released the source code for the SDK version of .NET; see http://msdn.microsoft.com/library/en-us/Dndotnet/html/mssharsourcecli.asp. Looking through the code in "delegate.cs" is interesting. Dan [ edited delegate.cs ] "Pavel Minayev" <evilone omen.ru> wrote in message news:a8evkh$5tf$1 digitaldaemon.com..."Walter" <walter digitalmars.com> wrote in message news:a8eie6$40d$1 digitaldaemon.com...athestorage class, but it isn't, it's a type component. It doesn't seempossibledelegatesor a pointer to a delegate or a function returning a delegate.which declares type, and not variable: delegate void Foo(int); // Foo is a new type Foo ptr; // declare a pointer of that type So, you can actually have arrays: Foo[] ptr; Still, I like your syntax more. It is more distinct from normal function declaration.The static/virtual delegate call shouldn't cause a slowdown in D, forhappy coincidence that the 'this' pointer is passed in EAX. Hence, just stuff the object reference in EAX after pushing the parameters. If the function doesn't take a this pointer, it ignores EAX with no adverse consequences.It's implementation detail, I guess. As long as it works, great, and no matter how it is done. I wouldn't mind if it were slower than normal ptr call, but if you can make it the same, well, it's great! By the way, I guess functions with non-D calling conventions cannot be delegated?
Apr 03 2002
Um - The paranoid part of me thinks, Walter, that you should delete that post, since it contains Microsoft copyrighted code. I say this without knowing if it's actually illegal to have posted a copy, but rather from extreme caution. MS might come in later and say that, having read this source you have agreed to the source license, and the source license states that everything you gain from reading the source belongs to MS. Mono project (www.go-mono.com) which is "libre" open source. "J. Daniel Smith" <j_daniel_smith HoTMaiL.com> wrote in message news:a8f65e$bal$1 digitaldaemon.com...Microsoft has released the source code for the SDK version of .NET; see http://msdn.microsoft.com/library/en-us/Dndotnet/html/mssharsourcecli.asp. Looking through the code in "delegate.cs" is interesting. Dan-- Richard Krehbiel, Arlington, VA, USA rich kastle.com (work) or krehbiel3 comcast.net (personal)
Apr 03 2002
I think the provision "You may use any information in intangible form that you remember after accessing the Software." covers the D effort with regards to this. I removed most of the code that actually does anything from my post since that didn't seem very relevent to the discussion; thus the code I posted won't compile, and even it it does, it won't do anything useful. code snipet would seem to fall under the "academic research" category for use of "the Software". Dan "Richard Krehbiel" <rich kastle.com> wrote in message news:a8fg3e$289$1 digitaldaemon.com...Um - The paranoid part of me thinks, Walter, that you should delete that post, since it contains Microsoft copyrighted code. I say this without knowing if it's actually illegal to have posted a copy, but rather from extreme caution. MS might come in later and say that, having read this source you have agreed to the source license, and the source licensestatesthat everything you gain from reading the source belongs to MS.theMono project (www.go-mono.com) which is "libre" open source. "J. Daniel Smith" <j_daniel_smith HoTMaiL.com> wrote in message news:a8f65e$bal$1 digitaldaemon.com...http://msdn.microsoft.com/library/en-us/Dndotnet/html/mssharsourcecli.asp.Microsoft has released the source code for the SDK version of .NET; seeboundLooking through the code in "delegate.cs" is interesting. Dan [ edited delegate.cs ] // ==++== // // // Copyright (c) 2002 Microsoft Corporation. All rights reserved. // // The use and distribution terms for this software are contained inthefile // named license.txt, which can be found in the root of this distribution. // By using this software in any fashion, you are agreeing to bebythe // terms of this license. // // You must not remove this notice, or any other, from this software.-- Richard Krehbiel, Arlington, VA, USA rich kastle.com (work) or krehbiel3 comcast.net (personal)
Apr 03 2002
Looks really good! -- The Villagers are Online! villagersonline.com .[ (the fox.(quick,brown)) jumped.over(the dog.lazy) ] .[ (a version.of(English).(precise.more)) is(possible) ] ?[ you want.to(help(develop(it))) ]
Apr 02 2002
"Walter" <walter digitalmars.com> wrote in message news:a8d501$2far$1 digitaldaemon.com...A first crack at a proposal. ---------------------------------- A delegate is conceptually a function pointer coupled with an object reference. If the function is a non-member or a static function, theobjectreference is null. There are three things to do with delegates 1) declaring them 2) initializing them and 3) calling them. 1. Declaring Delegates A delegate needs a return type and a parameter list. Introduce the keyword 'delegate' and declare mydelegate as: int delegate(int x, int y) mydelegate; An array of delegates would be: float delegate(int *p)[] foo; // foo is array of delegates Delegates can be typedef'd: typedef int delegate(int x, int y) bar; bar x; // x is a delegate 2. Initializing Delegates Delegates are initialized with an object and a function signature. They are initialized with a DelegateExpression: class Abc { int func(int,int); } Abc a = new Abc(); int delegate(int, int) x; x = delegate(a, func(int,int)); The first argument to delegate(object, function signature) is the object reference. A delegate to a non-member or static function can be initialized by using null as the object: int xyzzy(int, int); x = delegate(null, xyzzy(int, int)); 3. Calling Delegates Delegates are called as if they are normal functions: x(3,4); // call delegate xOh oh, I sense another rewrite of Pavel's WinD module coming up... :) But I guess you won't mind at all eh Pavel, this is pretty much what you want isn't it? -- Stijn OddesE_XYZ hotmail.com http://OddesE.cjb.net _________________________________________________ Remove _XYZ from my address when replying by mail
Apr 02 2002
"OddesE" <OddesE_XYZ hotmail.com> wrote in message news:a8ddi3$ret$1 digitaldaemon.com...Oh oh, I sense another rewrite of Pavel's WinD module coming up... :) But I guess you won't mind at all eh Pavel, this is pretty much what you want isn't it?Well, yes =)
Apr 02 2002
*requires* that certain classes (in this case System.Delegate and friends) exist at run-time. This seems to harken back to languages like Pascal where writeln() was part of the the language, but it was implemented in a run-time library; it is a different approach from C/C++ (and D) where printf() is "only" a library routine. "delegate" feature, not only does the compiler have to support the new syntax, but then it also has to generate a bunch of code to make the syntax work. By moving the actual implementing into a class, there is much less work for the compiler to do: when it sees the "delegate" keyword is knows to use the System.Delegate class in a certain manner. Of course, this approach opens might open a whole can of worms with regards to issues that have been hashed over to some length already such as operator overloading, since you now have to be able to write a "delegate", "string", or "complex" class in D itself - the compiler can't do as much "black magic" to make such things work. Putting the bulk of the "real work" in a class would also seem to make it easier to port D to other platforms since the compiler itself would now be simplier. Dan "Walter" <walter digitalmars.com> wrote in message news:a8d501$2far$1 digitaldaemon.com...A first crack at a proposal. ---------------------------------- A delegate is conceptually a function pointer coupled with an object reference. If the function is a non-member or a static function, theobjectreference is null. There are three things to do with delegates 1) declaring them 2) initializing them and 3) calling them. [...]
Apr 04 2002
Walter a écrit :A first crack at a proposal.beautiful !x = delegate(a, func(int,int));i don't know why, but i feel delegate initialisation can be nicer: x = delegate(a.func(int,int)); //? or if "a" is *this: x = delegate(func(int,int)) //? or even if there is only one methode called func: x = delegate(a.func); //? roland
Apr 04 2002
roland a écrit :i don't know why, but i feel delegate initialisation can be nicer:.or even if there is only one methode called func:rectification: as function args are declared with delegate, there is no ambiguity about witch methode is to be delegated. so, delegate initialisation could, in theory, always be this format.x = delegate(a.func); //?roland
Apr 04 2002
"Roland" <rv ronetech.com> wrote in message news:3CAD5197.5CC2DA84 ronetech.com...rectification: as function args are declared with delegate, there is no ambiguity about witch methode is to be delegated. so, delegate initialisation could, in theory, always be this format.Type information (typically) does not flow left-to-right across assignment expressions; in other words, the "delegate" operation can't peek at the "x" across the "=" to find anything out. But actually, having said that, I already know there's an exception in D. String literals become char literals and wide strings based on their assignment context, so maybe delegates can do similar magic. -- Richard Krehbiel, Arlington, VA, USA rich kastle.com (work) or krehbiel3 comcast.net (personal)x = delegate(a.func); //?
Apr 05 2002
"Richard Krehbiel" <rich kastle.com> wrote in message news:a8k6de$5na$1 digitaldaemon.com...But actually, having said that, I already know there's an exception in D. String literals become char literals and wide strings based on their assignment context, so maybe delegates can do similar magic.I had the same thought, but I still haven't figured out what to do in ambiguous cases like: void foo(char[]); void foo(wchar[]); ... foo("hello"); Which gets called? Should it be an error? In any case, I'm leaning towards initializing a delegate with the syntax: x = &o.func; and then using the context to figure out which overloaded func it should be. This does add some complexity to the compiler I don't like.
Apr 05 2002
Walter wrote:I had the same thought, but I still haven't figured out what to do in ambiguous cases like: void foo(char[]); void foo(wchar[]); ... foo("hello"); Which gets called? Should it be an error?Hey, I'm not following the discussion of delegates too closely, but I've got an opinion on this one. I'd want a warning on that so as to avoid consequences of calling the wrong one; since you don't believe in warnings, it should be an error. -RB
Apr 05 2002
"Russell Borogove" <kaleja estarcion.com> wrote in message news:3CADE8E0.1070307 estarcion.com...I'd want a warning on that so as to avoid consequences of calling the wrong one; since you don't believe in warnings, it should be an error.Imagine: class Stream { void write(char[] s) { ... } void write(wchar[] s) { ... } } That's right, two versions, because you might want to feed char[] or wchar[] variable to it. Now, you write: stdout.write("Hello, world!"); And get the compiler error, 'cause you must do: stdout.write(cast(char[]) "Hello, world!"); You like it?
Apr 05 2002
Pavel Minayev wrote:"Russell Borogove" <kaleja estarcion.com> wrote in message news:3CADE8E0.1070307 estarcion.com...This language design thing is hard. :) Like you, I'd have to lean towards differentiating char and wchar literals, or default to char unless there's a \uXXXX in there somewhere. The latter might give rise to the (ugly) idiom: "Hello world!\u0000" to force wide char literal strings. Sidethread, you complain about the L"literal" syntax as ugly, but it's far less ugly than the cast. -RI'd want a warning on that so as to avoid consequences of calling the wrong one; since you don't believe in warnings, it should be an error.Imagine: class Stream { void write(char[] s) { ... } void write(wchar[] s) { ... } } That's right, two versions, because you might want to feed char[] or wchar[] variable to it. Now, you write: stdout.write("Hello, world!"); And get the compiler error, 'cause you must do: stdout.write(cast(char[]) "Hello, world!"); You like it?
Apr 05 2002
"Russell Borogove" <kaleja estarcion.com> wrote in message news:3CADFE2F.4070502 estarcion.com...This language design thing is hard. :) Like you, I'd have to lean towards differentiating char and wchar literals, or default to char unless there's a \uXXXX in there somewhere. The latter might give rise to the (ugly) idiom: "Hello world!\u0000" to force wide char literal strings.It isn't proper way since D strings are not 0-terminated, so if you print it, the null char will be printed as well, I guess. But still the idea is interesting. The compiler should be able to determine whether string is char or wchar on his own. Also, if you have function overloaded for both, then it's not very likely that you have to force wchar literals, since char version would do exactly the same (e.g. print the string).Sidethread, you complain about the L"literal" syntax as ugly, but it's far less ugly than the cast.Yep, right. But still, L is hard to parse and to distinguish. I think that suffix would be better, "w" or something: "Hello, world!"W
Apr 05 2002
Pavel Minayev wrote:"Russell Borogove" <kaleja estarcion.com> wrote in message news:3CADFE2F.4070502 estarcion.com...Ohhh, crap. Well, I lobbied for padding (at least char and wchar) arrays with an extra zero-valued element to make conversion to C-strings easier way back when, but noooooooo....This language design thing is hard. :) Like you, I'd have to lean towards differentiating char and wchar literals, or default to char unless there's a \uXXXX in there somewhere. The latter might give rise to the (ugly) idiom: "Hello world!\u0000" to force wide char literal strings.It isn't proper way since D strings are not 0-terminated, so if you print it, the null char will be printed as well, I guess.But still the idea is interesting. The compiler should be able to determine whether string is char or wchar on his own. Also, if you have function overloaded for both, then it's not very likely that you have to force wchar literals, since char version would do exactly the same (e.g. print the string).I can contrive cases where the char and wchar versions do sufficiently different things (e.g. render from a 100KB TrueType font versus render from a 20MB TrueType font) that the impact would be significant, but even such cases aren't catastrophic. As you point out, the numeric promotions and conversions are probably more troublesome. -RB
Apr 05 2002
"Russell Borogove" <kaleja estarcion.com> wrote in message news:3CAE8210.4020908 estarcion.com...Ohhh, crap. Well, I lobbied for padding (at least char and wchar) arrays with an extra zero-valued element to make conversion to C-strings easier way back when, but noooooooo....Actually, D does 0 terminate them when it can, for just that reason. But if you slice an array out of another char[], it won't be 0 terminated.
Apr 05 2002
"Russell Borogove" <kaleja estarcion.com> wrote in message news:3CAE8210.4020908 estarcion.com...Ohhh, crap. Well, I lobbied for padding (at least char and wchar) arrays with an extra zero-valued element to make conversion to C-strings easier way back when, but noooooooo....Literals are terminated with 0 in memory. However, 0 is not considered element of the array: "foo" -> 'f', 'o', 'o', 0 "foo".length == 3;
Apr 06 2002
"Pavel Minayev" <evilone omen.ru> wrote in message news:a8mk4r$n0q$1 digitaldaemon.com..."Russell Borogove" <kaleja estarcion.com> wrote in message news:3CAE8210.4020908 estarcion.com...That's right. It's a bit of a hack, but a hack that works for the most common cases, like passing a string literal to printf!Ohhh, crap. Well, I lobbied for padding (at least char and wchar) arrays with an extra zero-valued element to make conversion to C-strings easier way back when, but noooooooo....Literals are terminated with 0 in memory. However, 0 is not considered element of the array: "foo" -> 'f', 'o', 'o', 0 "foo".length == 3;
Apr 06 2002
"Walter" <walter digitalmars.com> wrote in message news:a8nalt$1fsi$1 digitaldaemon.com...It's also great when interfacing with APIs and such. Well, it just works, and variables can always be converted using toStringz().Literals are terminated with 0 in memory. However, 0 is not considered element of the array: "foo" -> 'f', 'o', 'o', 0 "foo".length == 3;That's right. It's a bit of a hack, but a hack that works for the most common cases, like passing a string literal to printf!
Apr 06 2002
"Walter" <walter digitalmars.com> wrote in message news:a8kn36$2hic$1 digitaldaemon.com...I had the same thought, but I still haven't figured out what to do in ambiguous cases like: void foo(char[]); void foo(wchar[]); ... foo("hello"); Which gets called? Should it be an error?I guess it shouldn't. The reason is, you will probably define a wchar version for each string-handling function, and if it was considered an error, you wouldn't be able to call those functions with literals as arguments - which is convenient sometimes. I'd personally suggest to make some way to differentiate between char and wchar literals (but not that ugly L"..."!).In any case, I'm leaning towards initializing a delegate with the syntax: x = &o.func; and then using the context to figure out which overloaded func it shouldbe.This does add some complexity to the compiler I don't like.Well if function is NOT overloaded (which will most likely be the case), what's the sense of specifying parameters explicitly? Also, even for overloaded functions, I think the & syntax is better: x = &o.func(int, int);
Apr 05 2002