D - arrays of delegates
- Pavel Minayev (17/17) Apr 14 2002 An idea came to my mind. D allows operators to be applied to the entire
- Russ Lewis (6/6) Apr 14 2002 Great thinking, Pavel!!!
- Walter (3/20) Apr 14 2002 That is a neat idea.
- Patrick Down (20/26) Apr 14 2002 Can we apply this to arrays of objects too?
- Russ Lewis (12/12) Apr 14 2002 Suddenly, when we least expect it, we have a convenient syntax for
- Patrick Down (6/12) Apr 14 2002 Actually I see no reason why this shouldn't work.
- Russ Lewis (22/34) Apr 14 2002 There would also have to be a spec on how to do arguments. Consider:
- Patrick Down (8/37) Apr 14 2002 I would argue for the former. :) If you adopt this method then
- Pavel Minayev (7/13) Apr 15 2002 Where you want a loop, it's better to state it clearly by making
- Russ Lewis (10/25) Apr 15 2002 They both are convincing arguments. I guess that whatever the syntax
- Patrick Down (10/18) Apr 15 2002 Ok I've changed my mind. :) fred() should only be executed once.
- Russ Lewis (15/19) Apr 15 2002 The first syntax makes sense to me from my ksh programming...but it
- Robert W. Cunningham (21/34) Apr 15 2002 Wouldn't it be simpler to restrict the kinds of arguments that delegates
- Pavel Minayev (7/11) Apr 15 2002 No, it doesn't:
- Walter (10/16) Apr 16 2002 That's a point worth repeating. I'm willing to sacrifice some expressive
- Roland (4/20) Apr 16 2002 Yes..i should have posted my last post (D and real macros) in chat..
- J. Daniel Smith (21/38) Apr 15 2002 Actually, this is exactly the behavior you get from C# when using the
An idea came to my mind. D allows operators to be applied to the entire array, so, for example, foo[]++ should be equal to: for (uint i = 0; i < foo.length; i++) foo[i]++; Now, if we just think of () as of "call delegate" operator (and obviously it is), then foo[]() should be treated as: for (uint i = 0; i < foo.length; i++) foo[i](); Seems logical, doesn't it? And makes it easy to have arrays of delegates without clumsy wrappers: void delegate(int x, int y)[] onMouseMove; void mouseMoved(int x, int y) { onMouseMove[](x, y); } // call 'em all! wnd.onMouseMove ~= &handler1; wnd.onMouseMove ~= &handler2; ...
Apr 14 2002
Great thinking, Pavel!!! -- The Villagers are Online! http://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 14 2002
That is a neat idea. "Pavel Minayev" <evilone omen.ru> wrote in message news:a9bpa5$12pe$1 digitaldaemon.com...An idea came to my mind. D allows operators to be applied to the entire array, so, for example, foo[]++ should be equal to: for (uint i = 0; i < foo.length; i++) foo[i]++; Now, if we just think of () as of "call delegate" operator (and obviously it is), then foo[]() should be treated as: for (uint i = 0; i < foo.length; i++) foo[i](); Seems logical, doesn't it? And makes it easy to have arrays of delegates without clumsy wrappers: void delegate(int x, int y)[] onMouseMove; void mouseMoved(int x, int y) { onMouseMove[](x, y); } // call 'em all! wnd.onMouseMove ~= &handler1; wnd.onMouseMove ~= &handler2; ...
Apr 14 2002
"Pavel Minayev" <evilone omen.ru> wrote in news:a9bpa5$12pe$1 digitaldaemon.com:Now, if we just think of () as of "call delegate" operator (and obviously it is), then foo[]() should be treated as: for (uint i = 0; i < foo.length; i++) foo[i]();Can we apply this to arrays of objects too? class Foo { void Bar() { } void Fred() { } } Foo[] arr; arr[].Bar(); // ?? Or perhaps... with(arr[]) { Bar(); Fred(); }
Apr 14 2002
Suddenly, when we least expect it, we have a convenient syntax for "foreach" constructs. :) Of course, we can't use the return code from it (unless all of the return codes are packed into an array the same length as arr[] Nor is it totally clear what happens during exceptions. Perhaps we need a meta-variable that would tell us which index we were working on when the exception was thrown? -- The Villagers are Online! http://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 14 2002
Russ Lewis <spamhole-2001-07-16 deming-os.org> wrote in news:3CBA03E6.BF5DB7FD deming-os.org:Suddenly, when we least expect it, we have a convenient syntax for "foreach" constructs. :) Of course, we can't use the return code from it (unless all of the return codes are packed into an array the same length as arr[]Actually I see no reason why this shouldn't work. int[] a; Foo[] b; a[] = b[].Bar();
Apr 14 2002
Patrick Down wrote:Russ Lewis <spamhole-2001-07-16 deming-os.org> wrote in news:3CBA03E6.BF5DB7FD deming-os.org:There would also have to be a spec on how to do arguments. Consider: int Fred(); b[].Baz(Fred()); does this expand to: for(int i=0; i<b.length; i++) b[i].Baz(Fred()); or { int temp = Fred(); for(int i=0; i<b.length; i++) b[i].Baz(temp); } The difference could be very significant if Fred() actually did something (some side effect), or if Fred() had a long running time. I would argue for the latter, but would be very uncomfortable with it if the community didn't generally agree that that was the "right" (i.e. the anticipated) spec. Few things are worse than having something you *think* works one way, but works the opposite... -- The Villagers are Online! http://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))) ]Suddenly, when we least expect it, we have a convenient syntax for "foreach" constructs. :) Of course, we can't use the return code from it (unless all of the return codes are packed into an array the same length as arr[]Actually I see no reason why this shouldn't work. int[] a; Foo[] b; a[] = b[].Bar();
Apr 14 2002
Russ Lewis <spamhole-2001-07-16 deming-os.org> wrote in news:3CBA6047.B188929 deming-os.org:Patrick Down wrote:I would argue for the former. :) If you adopt this method then the latter example can always be constructed like this... int temp = Fred(); b[].Baz(temp) but it's impossible to go the other way without explictily making the loop.Russ Lewis <spamhole-2001-07-16 deming-os.org> wrote in news:3CBA03E6.BF5DB7FD deming-os.org:There would also have to be a spec on how to do arguments. Consider: int Fred(); b[].Baz(Fred()); does this expand to: for(int i=0; i<b.length; i++) b[i].Baz(Fred()); or { int temp = Fred(); for(int i=0; i<b.length; i++) b[i].Baz(temp); } The difference could be very significant if Fred() actually did something (some side effect), or if Fred() had a long running time. I would argue for the latter, but would be very uncomfortable with it if the community didn't generally agree that that was the "right" (i.e. the anticipated) spec. Few things are worse than having something you *think* works one way, but works the opposite...Suddenly, when we least expect it, we have a convenient syntax for "foreach" constructs. :) Of course, we can't use the return code from it (unless all of the
Apr 14 2002
"Patrick Down" <pat codemoon.com> wrote in message news:Xns91F1EBD9CDFFpatcodemooncom 63.105.9.61...I would argue for the former. :) If you adopt this method then the latter example can always be constructed like this... int temp = Fred(); b[].Baz(temp) but it's impossible to go the other way without explictily making the loop.Where you want a loop, it's better to state it clearly by making a loop. However, when you write: b[].baz(fred()); You only see fred() once in the expression, so, IMO, it should be evaluated only once.
Apr 15 2002
Pavel Minayev wrote:"Patrick Down" <pat codemoon.com> wrote in message news:Xns91F1EBD9CDFFpatcodemooncom 63.105.9.61...They both are convincing arguments. I guess that whatever the syntax is, it should match all other array operations. Does b[] += fred(); call fred() once or many times? -- 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))) ]I would argue for the former. :) If you adopt this method then the latter example can always be constructed like this... int temp = Fred(); b[].Baz(temp) but it's impossible to go the other way without explictily making the loop.Where you want a loop, it's better to state it clearly by making a loop. However, when you write: b[].baz(fred()); You only see fred() once in the expression, so, IMO, it should be evaluated only once.
Apr 15 2002
"Pavel Minayev" <evilone omen.ru> wrote in news:a9e8cb$elj$1 digitaldaemon.com:Where you want a loop, it's better to state it clearly by making a loop. However, when you write: b[].baz(fred()); You only see fred() once in the expression, so, IMO, it should be evaluated only once.Ok I've changed my mind. :) fred() should only be executed once. My problem is that I want some sort of foreach construct in D and was trying to make the vector syntax fit that role. For the other problem I'd rather have this. foreach(a in b[]) // foreach(a,b[]), foreach(a,b) ?? { a.baz(fred()); }
Apr 15 2002
Patrick Down wrote:foreach(a in b[]) // foreach(a,b[]), foreach(a,b) ?? { a.baz(fred()); }The first syntax makes sense to me from my ksh programming...but it would seem to conflict with the normal use of "in" - to test for presence of a key. What about "of" ? foreach(a of b[]) { a.baz(fred()); } 'a' would automatically get its type from the underlying type of the array. -- 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 15 2002
Patrick Down wrote:"Pavel Minayev" <evilone omen.ru> wrote in news:a9e8cb$elj$1 digitaldaemon.com:Wouldn't it be simpler to restrict the kinds of arguments that delegates are allowed to have? For example, require that delegates must have only discrete pass-by-value parameters. Concerns about single versus multiple argument evaluation should then go away. Delegate arrays are a powerful tool, and any limits placed on them should be there only to make them more generally useful. Restricting the arguments would simply mean the programmer would have to write code to circumvent the restriction (pass a function pointer in the above example, and call it within each delegate), which makes the risk explicit in the code instead of implicit in the language. That's good programming practice and good language design. Don't make the risky stuff (like side effects) impossible. But don't make them too easy either. And don't muck things up by mandating special execution behavior (single versus multiple evaluation) for delegate arrays: That just makes using delegate arrays more complex. Who will remember the rules correctly every time? (Other than Pavel, of course!) The compiler won't be able to help much in such situations unless the restrictions can be easily flagged at compile time (and easily fixed). Let's not make things so complex that we'll need a lint for D! -BobCWhere you want a loop, it's better to state it clearly by making a loop. However, when you write: b[].baz(fred()); You only see fred() once in the expression, so, IMO, it should be evaluated only once.Ok I've changed my mind. :) fred() should only be executed once. My problem is that I want some sort of foreach construct in D and was trying to make the vector syntax fit that role.
Apr 15 2002
"Robert W. Cunningham" <rcunning acm.org> wrote in message news:3CBB9E37.1B196FB6 acm.org...Wouldn't it be simpler to restrict the kinds of arguments that delegates are allowed to have? For example, require that delegates must have only discrete pass-by-value parameters. Concerns about single versus multiple argument evaluation should then go away.No, it doesn't: foo[].bar(baz()); Don't forget that baz() might do something as well, as well as return different values each time it's called. So the behaviour of this code could depend on whethe baz() is called once or many times.
Apr 15 2002
"Robert W. Cunningham" <rcunning acm.org> wrote in message news:3CBB9E37.1B196FB6 acm.org...That's good programming practice and good language design. Don't make the risky stuff (like side effects) impossible. But don't make them too easy either. And don't muck things up by mandating special execution behavior (single versus multiple evaluation) for delegate arrays: That just makes using delegate arrays more complex. Who will remember the rules correctly every time?That's a point worth repeating. I'm willing to sacrifice some expressive power of the language to gain orthogonality, consistency, and clarity in understanding code written by others. Every special case rule added to the language substantially reduces this, making it harder to learn/remember the language, and harder to read other peoples' code. That's also why D uses C's operator priority and integral promotion rules verbatim - such rules are a mess, but programmers are so used to them that changing them would be like trying to get people to switch from QWERTY to Dvorak.
Apr 16 2002
Walter a écrit :"Robert W. Cunningham" <rcunning acm.org> wrote in message news:3CBB9E37.1B196FB6 acm.org...Yes..i should have posted my last post (D and real macros) in chat.. It is not D phylosophy, but it is still interesting i hope. rolandThat's good programming practice and good language design. Don't make the risky stuff (like side effects) impossible. But don't make them too easy either. And don't muck things up by mandating special execution behavior (single versus multiple evaluation) for delegate arrays: That just makes using delegate arrays more complex. Who will remember the rules correctly every time?That's a point worth repeating. I'm willing to sacrifice some expressive power of the language to gain orthogonality, consistency, and clarity in understanding code written by others. Every special case rule added to the language substantially reduces this, making it harder to learn/remember the language, and harder to read other peoples' code. That's also why D uses C's operator priority and integral promotion rules verbatim - such rules are a mess, but programmers are so used to them that changing them would be like trying to get people to switch from QWERTY to Dvorak.
Apr 16 2002
"event" keyword. See thread "More on Delegats" (in "D alpha 26") for sample void Fire_MyEvent(int event_data) { for (int i=0; i<MyEvent.length; i++) { dg_t e = MyEvent[i]; e(event_data); } becomes void Fire_MyEvent(int event_data) { MyEvent[](event_data) } public void Fire_MyEvent(int event_data) { MyEvent(event_data); } Dan "Pavel Minayev" <evilone omen.ru> wrote in message news:a9bpa5$12pe$1 digitaldaemon.com...An idea came to my mind. D allows operators to be applied to the entire array, so, for example, foo[]++ should be equal to: for (uint i = 0; i < foo.length; i++) foo[i]++; Now, if we just think of () as of "call delegate" operator (and obviously it is), then foo[]() should be treated as: for (uint i = 0; i < foo.length; i++) foo[i](); Seems logical, doesn't it? And makes it easy to have arrays of delegates without clumsy wrappers: void delegate(int x, int y)[] onMouseMove; void mouseMoved(int x, int y) { onMouseMove[](x, y); } // call 'em all! wnd.onMouseMove ~= &handler1; wnd.onMouseMove ~= &handler2; ...
Apr 15 2002