digitalmars.D - But... I don't want my delegates to be lazy - breeding advice
- Tom S (42/42) Aug 22 2006 Walter, if you *really* want to keep lazy expression evaluation in its
- kris (2/59) Aug 22 2006 Amen
- Lars Ivar Igesund (6/63) Aug 22 2006 Yes, I agree.
- Gregor Richards (3/60) Aug 22 2006 Hear hear, I agree 100%.
- Sean Kelly (3/56) Aug 22 2006 What he said :-p
- David Medlock (7/64) Aug 22 2006 I agree a keyword might be appropriate here, so as to ease the pain of
- Gregor Richards (15/18) Aug 22 2006 IMHO it has nothing to do with C/C++ programmers moving over. It's bad
- Wim Vander Schelden (2/55) Aug 22 2006 I agree completely.
- Walter Bright (3/56) Aug 22 2006 I think this is probably the most sensible proposal yet. Let me think
- Walter Bright (14/14) Aug 23 2006 Ok, I've thought about it a bit:
- Derek Parnell (30/52) Aug 24 2006 Thanks for do this Walter. The idea of converting expressions to delegat...
- Andy Knowles (21/43) Aug 24 2006 I think that is definitely a step in the right direction, and I think it...
- BCS (45/79) Aug 24 2006 (I'm one of the above mentioned people)
- Bruno Medeiros (4/53) Aug 24 2006 Indeed, "x()" is a better usage, however, if x is a delegate, then the
- BCS (12/30) Aug 24 2006 Delegates can't be used with implicit call syntax. You get a "can't
- Bruno Medeiros (6/42) Aug 25 2006 Hum, you're right. I was quite under the impression of the otherwise, I
- Sean Kelly (4/26) Aug 24 2006 Fantastic! This will even allow lazy values to be pre-constructed,
- Carlos Santander (5/62) Aug 22 2006 I think some things are over my head, but I have the feeling this makes ...
- Derek Parnell (20/48) Aug 22 2006 Well ... its the implicit conversion of expressions to delegates that
- Andy Knowles (28/85) Aug 23 2006 I agree, there should be some difference between a delegate and a lazy
- Lars Ivar Igesund (7/10) Aug 23 2006 I have to ask ... why is your username (melkesjokolade) on this site the
- Andy Knowles (6/15) Aug 23 2006 lol :P
- =?ISO-8859-1?Q?=22R=E9my_J=2E_A=2E_Mou=EBza=22?= (15/107) Aug 23 2006 Andy, is there a particular reason why you don't use the array
- Andy Knowles (17/31) Aug 23 2006 :)
Walter, if you *really* want to keep lazy expression evaluation in its current form, then please *at least* don't force everyone to use it. Adopting delegate function parameters for lazy expressions is a mistake. At least consider adding a new keyword, e.g. 'lazy' or 'expression', please. The syntax could look like: void foo(int expression() foo) { } or void foo(lazy int foo) { } or just some other variant. Delegates would then be delegates and wouldn't accept lazy expressions. But lazy expressions could accept delegates. The above approach has three significant advantages over the current state of things: 1. When the coder doesn't intend to use lazy expression evaluation, his/her functions that take delegates as params won't silently accept lazily evaluated expressions 2. Less existing code will be broken or the changes will be easier to fix - renaming the keyword to some other variable name compared to the nontrivial fixes that have to be done now. 3. In future, the 'expression' or 'lazy' types might provide meta-data allowing advanced metaprogramming techniques The third point is important because lazy expressions in their current form simply can't replace expression templates. Even by looking at the first resource available on google... http://osl.iu.edu/~tveldhui/papers/Expression-Templates/exprtmpl.html ... it's clear that one of the most important points behind expression templates is the ability to deconstruct expressions and basing on their internal structure, generate highly optimized code. At least that's what game developers use to make their linear algebra libraries as fast as possible. This is only possible by knowing the structure of the expression and applying localized and specialized optimizations. The 'expression' or 'lazy' types might work in a similar way. They would allow the programmer to inspect parse trees at compile-time and generate specially tailored code. Currently the only performance advantage that can be accomplished with lazy expression evaluation is when the compiler determines the delegate might be inlined, which currently doesn't happen at all. -- Tomasz Stachowiak
Aug 22 2006
Tom S wrote:Walter, if you *really* want to keep lazy expression evaluation in its current form, then please *at least* don't force everyone to use it. Adopting delegate function parameters for lazy expressions is a mistake. At least consider adding a new keyword, e.g. 'lazy' or 'expression', please. The syntax could look like: void foo(int expression() foo) { } or void foo(lazy int foo) { } or just some other variant. Delegates would then be delegates and wouldn't accept lazy expressions. But lazy expressions could accept delegates. The above approach has three significant advantages over the current state of things: 1. When the coder doesn't intend to use lazy expression evaluation, his/her functions that take delegates as params won't silently accept lazily evaluated expressions 2. Less existing code will be broken or the changes will be easier to fix - renaming the keyword to some other variable name compared to the nontrivial fixes that have to be done now. 3. In future, the 'expression' or 'lazy' types might provide meta-data allowing advanced metaprogramming techniques The third point is important because lazy expressions in their current form simply can't replace expression templates. Even by looking at the first resource available on google... http://osl.iu.edu/~tveldhui/papers/Expression-Templates/exprtmpl.html ... it's clear that one of the most important points behind expression templates is the ability to deconstruct expressions and basing on their internal structure, generate highly optimized code. At least that's what game developers use to make their linear algebra libraries as fast as possible. This is only possible by knowing the structure of the expression and applying localized and specialized optimizations. The 'expression' or 'lazy' types might work in a similar way. They would allow the programmer to inspect parse trees at compile-time and generate specially tailored code. Currently the only performance advantage that can be accomplished with lazy expression evaluation is when the compiler determines the delegate might be inlined, which currently doesn't happen at all. -- Tomasz StachowiakAmen
Aug 22 2006
Tom S wrote:Walter, if you *really* want to keep lazy expression evaluation in its current form, then please *at least* don't force everyone to use it. Adopting delegate function parameters for lazy expressions is a mistake. At least consider adding a new keyword, e.g. 'lazy' or 'expression', please. The syntax could look like: void foo(int expression() foo) { } or void foo(lazy int foo) { } or just some other variant. Delegates would then be delegates and wouldn't accept lazy expressions. But lazy expressions could accept delegates. The above approach has three significant advantages over the current state of things: 1. When the coder doesn't intend to use lazy expression evaluation, his/her functions that take delegates as params won't silently accept lazily evaluated expressions 2. Less existing code will be broken or the changes will be easier to fix - renaming the keyword to some other variable name compared to the nontrivial fixes that have to be done now. 3. In future, the 'expression' or 'lazy' types might provide meta-data allowing advanced metaprogramming techniques The third point is important because lazy expressions in their current form simply can't replace expression templates. Even by looking at the first resource available on google... http://osl.iu.edu/~tveldhui/papers/Expression-Templates/exprtmpl.html ... it's clear that one of the most important points behind expression templates is the ability to deconstruct expressions and basing on their internal structure, generate highly optimized code. At least that's what game developers use to make their linear algebra libraries as fast as possible. This is only possible by knowing the structure of the expression and applying localized and specialized optimizations. The 'expression' or 'lazy' types might work in a similar way. They would allow the programmer to inspect parse trees at compile-time and generate specially tailored code. Currently the only performance advantage that can be accomplished with lazy expression evaluation is when the compiler determines the delegate might be inlined, which currently doesn't happen at all. -- Tomasz StachowiakYes, I agree. -- Lars Ivar Igesund blog at http://larsivi.net DSource & #D: larsivi
Aug 22 2006
Tom S wrote:Walter, if you *really* want to keep lazy expression evaluation in its current form, then please *at least* don't force everyone to use it. Adopting delegate function parameters for lazy expressions is a mistake. At least consider adding a new keyword, e.g. 'lazy' or 'expression', please. The syntax could look like: void foo(int expression() foo) { } or void foo(lazy int foo) { } or just some other variant. Delegates would then be delegates and wouldn't accept lazy expressions. But lazy expressions could accept delegates. The above approach has three significant advantages over the current state of things: 1. When the coder doesn't intend to use lazy expression evaluation, his/her functions that take delegates as params won't silently accept lazily evaluated expressions 2. Less existing code will be broken or the changes will be easier to fix - renaming the keyword to some other variable name compared to the nontrivial fixes that have to be done now. 3. In future, the 'expression' or 'lazy' types might provide meta-data allowing advanced metaprogramming techniques The third point is important because lazy expressions in their current form simply can't replace expression templates. Even by looking at the first resource available on google... http://osl.iu.edu/~tveldhui/papers/Expression-Templates/exprtmpl.html ... it's clear that one of the most important points behind expression templates is the ability to deconstruct expressions and basing on their internal structure, generate highly optimized code. At least that's what game developers use to make their linear algebra libraries as fast as possible. This is only possible by knowing the structure of the expression and applying localized and specialized optimizations. The 'expression' or 'lazy' types might work in a similar way. They would allow the programmer to inspect parse trees at compile-time and generate specially tailored code. Currently the only performance advantage that can be accomplished with lazy expression evaluation is when the compiler determines the delegate might be inlined, which currently doesn't happen at all. -- Tomasz StachowiakHear hear, I agree 100%. - Gregor Richards
Aug 22 2006
Tom S wrote:Walter, if you *really* want to keep lazy expression evaluation in its current form, then please *at least* don't force everyone to use it. Adopting delegate function parameters for lazy expressions is a mistake. At least consider adding a new keyword, e.g. 'lazy' or 'expression', please. The syntax could look like: void foo(int expression() foo) { } or void foo(lazy int foo) { } or just some other variant. Delegates would then be delegates and wouldn't accept lazy expressions. But lazy expressions could accept delegates. The above approach has three significant advantages over the current state of things: 1. When the coder doesn't intend to use lazy expression evaluation, his/her functions that take delegates as params won't silently accept lazily evaluated expressions 2. Less existing code will be broken or the changes will be easier to fix - renaming the keyword to some other variable name compared to the nontrivial fixes that have to be done now. 3. In future, the 'expression' or 'lazy' types might provide meta-data allowing advanced metaprogramming techniques The third point is important because lazy expressions in their current form simply can't replace expression templates. Even by looking at the first resource available on google... http://osl.iu.edu/~tveldhui/papers/Expression-Templates/exprtmpl.html ... it's clear that one of the most important points behind expression templates is the ability to deconstruct expressions and basing on their internal structure, generate highly optimized code. At least that's what game developers use to make their linear algebra libraries as fast as possible. This is only possible by knowing the structure of the expression and applying localized and specialized optimizations. The 'expression' or 'lazy' types might work in a similar way. They would allow the programmer to inspect parse trees at compile-time and generate specially tailored code. Currently the only performance advantage that can be accomplished with lazy expression evaluation is when the compiler determines the delegate might be inlined, which currently doesn't happen at all.What he said :-p Sean
Aug 22 2006
Tom S wrote:Walter, if you *really* want to keep lazy expression evaluation in its current form, then please *at least* don't force everyone to use it. Adopting delegate function parameters for lazy expressions is a mistake. At least consider adding a new keyword, e.g. 'lazy' or 'expression', please. The syntax could look like: void foo(int expression() foo) { } or void foo(lazy int foo) { } or just some other variant. Delegates would then be delegates and wouldn't accept lazy expressions. But lazy expressions could accept delegates. The above approach has three significant advantages over the current state of things: 1. When the coder doesn't intend to use lazy expression evaluation, his/her functions that take delegates as params won't silently accept lazily evaluated expressions 2. Less existing code will be broken or the changes will be easier to fix - renaming the keyword to some other variable name compared to the nontrivial fixes that have to be done now. 3. In future, the 'expression' or 'lazy' types might provide meta-data allowing advanced metaprogramming techniques The third point is important because lazy expressions in their current form simply can't replace expression templates. Even by looking at the first resource available on google... http://osl.iu.edu/~tveldhui/papers/Expression-Templates/exprtmpl.html ... it's clear that one of the most important points behind expression templates is the ability to deconstruct expressions and basing on their internal structure, generate highly optimized code. At least that's what game developers use to make their linear algebra libraries as fast as possible. This is only possible by knowing the structure of the expression and applying localized and specialized optimizations. The 'expression' or 'lazy' types might work in a similar way. They would allow the programmer to inspect parse trees at compile-time and generate specially tailored code. Currently the only performance advantage that can be accomplished with lazy expression evaluation is when the compiler determines the delegate might be inlined, which currently doesn't happen at all. -- Tomasz StachowiakI agree a keyword might be appropriate here, so as to ease the pain of current C/C++ programmers moving to the Light side. While I am shooting my mouth off, let me chime in with those who think the *auto* keyword should be *var* for automatic type inferencing. I know keywords should be used sparingly but these are fairly big features. -DavidM
Aug 22 2006
David Medlock wrote:I agree a keyword might be appropriate here, so as to ease the pain of current C/C++ programmers moving to the Light side.IMHO it has nothing to do with C/C++ programmers moving over. It's bad because: 1) It's not intuitive to cast expressions into anonymous delegates. 2) It causes ridiculous overload issues: class A {...} class B : A {...} void q(A a); void q(void delegate() a); void whatever() { B b = new B(); q(b); // this should not be ambiguous, but is } 3) If I understand, the expression will be evaluated multiple times, once every time you use it in the function, unless you copy it into a different value, which is just painful. - Gregor Richards
Aug 22 2006
On Tue, 22 Aug 2006 18:39:57 +0100, Tom S wrote:Walter, if you *really* want to keep lazy expression evaluation in its current form, then please *at least* don't force everyone to use it. Adopting delegate function parameters for lazy expressions is a mistake. At least consider adding a new keyword, e.g. 'lazy' or 'expression', please. The syntax could look like: void foo(int expression() foo) { } or void foo(lazy int foo) { } or just some other variant. Delegates would then be delegates and wouldn't accept lazy expressions. But lazy expressions could accept delegates. The above approach has three significant advantages over the current state of things: 1. When the coder doesn't intend to use lazy expression evaluation, his/her functions that take delegates as params won't silently accept lazily evaluated expressions 2. Less existing code will be broken or the changes will be easier to fix - renaming the keyword to some other variable name compared to the nontrivial fixes that have to be done now. 3. In future, the 'expression' or 'lazy' types might provide meta-data allowing advanced metaprogramming techniques The third point is important because lazy expressions in their current form simply can't replace expression templates. Even by looking at the first resource available on google... http://osl.iu.edu/~tveldhui/papers/Expression-Templates/exprtmpl.html ... it's clear that one of the most important points behind expression templates is the ability to deconstruct expressions and basing on their internal structure, generate highly optimized code. At least that's what game developers use to make their linear algebra libraries as fast as possible. This is only possible by knowing the structure of the expression and applying localized and specialized optimizations. The 'expression' or 'lazy' types might work in a similar way. They would allow the programmer to inspect parse trees at compile-time and generate specially tailored code. Currently the only performance advantage that can be accomplished with lazy expression evaluation is when the compiler determines the delegate might be inlined, which currently doesn't happen at all.I agree completely.
Aug 22 2006
Tom S wrote:Walter, if you *really* want to keep lazy expression evaluation in its current form, then please *at least* don't force everyone to use it. Adopting delegate function parameters for lazy expressions is a mistake. At least consider adding a new keyword, e.g. 'lazy' or 'expression', please. The syntax could look like: void foo(int expression() foo) { } or void foo(lazy int foo) { } or just some other variant. Delegates would then be delegates and wouldn't accept lazy expressions. But lazy expressions could accept delegates. The above approach has three significant advantages over the current state of things: 1. When the coder doesn't intend to use lazy expression evaluation, his/her functions that take delegates as params won't silently accept lazily evaluated expressions 2. Less existing code will be broken or the changes will be easier to fix - renaming the keyword to some other variable name compared to the nontrivial fixes that have to be done now. 3. In future, the 'expression' or 'lazy' types might provide meta-data allowing advanced metaprogramming techniques The third point is important because lazy expressions in their current form simply can't replace expression templates. Even by looking at the first resource available on google... http://osl.iu.edu/~tveldhui/papers/Expression-Templates/exprtmpl.html ... it's clear that one of the most important points behind expression templates is the ability to deconstruct expressions and basing on their internal structure, generate highly optimized code. At least that's what game developers use to make their linear algebra libraries as fast as possible. This is only possible by knowing the structure of the expression and applying localized and specialized optimizations. The 'expression' or 'lazy' types might work in a similar way. They would allow the programmer to inspect parse trees at compile-time and generate specially tailored code. Currently the only performance advantage that can be accomplished with lazy expression evaluation is when the compiler determines the delegate might be inlined, which currently doesn't happen at all.I think this is probably the most sensible proposal yet. Let me think about it a bit.
Aug 22 2006
Ok, I've thought about it a bit: void foo(int x); // same as before 0.165 void foo(int delegate() x) // same as before 0.165 and now: void foo(lazy int x); In other words, 'lazy' is now a parameter storage class. This means that: void foo(int x); void foo(lazy int x); cannot be distinguished based on overloading, but: void foo(lazy int x); void foo(int delegate() x); can be. The implicit conversion of a value to a delegate returning that value would be removed. The conversion happens always (not implicitly) if the parameter storage class is 'lazy'.
Aug 23 2006
On Wed, 23 Aug 2006 22:54:35 -0700, Walter Bright wrote:Ok, I've thought about it a bit: void foo(int x); // same as before 0.165 void foo(int delegate() x) // same as before 0.165 and now: void foo(lazy int x); In other words, 'lazy' is now a parameter storage class. This means that: void foo(int x); void foo(lazy int x); cannot be distinguished based on overloading, but: void foo(lazy int x); void foo(int delegate() x); can be. The implicit conversion of a value to a delegate returning that value would be removed. The conversion happens always (not implicitly) if the parameter storage class is 'lazy'.Thanks for do this Walter. The idea of converting expressions to delegates is a good one, and with these changes proposed here it removes a lot of the 'gotchas' that come with implicit conversions. (uint --> int --> uint, and long --> int --> short are still sore points, BTW). I also assume that the mutability of lazy parameters is identical to the 'in' parameter storage class. That is, any changes to the actual value passed to the function are never passed back to the caller, but that doesn't stop one modifying data passed as references. import std.stdio; void foo(lazy char[] x) { x[0..2] = x[1..2] ~ x[0..1]; x ~= "k"; writefln("%s", x); // --> "back"; } void main() { char[] d = "abc"; foo( d ); writefln("%s", d); // --> "bac"; } -- Derek (skype: derek.j.parnell) Melbourne, Australia "Down with mediocrity!" 24/08/2006 4:45:03 PM
Aug 24 2006
Walter Bright wrote:Ok, I've thought about it a bit: void foo(int x); // same as before 0.165 void foo(int delegate() x) // same as before 0.165 and now: void foo(lazy int x); In other words, 'lazy' is now a parameter storage class. This means that: void foo(int x); void foo(lazy int x); cannot be distinguished based on overloading, but: void foo(lazy int x); void foo(int delegate() x); can be. The implicit conversion of a value to a delegate returning that value would be removed. The conversion happens always (not implicitly) if the parameter storage class is 'lazy'.I think that is definitely a step in the right direction, and I think it will make people a lot more comfortable. Some questions: 1) While in void foo(lazy int x) will x be evaluated using x() or just x? Either one could lead to confusion. 2) What are your thoughts on allowing {2*x} as a shortcut for { return 2*x; }? This would only apply to delegates of course, but may still be useful in places. 3) Any thoughts on a shortcut syntax for arguments to delegates? It would be nice to be able to write: int[] map(int[] arr, int delegate(int) func); int[] b = map(a, (x){ 2*x }); or something similar. At the moment we must write either: int[] map(int[] arr, int delegate(int) func); int[] b = map(a, (int x){ return 2*x; }); or: int[] map(int[] arr, out int arg, lazy int func); int x; int[] b = map(a, x, 2*x); Andy
Aug 24 2006
Andy Knowles wrote:Walter Bright wrote:I like that a lot better.Ok, I've thought about it a bit: void foo(int x); // same as before 0.165 void foo(int delegate() x) // same as before 0.165 and now: void foo(lazy int x); In other words, 'lazy' is now a parameter storage class. This means that: void foo(int x); void foo(lazy int x); cannot be distinguished based on overloading, but: void foo(lazy int x); void foo(int delegate() x); can be. The implicit conversion of a value to a delegate returning that value would be removed. The conversion happens always (not implicitly) if the parameter storage class is 'lazy'.I think that is definitely a step in the right direction, and I think it will make people a lot more comfortable.(I'm one of the above mentioned people)Some questions: 1) While in void foo(lazy int x) will x be evaluated using x() or just x? Either one could lead to confusion.I'd go for "x()", because 1> it more closely reflects what is actually happening. 2> it allows x to be used to refer to the delegate 3> it is semantically different than a value parameter. This will force you to look at each use while converting a function to lazy use. This is coming from the "when its easy, broken code shouldn't compile" school of thought. OTOH pros for the "x" version 1> the compiler could handle the code to detect the first usage and evaluate it once and use the evaluated version thereafter. This would automate the generation and optimization of a lot of "hard to follow code". However that would be to much to trust the compiler in if you ask me. But it would make for some neat code. void foo(Person[] people, lazy char[] here) { foreach(man;people) if(man.IsHere) writef(man.name ~" is at "~here~\n); } becomes void foo(Person[] people, lazy char[] here) { int __j; foreach(__i, man;people) if(man.IsHere) { __j = __i; goto __eval; } return; __eval: char[] __here = EVAL(here); // sudo code writef(people[__j].name ~" is at "~__here~\n); foreach(man;people[__j+1..$) if(man.IsHere) writef(man.name ~" is at "~__here~\n); } Vary tight code. Now, try writhing that by hand with three lazy argument and 6 places each that they could get evaluated for the first time. That would be a cake walk for a code generator and a nightmare for a programmer.
Aug 24 2006
BCS wrote:Andy Knowles wrote:Indeed, "x()" is a better usage, however, if x is a delegate, then the "x" usage will still be allowed, due to the implicit call syntax (aka property syntax).Walter Bright wrote:I like that a lot better.Ok, I've thought about it a bit: void foo(int x); // same as before 0.165 void foo(int delegate() x) // same as before 0.165 and now: void foo(lazy int x); In other words, 'lazy' is now a parameter storage class. This means that: void foo(int x); void foo(lazy int x); cannot be distinguished based on overloading, but: void foo(lazy int x); void foo(int delegate() x); can be. The implicit conversion of a value to a delegate returning that value would be removed. The conversion happens always (not implicitly) if the parameter storage class is 'lazy'.I think that is definitely a step in the right direction, and I think it will make people a lot more comfortable.(I'm one of the above mentioned people)Some questions: 1) While in void foo(lazy int x) will x be evaluated using x() or just x? Either one could lead to confusion.I'd go for "x()", because 1> it more closely reflects what is actually happening. 2> it allows x to be used to refer to the delegate
Aug 24 2006
Bruno Medeiros wrote:BCS wrote:Delegates can't be used with implicit call syntax. You get a "can't convert T delegate() to T" error. void main() { int dg() { return 1; } int i = dg; int delegate() t = &dg; i = t; } d.d(7): cannot implicitly convert expression (t) of type int delegate() to intAndy Knowles wrote:Indeed, "x()" is a better usage, however, if x is a delegate, then the "x" usage will still be allowed, due to the implicit call syntax (aka property syntax).1) While in void foo(lazy int x) will x be evaluated using x() or just x? Either one could lead to confusion.I'd go for "x()", because 1> it more closely reflects what is actually happening. 2> it allows x to be used to refer to the delegate
Aug 24 2006
BCS wrote:Bruno Medeiros wrote:Hum, you're right. I was quite under the impression of the otherwise, I wonder where I got that from. :7 -- Bruno Medeiros - MSc in CS/E student http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#DBCS wrote:Delegates can't be used with implicit call syntax. You get a "can't convert T delegate() to T" error. void main() { int dg() { return 1; } int i = dg; int delegate() t = &dg; i = t; } d.d(7): cannot implicitly convert expression (t) of type int delegate() to intAndy Knowles wrote:Indeed, "x()" is a better usage, however, if x is a delegate, then the "x" usage will still be allowed, due to the implicit call syntax (aka property syntax).1) While in void foo(lazy int x) will x be evaluated using x() or just x? Either one could lead to confusion.I'd go for "x()", because 1> it more closely reflects what is actually happening. 2> it allows x to be used to refer to the delegate
Aug 25 2006
Walter Bright wrote:Ok, I've thought about it a bit: void foo(int x); // same as before 0.165 void foo(int delegate() x) // same as before 0.165 and now: void foo(lazy int x); In other words, 'lazy' is now a parameter storage class. This means that: void foo(int x); void foo(lazy int x); cannot be distinguished based on overloading, but: void foo(lazy int x); void foo(int delegate() x); can be. The implicit conversion of a value to a delegate returning that value would be removed. The conversion happens always (not implicitly) if the parameter storage class is 'lazy'.Fantastic! This will even allow lazy values to be pre-constructed, which is a nice perk. Sean
Aug 24 2006
Tom S escribió:Walter, if you *really* want to keep lazy expression evaluation in its current form, then please *at least* don't force everyone to use it. Adopting delegate function parameters for lazy expressions is a mistake. At least consider adding a new keyword, e.g. 'lazy' or 'expression', please. The syntax could look like: void foo(int expression() foo) { } or void foo(lazy int foo) { } or just some other variant. Delegates would then be delegates and wouldn't accept lazy expressions. But lazy expressions could accept delegates. The above approach has three significant advantages over the current state of things: 1. When the coder doesn't intend to use lazy expression evaluation, his/her functions that take delegates as params won't silently accept lazily evaluated expressions 2. Less existing code will be broken or the changes will be easier to fix - renaming the keyword to some other variable name compared to the nontrivial fixes that have to be done now. 3. In future, the 'expression' or 'lazy' types might provide meta-data allowing advanced metaprogramming techniques The third point is important because lazy expressions in their current form simply can't replace expression templates. Even by looking at the first resource available on google... http://osl.iu.edu/~tveldhui/papers/Expression-Templates/exprtmpl.html .... it's clear that one of the most important points behind expression templates is the ability to deconstruct expressions and basing on their internal structure, generate highly optimized code. At least that's what game developers use to make their linear algebra libraries as fast as possible. This is only possible by knowing the structure of the expression and applying localized and specialized optimizations. The 'expression' or 'lazy' types might work in a similar way. They would allow the programmer to inspect parse trees at compile-time and generate specially tailored code. Currently the only performance advantage that can be accomplished with lazy expression evaluation is when the compiler determines the delegate might be inlined, which currently doesn't happen at all. -- Tomasz StachowiakI think some things are over my head, but I have the feeling this makes sense. Besides, everyone else has agreed :D -- Carlos Santander Bernal
Aug 22 2006
On Tue, 22 Aug 2006 18:39:57 +0100, Tom S wrote:Walter, if you *really* want to keep lazy expression evaluation in its current form, then please *at least* don't force everyone to use it.Amen to that!Adopting delegate function parameters for lazy expressions is a mistake.Well ... its the implicit conversion of expressions to delegates that concerns me. I can see that most of the time it should be harmless, but it still opens the window of opportunity for seriously long debugging sessions.At least consider adding a new keyword, e.g. 'lazy' or 'expression', please. The syntax could look like: void foo(int expression() foo) { } or void foo(lazy int foo) { }or ... void foo( delegate int () foo) {} void foo( expression int () foo) {}or just some other variant. Delegates would then be delegates and wouldn't accept lazy expressions. But lazy expressions could accept delegates. The above approach has three significant advantages over the current state of things: 1. When the coder doesn't intend to use lazy expression evaluation, his/her functions that take delegates as params won't silently accept lazily evaluated expressionsA big plus, in the manner of "least surprise".2. Less existing code will be broken or the changes will be easier to fix - renaming the keyword to some other variable name compared to the nontrivial fixes that have to be done now.This also enhances understanding when reading someone else's code. It allows better understanding of the coder's intentions.3. In future, the 'expression' or 'lazy' types might provide meta-data allowing advanced metaprogramming techniquesHmmm ... interesting. -- Derek (skype: derek.j.parnell) Melbourne, Australia "Down with mediocrity!" 23/08/2006 2:30:50 PM
Aug 22 2006
Tom S wrote:Walter, if you *really* want to keep lazy expression evaluation in its current form, then please *at least* don't force everyone to use it. Adopting delegate function parameters for lazy expressions is a mistake. At least consider adding a new keyword, e.g. 'lazy' or 'expression', please. The syntax could look like: void foo(int expression() foo) { } or void foo(lazy int foo) { } or just some other variant. Delegates would then be delegates and wouldn't accept lazy expressions. But lazy expressions could accept delegates. The above approach has three significant advantages over the current state of things: 1. When the coder doesn't intend to use lazy expression evaluation, his/her functions that take delegates as params won't silently accept lazily evaluated expressions 2. Less existing code will be broken or the changes will be easier to fix - renaming the keyword to some other variable name compared to the nontrivial fixes that have to be done now. 3. In future, the 'expression' or 'lazy' types might provide meta-data allowing advanced metaprogramming techniques The third point is important because lazy expressions in their current form simply can't replace expression templates. Even by looking at the first resource available on google... http://osl.iu.edu/~tveldhui/papers/Expression-Templates/exprtmpl.html ... it's clear that one of the most important points behind expression templates is the ability to deconstruct expressions and basing on their internal structure, generate highly optimized code. At least that's what game developers use to make their linear algebra libraries as fast as possible. This is only possible by knowing the structure of the expression and applying localized and specialized optimizations. The 'expression' or 'lazy' types might work in a similar way. They would allow the programmer to inspect parse trees at compile-time and generate specially tailored code. Currently the only performance advantage that can be accomplished with lazy expression evaluation is when the compiler determines the delegate might be inlined, which currently doesn't happen at all. -- Tomasz StachowiakI agree, there should be some difference between a delegate and a lazy expression. Besides fixing an overload ambiguity, this would leave the door open to extensions to lazy expressions that won't necessarily make sense for delegates. The reason people tout LISP (not that I have used it more than I absolutely had to) as having power that other languages do not is not the lazy evaluation of expressions but the ability to decompose, examine and alter the expression tree using the same code as for any other LISP data structure (since they're all the same anyway). The reason people think Expression templates in C++ are so impressive is not lazy evaluation - it's compile-time inline insertion of user code into library functions. So when I write math::integrate(x*x + 2*x + 1, x, 0, 3) I know that my quadratic expression is inserted directly into the inner-most loop of the integral function and incurs no overhead per iteration. more than syntactic sugar for anonymous delegates (which it already has and is improving). The point is that an expression template is not compiled into code but into a data structure that can be explored at into an efficient SQL query. Having said all that, the syntax does open some functional-programming doors to D. I knocked this up while experimenting. Note the need to pass in the expression argument as a separate parameter - something a => a * 2 could fix (or some other syntax). http://www.members.iinet.net.au/~melkesjokolade/functional.d Andy
Aug 23 2006
Andy Knowles wrote:http://www.members.iinet.net.au/~melkesjokolade/functional.d AndyI have to ask ... why is your username (melkesjokolade) on this site the norwegian word for milk chocolate? :D -- Lars Ivar Igesund blog at http://larsivi.net DSource & #D: larsivi
Aug 23 2006
Lars Ivar Igesund wrote:Andy Knowles wrote:lol :P my gf is norwegian and we needed a username that was valid for us both and guaranteed not to be taken. melkesjokolade came to mind, and we both thought it would be suitably confusing to anyone who noticed :D Andyhttp://www.members.iinet.net.au/~melkesjokolade/functional.d AndyI have to ask ... why is your username (melkesjokolade) on this site the norwegian word for milk chocolate? :D
Aug 23 2006
Andy, is there a particular reason why you don't use the array concatenation operator in your select ( and others ) function(s) ? Like this one : ) predicate ) Andy Knowles a écrit :Tom S wrote:Walter, if you *really* want to keep lazy expression evaluation in its current form, then please *at least* don't force everyone to use it. Adopting delegate function parameters for lazy expressions is a mistake. At least consider adding a new keyword, e.g. 'lazy' or 'expression', please. The syntax could look like: void foo(int expression() foo) { } or void foo(lazy int foo) { } or just some other variant. Delegates would then be delegates and wouldn't accept lazy expressions. But lazy expressions could accept delegates. The above approach has three significant advantages over the current state of things: 1. When the coder doesn't intend to use lazy expression evaluation, his/her functions that take delegates as params won't silently accept lazily evaluated expressions 2. Less existing code will be broken or the changes will be easier to fix - renaming the keyword to some other variable name compared to the nontrivial fixes that have to be done now. 3. In future, the 'expression' or 'lazy' types might provide meta-data allowing advanced metaprogramming techniques The third point is important because lazy expressions in their current form simply can't replace expression templates. Even by looking at the first resource available on google... http://osl.iu.edu/~tveldhui/papers/Expression-Templates/exprtmpl.html ... it's clear that one of the most important points behind expression templates is the ability to deconstruct expressions and basing on their internal structure, generate highly optimized code. At least that's what game developers use to make their linear algebra libraries as fast as possible. This is only possible by knowing the structure of the expression and applying localized and specialized optimizations. The 'expression' or 'lazy' types might work in a similar way. They would allow the programmer to inspect parse trees at compile-time and generate specially tailored code. Currently the only performance advantage that can be accomplished with lazy expression evaluation is when the compiler determines the delegate might be inlined, which currently doesn't happen at all. -- Tomasz StachowiakI agree, there should be some difference between a delegate and a lazy expression. Besides fixing an overload ambiguity, this would leave the door open to extensions to lazy expressions that won't necessarily make sense for delegates. The reason people tout LISP (not that I have used it more than I absolutely had to) as having power that other languages do not is not the lazy evaluation of expressions but the ability to decompose, examine and alter the expression tree using the same code as for any other LISP data structure (since they're all the same anyway). The reason people think Expression templates in C++ are so impressive is not lazy evaluation - it's compile-time inline insertion of user code into library functions. So when I write math::integrate(x*x + 2*x + 1, x, 0, 3) I know that my quadratic expression is inserted directly into the inner-most loop of the integral function and incurs no overhead per iteration. more than syntactic sugar for anonymous delegates (which it already has and is improving). The point is that an expression template is not compiled into code but into a data structure that can be explored at into an efficient SQL query. Having said all that, the syntax does open some functional-programming doors to D. I knocked this up while experimenting. Note the need to pass in the expression argument as a separate parameter - something a => a * 2 could fix (or some other syntax). http://www.members.iinet.net.au/~melkesjokolade/functional.d Andy
Aug 23 2006
Rémy J. A. Mouëza wrote:Andy, is there a particular reason why you don't use the array concatenation operator in your select ( and others ) function(s) ? Like this one : ) predicate ):) An excellent question! Frankly, I forgot about it. While I pay close attention to D's development and these news groups, I rarely get a chance to write D code. It *might* be better to (over)allocate only once (as I do) rather than realloc the array who knows how many times. Depends on usage really - wasted space on one hand, wasted cycles on the other. For the range function, it depends how Walter's realloc code works. I know it allocates more than it needs to, but I don't know what factor or constant it increase the size by. Depends again on usage which is the better option. I should probably just use the concat operator and leave the performance tuning for when it is really needed. And of course, you can't use a predicate with an argument if you want to use lazy evaluation, even though it makes the code more logical. Andy
Aug 23 2006