digitalmars.D - DIP27 available for destruction
- "deadalnix" <deadalnix gmail.com> Feb 26 2013
- "Dicebot" <m.strashun gmail.com> Feb 26 2013
- Timon Gehr <timon.gehr gmx.ch> Feb 26 2013
- Timon Gehr <timon.gehr gmx.ch> Feb 26 2013
- Dmitry Olshansky <dmitry.olsh gmail.com> Feb 26 2013
- Dmitry Olshansky <dmitry.olsh gmail.com> Feb 26 2013
- Andrej Mitrovic <andrej.mitrovich gmail.com> Feb 26 2013
- "Joshua Niehus" <jm.niehus gmail.com> Feb 26 2013
- "Dicebot" <m.strashun gmail.com> Feb 26 2013
- "Dicebot" <m.strashun gmail.com> Feb 26 2013
- "Jonathan M Davis" <jmdavisProg gmx.com> Feb 26 2013
- Timon Gehr <timon.gehr gmx.ch> Feb 26 2013
- Timon Gehr <timon.gehr gmx.ch> Feb 26 2013
- Timon Gehr <timon.gehr gmx.ch> Feb 27 2013
- Timon Gehr <timon.gehr gmx.ch> Feb 27 2013
- Timon Gehr <timon.gehr gmx.ch> Feb 27 2013
- Timon Gehr <timon.gehr gmx.ch> Feb 27 2013
- Timon Gehr <timon.gehr gmx.ch> Feb 27 2013
- "Dicebot" <m.strashun gmail.com> Feb 26 2013
- "deadalnix" <deadalnix gmail.com> Feb 26 2013
- "deadalnix" <deadalnix gmail.com> Feb 26 2013
- "deadalnix" <deadalnix gmail.com> Feb 26 2013
- "deadalnix" <deadalnix gmail.com> Feb 26 2013
- "deadalnix" <deadalnix gmail.com> Feb 26 2013
- "deadalnix" <deadalnix gmail.com> Feb 26 2013
- "deadalnix" <deadalnix gmail.com> Feb 26 2013
- "deadalnix" <deadalnix gmail.com> Feb 26 2013
- kenji hara <k.hara.pg gmail.com> Feb 26 2013
- Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> Feb 26 2013
- Dmitry Olshansky <dmitry.olsh gmail.com> Feb 26 2013
- dennis luehring <dl.soluz gmx.net> Feb 26 2013
- Timon Gehr <timon.gehr gmx.ch> Feb 27 2013
- Dmitry Olshansky <dmitry.olsh gmail.com> Feb 27 2013
- Timon Gehr <timon.gehr gmx.ch> Feb 27 2013
- "deadalnix" <deadalnix gmail.com> Feb 26 2013
- kenji hara <k.hara.pg gmail.com> Feb 26 2013
- "deadalnix" <deadalnix gmail.com> Feb 26 2013
- Jonathan M Davis <jmdavisProg gmx.com> Feb 26 2013
- "deadalnix" <deadalnix gmail.com> Feb 26 2013
- kenji hara <k.hara.pg gmail.com> Feb 27 2013
- "deadalnix" <deadalnix gmail.com> Feb 27 2013
- "deadalnix" <deadalnix gmail.com> Feb 27 2013
- "deadalnix" <deadalnix gmail.com> Feb 27 2013
- "deadalnix" <deadalnix gmail.com> Feb 27 2013
- Robert <jfanatiker gmx.at> Feb 27 2013
- "Maxim Fomin" <maxim maxim-fomin.ru> Feb 27 2013
- "deadalnix" <deadalnix gmail.com> Feb 27 2013
- Andrej Mitrovic <andrej.mitrovich gmail.com> Feb 27 2013
- "deadalnix" <deadalnix gmail.com> Feb 27 2013
- Andrej Mitrovic <andrej.mitrovich gmail.com> Feb 27 2013
- "Dicebot" <m.strashun gmail.com> Feb 27 2013
- "deadalnix" <deadalnix gmail.com> Feb 27 2013
Carmack said : « I will always take an aggressively simple approach to things » and so I did, as I love cargo cult. More seriously, I face the need of more simplicity into D quite often, as the feature matrix is quite heavy. So here is a new DIP about function call (and function call only, I have 2 more DIP to come, but writing them take quite a lot of time). I actually had the time to play around with different scheme, and that one seems clearly to be the simplest. As usual, destroy, I don't expect to get unanimity on that. But I tried very hard to get most benefit of actual situation, including the possibility of optional parentheses in some situations (even if I'm not the biggest fan of it, I recognize that they are nice).
Feb 26 2013
I like overall approach and think it really should be rule of a thumb for designing D features - defining simple bullet-proof semantics and making conclusions from it. As opposed to syntax-based special case coverage. What I do find lacking in this DIP: 1) "Optional parentheses" part needs detailed description why exactly those cases have special handling and how are they different from others. Also looks like example code has errors there, for example, function that has no return statement and uint return type. 2) If you want to prohibit functions having an address, you need a section explaining communication with C in details in regard to passing function pointers. 3) It really needs a broad overview of semantic changes in common use cases and code breakage list.
Feb 26 2013
On 02/26/2013 06:09 PM, Dicebot wrote:I like overall approach and think it really should be rule of a thumb for designing D features - defining simple bullet-proof semantics and making conclusions from it. As opposed to syntax-based special case coverage. ...
Like it or not, that is what a compiler does.What I do find lacking in this DIP: 1) "Optional parentheses" part needs detailed description why exactly those cases have special handling and how are they different from others. ...
That part needs a complete overhaul. It is way too complex given the goal the DIP pursuits.2) If you want to prohibit functions having an address, you need a section explaining communication with C in details in regard to passing function pointers.
That actually wouldn't change.3) It really needs a broad overview of semantic changes in common use cases and code breakage list.
I guess it breaks most projects out there.
Feb 26 2013
On 02/26/2013 10:14 PM, Dicebot wrote:On Tuesday, 26 February 2013 at 20:42:57 UTC, Timon Gehr wrote:On 02/26/2013 06:09 PM, Dicebot wrote:I like overall approach and think it really should be rule of a thumb for designing D features - defining simple bullet-proof semantics and making conclusions from it. As opposed to syntax-based special case coverage. ...
Like it or not, that is what a compiler does.
Pardon me, how is compiler relevant here?
The DIP serves as specification for later compiler implementation. If it is not formal enough, the implementation may miss corner cases.Languages are designed for programmers in first place, not compilers.
Even if that was considered unequivocally true, it would not render language specification unnecessary.2) If you want to prohibit functions having an address, you need a section explaining communication with C in details in regard to passing function pointers.
That actually wouldn't change.
Why? Functions does not have an address according to this DIP. How will you pass a callback to C code then, special case for "extern(C)"?
ReturnType function(ParameterTypes) is a C function pointer type in the ABI. That wouldn't change. extern(C) int foo(int function() fun); void main(){ static int bar(int x){ return x+1; } foo(bar); // ok foo((int x)=>x+2); // ok }
Feb 26 2013
26-Feb-2013 20:16, deadalnix пишет:Carmack said : « I will always take an aggressively simple approach to things » and so I did, as I love cargo cult. More seriously, I face the need of more simplicity into D quite often, as the feature matrix is quite heavy. So here is a new DIP about function call (and function call only, I have 2 more DIP to come, but writing them take quite a lot of time). I actually had the time to play around with different scheme, and that one seems clearly to be the simplest. As usual, destroy, I don't expect to get unanimity on that. But I tried very hard to get most benefit of actual situation, including the possibility of optional parentheses in some situations (even if I'm not the biggest fan of it, I recognize that they are nice).
I like the simplicity and the automatic anti-boilerplate " property int blah;". The fact that empty can't be "enum empty = false;" is a problem since that's how infinite ranges are statically distinguished. -- Dmitry Olshansky
Feb 26 2013
26-Feb-2013 22:03, Dmitry Olshansky пишет:26-Feb-2013 20:16, deadalnix пишет:Carmack said : « I will always take an aggressively simple approach to things » and so I did, as I love cargo cult. More seriously, I face the need of more simplicity into D quite often, as the feature matrix is quite heavy. So here is a new DIP about function call (and function call only, I have 2 more DIP to come, but writing them take quite a lot of time). I actually had the time to play around with different scheme, and that one seems clearly to be the simplest. As usual, destroy, I don't expect to get unanimity on that. But I tried very hard to get most benefit of actual situation, including the possibility of optional parentheses in some situations (even if I'm not the biggest fan of it, I recognize that they are nice).
I like the simplicity and the automatic anti-boilerplate " property int blah;". The fact that empty can't be "enum empty = false;" is a problem since that's how infinite ranges are statically distinguished.
Ouch and I've reviewed an updated version of DIP 26 :) Mh-m OK the warm-up is done, and it was nice to see a refined DIP26. Time to get to the new stuff... I take it DIP27 was modeled after Scala? I think I like it but it leaves me wondering what properties are now and how they would fit. Eagerly waiting for more DIPs. -- Dmitry Olshansky
Feb 26 2013
On 2/26/13, deadalnix <deadalnix gmail.com> wrote:So here is a new DIP about function call
Where's the link? I don't see it listed: http://wiki.dlang.org/DIPs
Feb 26 2013
On Tuesday, 26 February 2013 at 18:27:13 UTC, Andrej Mitrovic wrote:Where's the link? I don't see it listed: http://wiki.dlang.org/DIPs
just added: http://wiki.dlang.org/DIP27 "Transitional measure to mitigate breakage" // Transitional behavior. static assert(is(typeof(&foo) == void function()); // Error (foo has no address). Final behavior static assert(is(typeof(&foo) == void function()); are these supposed to be different?
Feb 26 2013
I guessed it by name: http://wiki.dlang.org/DIP27
Feb 26 2013
On Tuesday, 26 February 2013 at 18:52:35 UTC, Dmitry Olshansky wrote:I take it DIP27 was modeled after Scala?
As far as I see it - better than Scala, as it uses real first-class function types, not just decorated classes. Wonder how it will interact with other paradigms though.
Feb 26 2013
On Tuesday, February 26, 2013 17:16:37 deadalnix wrote:Carmack said : « I will always take an aggressively simple approach to things » and so I did, as I love cargo cult. More seriously, I face the need of more simplicity into D quite often, as the feature matrix is quite heavy. So here is a new DIP about function call (and function call only, I have 2 more DIP to come, but writing them take quite a lot of time). I actually had the time to play around with different scheme, and that one seems clearly to be the simplest. As usual, destroy, I don't expect to get unanimity on that. But I tried very hard to get most benefit of actual situation, including the possibility of optional parentheses in some situations (even if I'm not the biggest fan of it, I recognize that they are nice).
Wouldn't this fall apart completely with auto or IFTI (implicit funtion template instantiation)? For instance take auto foo(T)(T blah) {...} int func() { return 7; } void bar() { ... foo(func); //Does this call func or pass its address? auto f = func; //Does this call func or take its address? ... } I believe that both Walter and Andrei have said on multiple occasions that one of C's big mistakes was conflating function names with their addresses, and this DIP appears to be trying to do exactly that. And I honestly don't see what it buys us. It just makes the situation with parenless function calls worse. At least right now, it's clear when you're dealing with a function pointer or a parenless function call. With this DIP, it wouldn't be. - Jonathan M Davis
Feb 26 2013
On 02/26/2013 09:00 PM, Jonathan M Davis wrote:... auto foo(T)(T blah) {...} int func() { return 7; } void bar() { ... foo(func); //Does this call func or pass its address? auto f = func; //Does this call func or take its address? ... } ...
Neither.
Feb 26 2013
On 02/26/2013 05:16 PM, deadalnix wrote:... As usual, destroy, I don't expect to get unanimity on that. But I tried very hard to get most benefit of actual situation, including the possibility of optional parentheses in some situations (even if I'm not the biggest fan of it, I recognize that they are nice).
If breaking code is an option, this is almost fine. Change the optional parens part to "optional parentheses are valid for CTFE calls", and you might have me on board. It is also simpler, less ad-hoc, and easier to implement than what the DIP currently states.
Feb 26 2013
On 02/27/2013 03:30 AM, deadalnix wrote:On Tuesday, 26 February 2013 at 21:01:04 UTC, Timon Gehr wrote:On 02/26/2013 05:16 PM, deadalnix wrote:... As usual, destroy, I don't expect to get unanimity on that. But I tried very hard to get most benefit of actual situation, including the possibility of optional parentheses in some situations (even if I'm not the biggest fan of it, I recognize that they are nice).
If breaking code is an option, this is almost fine. Change the optional parens part to "optional parentheses are valid for CTFE calls", and you might have me on board. It is also simpler, less ad-hoc, and easier to implement than what the DIP currently states.
Can you elaborate on that ? I'm not 100M satisfied with that part of the DIP, where I see everything else as a major improvement over current situation.
I'm not sure why elaboration would be necessary. Remove the optional parens part, then: int foo(int x){ ... } 2.foo // <- no meaning assigned by your DIP, make it a function call
Feb 27 2013
On 02/27/2013 11:24 AM, deadalnix wrote:On Wednesday, 27 February 2013 at 09:38:56 UTC, Timon Gehr wrote:I'm not sure why elaboration would be necessary. Remove the optional parens part, then: int foo(int x){ ... } 2.foo // <- no meaning assigned by your DIP, make it a function call
I considered optional parentheses where you would have an error, but I'm afraid that this could create weird effect with function overloads.
There are no weird effects with function overloads in what I propose. What is the issue you are seeing?It may be limited to the case where expression can't be used as statement because it has no effect.
Then it is not worth it.
Feb 27 2013
On 02/27/2013 11:57 AM, deadalnix wrote:On Wednesday, 27 February 2013 at 10:38:05 UTC, Timon Gehr wrote:I considered optional parentheses where you would have an error, but I'm afraid that this could create weird effect with function overloads.
There are no weird effects with function overloads in what I propose. What is the issue you are seeing?
Consider the following situation : void foo(uint a) { writeln("a is ", a); } uint bar() { return 0; } foo(bar); // a is 0
error: incompatible argument types (uint function()) to function foo(uint a)Later, this function is added : void foo(uint function() a) { writeln("function not executed"); } The statement above become : foo(bar); // function not executed Note that foo can be in other modules, so it may not be obvious. It can be solved in various ways, and I actually implemented some to play around. I was not satisfied with the result.
I see. This problem does not occur. (There is no UFCS in the above code.)It may be limited to the case where expression can't be used as statement because it has no effect.
Then it is not worth it.
It would kick in with the example you gave.
Not necessarily, it would depend on the context of the expression I gave.
Feb 27 2013
On 02/27/2013 12:18 PM, deadalnix wrote:On Wednesday, 27 February 2013 at 11:01:01 UTC, Timon Gehr wrote:I see. This problem does not occur. (There is no UFCS in the above code.)
It occurs the same way with UFCS as they are function call at the end. ...
This is an issue with the current DIP27, which my proposal does not have. In case this is not clear yet, please provide code that supposedly has the issue.
Feb 27 2013
On 02/26/2013 10:01 PM, Timon Gehr wrote:On 02/26/2013 05:16 PM, deadalnix wrote:... As usual, destroy, I don't expect to get unanimity on that. But I tried very hard to get most benefit of actual situation, including the possibility of optional parentheses in some situations (even if I'm not the biggest fan of it, I recognize that they are nice).
If breaking code is an option, this is almost fine. Change the optional parens part to "optional parentheses are valid for CTFE calls",
Ugh. Should be "UFCS calls".and you might have me on board. It is also simpler, less ad-hoc, and easier to implement than what the DIP currently states.
Feb 27 2013
On Tuesday, 26 February 2013 at 20:42:57 UTC, Timon Gehr wrote:On 02/26/2013 06:09 PM, Dicebot wrote:I like overall approach and think it really should be rule of a thumb for designing D features - defining simple bullet-proof semantics and making conclusions from it. As opposed to syntax-based special case coverage. ...
Like it or not, that is what a compiler does.
Pardon me, how is compiler relevant here? Languages are designed for programmers in first place, not compilers.2) If you want to prohibit functions having an address, you need a section explaining communication with C in details in regard to passing function pointers.
That actually wouldn't change.
Why? Functions does not have an address according to this DIP. How will you pass a callback to C code then, special case for "extern(C)"?
Feb 26 2013
On Tuesday, 26 February 2013 at 18:03:43 UTC, Dmitry Olshansky wrote:I like the simplicity and the automatic anti-boilerplate " property int blah;".
That isn't simplicity, that is ease. And property isn't covered by the DIP.
Feb 26 2013
On Tuesday, 26 February 2013 at 18:52:35 UTC, Dmitry Olshansky wrote:Ouch and I've reviewed an updated version of DIP 26 :) Mh-m OK the warm-up is done, and it was nice to see a refined DIP26. Time to get to the new stuff... I take it DIP27 was modeled after Scala? I think I like it but it leaves me wondering what properties are now and how they would fit. Eagerly waiting for more DIPs.
The DIP is similar to what exists in C# and Javascript, plus optional ().
Feb 26 2013
On Tuesday, 26 February 2013 at 20:00:26 UTC, Jonathan M Davis wrote:Wouldn't this fall apart completely with auto or IFTI (implicit funtion template instantiation)? For instance take auto foo(T)(T blah) {...} int func() { return 7; } void bar() { ... foo(func); //Does this call func or pass its address? auto f = func; //Does this call func or take its address? ... }
Both are the function. None is listed in the implicit call cases. Are you sure we are talking about the same DIP ?I believe that both Walter and Andrei have said on multiple occasions that one of C's big mistakes was conflating function names with their addresses, and this DIP appears to be trying to do exactly that.
That is not how C works. In C, the function name represent the actual instruction f the function (and this is why taking the address of the function gives you a function pointer). This mechanics is reproduced in D but has no real use case (even if it is around for more than 40 years) and add complexity. The DIP proposes something close to what exists in C# and Javascript.And I honestly don't see what it buys us. It just makes the situation with parenless function calls worse. At least right now, it's clear when you're dealing with a function pointer or a parenless function call. With this DIP, it wouldn't be.
Considering that both statement above are wrong, I think you should reconsider that conclusion.
Feb 26 2013
On Tuesday, 26 February 2013 at 20:42:57 UTC, Timon Gehr wrote:On 02/26/2013 06:09 PM, Dicebot wrote:I like overall approach and think it really should be rule of a thumb for designing D features - defining simple bullet-proof semantics and making conclusions from it. As opposed to syntax-based special case coverage. ...
Like it or not, that is what a compiler does.What I do find lacking in this DIP: 1) "Optional parentheses" part needs detailed description why exactly those cases have special handling and how are they different from others. ...
That part needs a complete overhaul. It is way too complex given the goal the DIP pursuits.
I have to say I'm not a big fan of it. But several people really seems to enjoy the ability to call function without (), so I went through some codebase to see where it is used most and figured out when it does not conflict with something else.I guess it breaks most projects out there.
I guess any changes to the way you call function is going to break a fair amount of code. This is the most basic feature. This is also why you really need to get it straightforward and simple.
Feb 26 2013
On Tuesday, 26 February 2013 at 21:01:04 UTC, Timon Gehr wrote:On 02/26/2013 05:16 PM, deadalnix wrote:... As usual, destroy, I don't expect to get unanimity on that. But I tried very hard to get most benefit of actual situation, including the possibility of optional parentheses in some situations (even if I'm not the biggest fan of it, I recognize that they are nice).
If breaking code is an option, this is almost fine. Change the optional parens part to "optional parentheses are valid for CTFE calls", and you might have me on board. It is also simpler, less ad-hoc, and easier to implement than what the DIP currently states.
Can you elaborate on that ? I'm not 100M satisfied with that part of the DIP, where I see everything else as a major improvement over current situation.
Feb 26 2013
On Tuesday, 26 February 2013 at 21:14:48 UTC, Dicebot wrote:Why? Functions does not have an address according to this DIP. How will you pass a callback to C code then, special case for "extern(C)"?
D first class function *ARE* C function pointer already. The concept of taking the function address disappear, but it doesn't mean the function have no address anymore.
Feb 26 2013
On Tuesday, 26 February 2013 at 23:40:09 UTC, Timon Gehr wrote:The DIP serves as specification for later compiler implementation. If it is not formal enough, the implementation may miss corner cases.
One of the goals of the DIP is precisely to avoid corner cases, as they are a pain both for programmer and language implementers.Languages are designed for programmers in first place, not compilers.
Even if that was considered unequivocally true, it would not render language specification unnecessary.
Language spec is a contract between the programmer and language implementers. It is highly relevant for both.
Feb 26 2013
On Tuesday, 26 February 2013 at 17:09:31 UTC, Dicebot wrote:I like overall approach and think it really should be rule of a thumb for designing D features - defining simple bullet-proof semantics and making conclusions from it. As opposed to syntax-based special case coverage. What I do find lacking in this DIP: 1) "Optional parentheses" part needs detailed description why exactly those cases have special handling and how are they different from others. Also looks like example code has errors there, for example, function that has no return statement and uint return type.
For the .identifier part, it isn't ambiguous as function don't have members, and it has been proven to work well with automatic pointer dereferences. For the foreach case, it is invalid to pass a function anyway, so no ambiguity here. It also quite heavily used.
Feb 26 2013
--047d7b86db609f2c8104d6ac7159 Content-Type: text/plain; charset=UTF-8 2013/2/27 Jonathan M Davis <jmdavisProg gmx.com>I believe that both Walter and Andrei have said on multiple occasions that one of C's big mistakes was conflating function names with their addresses, and this DIP appears to be trying to do exactly that. And I honestly don't see what it buys us. It just makes the situation with parenless function calls worse. At least right now, it's clear when you're dealing with a function pointer or a parenless function call. With this DIP, it wouldn't be.
I agree with Jonathan. DIP27 is a recurrence of C's mistake. It would remove a language future, and breaking much existing code, and then introduces nothing. Certainly compiler implementation may be simplified a little by doing it, however it is too small benefit than the D world destruction. Kenji Hara --047d7b86db609f2c8104d6ac7159 Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable <div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">2013= /2/27 Jonathan M Davis <span dir=3D"ltr"><<a href=3D"mailto:jmdavisProg = gmx.com" target=3D"_blank">jmdavisProg gmx.com</a>></span><br><blockquot= e class=3D"gmail_quote" style=3D"margin-top:0px;margin-right:0px;margin-bot= tom:0px;margin-left:0.8ex;border-left-width:1px;border-left-color:rgb(204,2= 04,204);border-left-style:solid;padding-left:1ex"> <div class=3D""><div class=3D"h5">I believe that both Walter and Andrei hav= e said on multiple occasions that one<br></div></div> of C's big mistakes was conflating function names with their addresses,= and<br> this DIP appears to be trying to do exactly that. And I honestly don't = see<br> what it buys us. It just makes the situation with parenless function calls<= br> worse. At least right now, it's clear when you're dealing with a fu= nction<br> pointer or a parenless function call. With this DIP, it wouldn't be.</b= lockquote><div><br></div><div>I agree with Jonathan. DIP27 is a recurrence = of C's mistake.</div><div>It would remove a language future, and breaki= ng much existing code, and then introduces nothing. Certainly compiler impl= ementation may be simplified a little by doing it, however it is too small = benefit than the D world destruction.<br> </div><div><br></div><div>Kenji Hara</div></div></div></div> --047d7b86db609f2c8104d6ac7159--
Feb 26 2013
On 2/26/13 10:33 PM, kenji hara wrote:2013/2/27 Jonathan M Davis <jmdavisProg gmx.com <mailto:jmdavisProg gmx.com>> I believe that both Walter and Andrei have said on multiple occasions that one of C's big mistakes was conflating function names with their addresses, and this DIP appears to be trying to do exactly that. And I honestly don't see what it buys us. It just makes the situation with parenless function calls worse. At least right now, it's clear when you're dealing with a function pointer or a parenless function call. With this DIP, it wouldn't be. I agree with Jonathan. DIP27 is a recurrence of C's mistake. It would remove a language future, and breaking much existing code, and then introduces nothing. Certainly compiler implementation may be simplified a little by doing it, however it is too small benefit than the D world destruction. Kenji Hara
Agreed. I think it's safe to close it. Andrei
Feb 26 2013
27-Feb-2013 09:34, kenji hara пишет:2013/2/27 deadalnix <deadalnix gmail.com <mailto:deadalnix gmail.com>> > > On Wednesday, 27 February 2013 at 03:46:44 UTC, Andrei Alexandrescu wrote: >> >> On 2/26/13 10:33 PM, kenji hara wrote: >>> >>> 2013/2/27 Jonathan M Davis <jmdavisProg gmx.com <mailto:jmdavisProg gmx.com> >>> <mailto:jmdavisProg gmx.com <mailto:jmdavisProg gmx.com>>> >>> >>> I believe that both Walter and Andrei have said on multiple >>> occasions that one >>> of C's big mistakes was conflating function names with their >>> addresses, and >>> this DIP appears to be trying to do exactly that. And I honestly >>> don't see >>> what it buys us. It just makes the situation with parenless function >>> calls >>> worse. At least right now, it's clear when you're dealing with a >>> function >>> pointer or a parenless function call. With this DIP, it wouldn't be. >>> >>> >>> I agree with Jonathan. DIP27 is a recurrence of C's mistake. >>> It would remove a language future, and breaking much existing code, and >>> then introduces nothing. Certainly compiler implementation may be >>> simplified a little by doing it, however it is too small benefit than >>> the D world destruction. >>> >>> Kenji Hara >> >> >> Agreed. I think it's safe to close it. >> >> Andrei > > > Andrei, Kenji and Jonathan, can you explain what error of C did this DIP reproduce and why it is an error ? The mistake in C is mixing of function name and function address. At least there is one ambiguity which appearance and meaning does not correspond one-to-one.
And what is the advantage of plain function name over just _always_ having a (constant) pointer to it ? Since a compiler can inline any "call by pointer" as long as it knows it's a constant (like manifest constant in this DIP) performance and codegen isn't an issue. I'd say the mistake in C is to: a) introduce nebulous type that's not expressible (plain function name). b) make things subtly different for func and &func, and let the letter be done under the covers sometimes Killing both of these is an improvement.In current D, the ambiguity is _already_ resolved - if you want to function address, use & operator. As far as I see, DIP27 will overturn the chess board, remove property feature, change the meaning of 'foo', deprecate '&foo', and finally add nothing for the language users.
-- Dmitry Olshansky
Feb 26 2013
Am 27.02.2013 06:54, schrieb deadalnix:In current D, the ambiguity is _already_ resolved - if you want to function address, use & operator.
D behave very much like C on that regard, so I don't really see how this can be true.
void (*functionPtr)(); //both are valid and working in C functionPtr xyz = &foo; functionPtr zxy = foo; //<- this is solved in D
Feb 26 2013
On 02/27/2013 02:08 PM, Maxim Fomin wrote:.... If such implicit conversion is performed in D, taking into account D complexity and corner cases may lead to collisions on using function name - is it a pointer or a type?
It's a function. I think the only technical problem of DIP27 outside the optional parentheses part is that it does not specify what is(T==function) will do.
Feb 27 2013
27-Feb-2013 20:24, deadalnix пишет:On Wednesday, 27 February 2013 at 15:57:12 UTC, Andrej Mitrovic wrote:On 2/27/13, Timon Gehr <timon.gehr gmx.ch> wrote:I think the only technical problem of DIP27 outside the optional parentheses part is that it does not specify what is(T==function) will do.
The only problem? How about breaking every single piece of code ever written in D? It seems to me like people assume we can easily force people to rewrite everything. It ain't gonna happen. This DIP was DOA from the start.
That is fallacy. PHP did massive breaking changes from 5 to 5 and still managed the change. And believe me, you'll find *WAY* more code written in PHP than in D even at the time. Breaking are not a problem in themselves and this reaction tells us more about our inability to do the most basic release management than anything else.
+1 on both counts. It's the inability to handle breaking changes that is the most annoying. An analogy: compare two situations. The first one is that you see a notification on your front door that this day electricity might be unstable say during 6-8 P.M due to maintenance work. And at least you know what to expect even if it doesn't break a thing in the end. The second one is that you have light constantly blink during the evening and your TV gets fried. Then a technician knock at you door to say that he's very sorry for frying your TV box. But rest assured that he tried hard not to break anything and that only 0.05% of people experienced any problems. Adopting the deprecation process is not good enough. Adopting and following it to the latter is still not good enough. Adopting, following and notifying people beforehand is close but not there. The missing steps is providing a migration path and guarantees.On a more personal level, every single version of dmd break my code, so I'm kind of fed up when people don't want to fix actual broken stuff to not break code. D break code all the time, that is a fact already. Many breakage don't even have a good reason to exists (alias this syntax, I'm looking at you, but you are not the only one).
Same thoughts here. If anything compiler bugfixes are the biggest source of breakage in my code. That and regressions that come along. I see it that only code that is constantly maintained (or instead is tied to a particular compiler version) is the only code that works today. -- Dmitry Olshansky
Feb 27 2013
On 02/27/2013 04:33 AM, kenji hara wrote:... I agree with Jonathan. DIP27 is a recurrence of C's mistake. ...
No it is not.
Feb 27 2013
On Wednesday, 27 February 2013 at 03:46:44 UTC, Andrei Alexandrescu wrote:On 2/26/13 10:33 PM, kenji hara wrote:2013/2/27 Jonathan M Davis <jmdavisProg gmx.com <mailto:jmdavisProg gmx.com>> I believe that both Walter and Andrei have said on multiple occasions that one of C's big mistakes was conflating function names with their addresses, and this DIP appears to be trying to do exactly that. And I honestly don't see what it buys us. It just makes the situation with parenless function calls worse. At least right now, it's clear when you're dealing with a function pointer or a parenless function call. With this DIP, it wouldn't be. I agree with Jonathan. DIP27 is a recurrence of C's mistake. It would remove a language future, and breaking much existing code, and then introduces nothing. Certainly compiler implementation may be simplified a little by doing it, however it is too small benefit than the D world destruction. Kenji Hara
Agreed. I think it's safe to close it. Andrei
Andrei, Kenji and Jonathan, can you explain what error of C did this DIP reproduce and why it is an error ?
Feb 26 2013
--047d7b86db6017e9c004d6ae21aa Content-Type: text/plain; charset=UTF-8 2013/2/27 deadalnix <deadalnix gmail.com>On Wednesday, 27 February 2013 at 03:46:44 UTC, Andrei Alexandrescu wrote:On 2/26/13 10:33 PM, kenji hara wrote:2013/2/27 Jonathan M Davis <jmdavisProg gmx.com <mailto:jmdavisProg gmx.com>> I believe that both Walter and Andrei have said on multiple occasions that one of C's big mistakes was conflating function names with their addresses, and this DIP appears to be trying to do exactly that. And I honestly don't see what it buys us. It just makes the situation with parenless function calls worse. At least right now, it's clear when you're dealing with a function pointer or a parenless function call. With this DIP, it wouldn't be. I agree with Jonathan. DIP27 is a recurrence of C's mistake. It would remove a language future, and breaking much existing code, and then introduces nothing. Certainly compiler implementation may be simplified a little by doing it, however it is too small benefit than the D world destruction. Kenji Hara
Agreed. I think it's safe to close it. Andrei
Andrei, Kenji and Jonathan, can you explain what error of C did this DIP
The mistake in C is mixing of function name and function address. At least there is one ambiguity which appearance and meaning does not correspond one-to-one. In current D, the ambiguity is _already_ resolved - if you want to function address, use & operator. As far as I see, DIP27 will overturn the chess board, remove property feature, change the meaning of 'foo', deprecate '&foo', and finally add nothing for the language users. Kenji Hara --047d7b86db6017e9c004d6ae21aa Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable <div dir=3D"ltr">2013/2/27 deadalnix <<a href=3D"mailto:deadalnix gmail.= com">deadalnix gmail.com</a>><br>><br>> On Wednesday, 27 February = 2013 at 03:46:44 UTC, Andrei Alexandrescu wrote:<br>>><br>>> On= 2/26/13 10:33 PM, kenji hara wrote:<br> >>><br>>>> 2013/2/27 Jonathan M Davis <<a href=3D"mail= to:jmdavisProg gmx.com">jmdavisProg gmx.com</a><br>>>> <mailto:= <a href=3D"mailto:jmdavisProg gmx.com">jmdavisProg gmx.com</a>>><br>&= gt;>><br> >>> =C2=A0 =C2=A0I believe that both Walter and Andrei have said o= n multiple<br>>>> =C2=A0 =C2=A0occasions that one<br>>>> = =C2=A0 =C2=A0of C's big mistakes was conflating function names with the= ir<br>>>> =C2=A0 =C2=A0addresses, and<br> >>> =C2=A0 =C2=A0this DIP appears to be trying to do exactly that.= And I honestly<br>>>> =C2=A0 =C2=A0don't see<br>>>> = =C2=A0 =C2=A0what it buys us. It just makes the situation with parenless fu= nction<br>>>> =C2=A0 =C2=A0calls<br> >>> =C2=A0 =C2=A0worse. At least right now, it's clear when yo= u're dealing with a<br>>>> =C2=A0 =C2=A0function<br>>>&g= t; =C2=A0 =C2=A0pointer or a parenless function call. With this DIP, it wou= ldn't be.<br>>>><br> >>><br>>>> I agree with Jonathan. DIP27 is a recurrence o= f C's mistake.<br>>>> It would remove a language future, and b= reaking much existing code, and<br>>>> then introduces nothing. Ce= rtainly compiler implementation may be<br> >>> simplified a little by doing it, however it is too small benef= it than<br>>>> the D world destruction.<br>>>><br>>>= ;> Kenji Hara<br>>><br>>><br>>> Agreed. I think it'= ;s safe to close it.<br> >><br>>> Andrei<br>><br>><br>> Andrei, Kenji and Jonat= han, can you explain what error of C did this DIP reproduce and why it is a= n error ?<br><br><div><div>The mistake in C is mixing of function name and = function address.</div> <div>At least there is one ambiguity which appearance and meaning does not = correspond one-to-one.</div><div><br></div><div>In current D, the ambiguity= is _already_ resolved - if you want to function address, use & operato= r.</div> <div><br></div><div>As far as I see, DIP27 will overturn the chess board, r= emove property feature, change the meaning of 'foo', deprecate '= ;&foo', and finally=C2=A0add nothing for the language users.</div><= div> <br></div><div>Kenji Hara</div></div></div> --047d7b86db6017e9c004d6ae21aa--
Feb 26 2013
On Wednesday, 27 February 2013 at 05:34:44 UTC, kenji hara wrote:The mistake in C is mixing of function name and function address. At least there is one ambiguity which appearance and meaning does not correspond one-to-one.
That is false. In C, function pointers are done as follow : void foo() { printf("foo"); } void (*functionPtr)(); // equivalent to D void function() functionPtr; functionPtr = &foo; // Note the presence of & operator. functionPtr(); // Call foo This is why I don't understand the point the 3 of you are trying to make. Current behavior of D is much more close to C than what the DIP proposes. This behavior is very specific to C and C++. If C's behavior was a mistake, then it an argument FOR this DIP, not against.In current D, the ambiguity is _already_ resolved - if you want to function address, use & operator.
D behave very much like C on that regard, so I don't really see how this can be true.As far as I see, DIP27 will overturn the chess board, remove property feature, change the meaning of 'foo', deprecate '&foo', and finally add nothing for the language users.
No, DIP27 is only about functions. It says nothing about properties. It add stable foundation we can build upon.
Feb 26 2013
On Wednesday, February 27, 2013 03:23:04 deadalnix wrote:On Tuesday, 26 February 2013 at 20:00:26 UTC, Jonathan M Davis wrote:Wouldn't this fall apart completely with auto or IFTI (implicit funtion template instantiation)? For instance take auto foo(T)(T blah) {...} int func() { return 7; } void bar() { ... foo(func); //Does this call func or pass its address? auto f = func; //Does this call func or take its address? ... }
Both are the function. None is listed in the implicit call cases. Are you sure we are talking about the same DIP ?
Then what happened to parenless function calls? _Both_ of the cases above need to call the function, or you're going to be breaking tons of code, and I see _zero_ useability gain here. The function's name by itself calls the function. & on the function's name gets its address. What's complicated about that? What we have right now with regards to functions and their addresses is incredibly straightforward, and I don't see any gains in simplifying it. It just sounds like you're killing parenless function calls for free functions outside of UFCS. What are you even trying to gain by making it so that a function's name and its address are conflated like this? - Jonathan M Davis
Feb 26 2013
On Wednesday, 27 February 2013 at 06:15:29 UTC, dennis luehring wrote:Am 27.02.2013 06:54, schrieb deadalnix:In current D, the ambiguity is _already_ resolved - if you want to function address, use & operator.
D behave very much like C on that regard, so I don't really see how this can be true.
void (*functionPtr)(); //both are valid and working in C functionPtr xyz = &foo; functionPtr zxy = foo; //<- this is solved in D
I don't think D solved that. Only partially. Both are conflated here for instance : void foo() {} foo(); <=> (&foo)(); Is another presentation of the same conflation. The DIP propose to effectively solve that by removing completely the entity represented by foo in &foo . You can't have conflation with something that do not exists.
Feb 26 2013
--089e013c6c0e8c31c604d6b1c06b Content-Type: text/plain; charset=UTF-8 2013/2/27 deadalnix <deadalnix gmail.com>On Wednesday, 27 February 2013 at 06:15:29 UTC, dennis luehring wrote:Am 27.02.2013 06:54, schrieb deadalnix:In current D, the ambiguity is _already_ resolved - if you wantto function address, use & operator.
how this can be true.
void (*functionPtr)(); //both are valid and working in C functionPtr xyz = &foo; functionPtr zxy = foo; //<- this is solved in D
I don't think D solved that. Only partially. Both are conflated here for instance : void foo() {} foo(); <=> (&foo)(); Is another presentation of the same conflation. The DIP propose to effectively solve that by removing completely the entity represented by foo in &foo . You can't have conflation with something that do not exists.
In D, function symbol and function pointer are distinct entities. The former is just accessible by its name and it has _no_ runtime value. The latter is a runtime value which generated by applying address operator to function symbol. Also in C, essentially these entities are distinct, but C's semantic analyzer will implicitly apply address operator against the use of function name. Finally 'foo' has the same meaning as '&foo'. That has still introduced confusion to many programmer's. Back to D, the two entities explicitly separated syntactically, and the use of function name is newly assigned as 'property call' (note that, the definition of 'property' is still debatable). So, applying DIP27 is just equivalent to discarding property feature. Kenji Hara --089e013c6c0e8c31c604d6b1c06b Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable <div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">2013= /2/27 deadalnix <span dir=3D"ltr"><<a href=3D"mailto:deadalnix gmail.com= " target=3D"_blank">deadalnix gmail.com</a>></span><br><blockquote class= =3D"gmail_quote" style=3D"margin-top:0px;margin-right:0px;margin-bottom:0px= ;margin-left:0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204)= ;border-left-style:solid;padding-left:1ex"> <div class=3D""><div class=3D"h5">On Wednesday, 27 February 2013 at 06:15:2= 9 UTC, dennis luehring wrote:<br> <blockquote class=3D"gmail_quote" style=3D"margin-top:0px;margin-right:0px;= margin-bottom:0px;margin-left:0.8ex;border-left-width:1px;border-left-color= :rgb(204,204,204);border-left-style:solid;padding-left:1ex"> Am <a href=3D"tel:27.02.2013%2006" value=3D"+12702201306" target=3D"_blank"=27.02.2013 06</a>:54, schrieb deadalnix:<br>
margin-bottom:0px;margin-left:0.8ex;border-left-width:1px;border-left-color= :rgb(204,204,204);border-left-style:solid;padding-left:1ex"><blockquote cla= ss=3D"gmail_quote" style=3D"margin-top:0px;margin-right:0px;margin-bottom:0= px;margin-left:0.8ex;border-left-width:1px;border-left-color:rgb(204,204,20= 4);border-left-style:solid;padding-left:1ex"> In current D, the ambiguity is _already_ resolved - if you want<br> to function<br> address, use & operator.<br> <br> </blockquote> <br> D behave very much like C on that regard, so I don't really see<br> how this can be true.<br> </blockquote> <br> void (*functionPtr)();<br> <br> //both are valid and working in C<br> functionPtr xyz =3D &foo;<br> functionPtr zxy =3D foo; //<- this is solved in D<br> </blockquote> <br></div></div> I don't think D solved that. Only partially. Both are conflated here fo= r instance :<br> <br> void foo() {}<br> foo(); <=3D> (&foo)();<br> <br> Is another presentation of the same conflation.<br> <br> The DIP propose to effectively solve that by removing completely the entity= represented by foo in &foo . You can't have conflation with someth= ing that do not exists.<br> </blockquote></div><br></div><div class=3D"gmail_extra">In D, function symb= ol and function pointer=C2=A0are distinct entities.=C2=A0The former is just= accessible by its name and it has _no_ runtime value. The latter is a runt= ime value which generated by applying address operator to function symbol.<= /div> <div class=3D"gmail_extra"><br></div><div class=3D"gmail_extra">Also in C, = essentially these entities are distinct, but C's semantic analyzer will= implicitly apply address operator against the use of function name. Finall= y 'foo' has the same meaning as '&foo'. That has still = introduced confusion to many programmer's.</div> <div class=3D"gmail_extra"><br></div><div class=3D"gmail_extra">Back to D, = the two entities explicitly separated syntactically, and the use of functio= n name is newly assigned as 'property call' (note that, the definit= ion of 'property' is still debatable). So, applying DIP27 is just e= quivalent to discarding property feature.<br> </div><div class=3D"gmail_extra"><br></div><div class=3D"gmail_extra">Kenji= Hara</div></div> --089e013c6c0e8c31c604d6b1c06b--
Feb 27 2013
On Wednesday, 27 February 2013 at 09:38:56 UTC, Timon Gehr wrote:I'm not sure why elaboration would be necessary. Remove the optional parens part, then: int foo(int x){ ... } 2.foo // <- no meaning assigned by your DIP, make it a function call
I considered optional parentheses where you would have an error, but I'm afraid that this could create weird effect with function overloads. It may be limited to the case where expression can't be used as statement because it has no effect.
Feb 27 2013
On Wednesday, 27 February 2013 at 10:41:01 UTC, Timon Gehr wrote:On 02/26/2013 10:01 PM, Timon Gehr wrote:On 02/26/2013 05:16 PM, deadalnix wrote:... As usual, destroy, I don't expect to get unanimity on that. But I tried very hard to get most benefit of actual situation, including the possibility of optional parentheses in some situations (even if I'm not the biggest fan of it, I recognize that they are nice).
If breaking code is an option, this is almost fine. Change the optional parens part to "optional parentheses are valid for CTFE calls",
Ugh. Should be "UFCS calls".
Oh ! That make much more sense :D Yes, UFCS is a nice use case for optional (). The actual proposal allow for chained UFCS calls, except the last one. Which is already a big win.
Feb 27 2013
On Wednesday, 27 February 2013 at 10:38:05 UTC, Timon Gehr wrote:I considered optional parentheses where you would have an error, but I'm afraid that this could create weird effect with function overloads.
There are no weird effects with function overloads in what I propose. What is the issue you are seeing?
Consider the following situation : void foo(uint a) { writeln("a is ", a); } uint bar() { return 0; } foo(bar); // a is 0 Later, this function is added : void foo(uint function() a) { writeln("function not executed"); } The statement above become : foo(bar); // function not executed Note that foo can be in other modules, so it may not be obvious. It can be solved in various ways, and I actually implemented some to play around. I was not satisfied with the result.It may be limited to the case where expression can't be used as statement because it has no effect.
Then it is not worth it.
It would kick in with the example you gave.
Feb 27 2013
On Wednesday, 27 February 2013 at 11:01:01 UTC, Timon Gehr wrote:I see. This problem does not occur. (There is no UFCS in the above code.)
It occurs the same way with UFCS as they are function call at the end.It may be limited to the case where expression can't be used as statement because it has no effect.
Then it is not worth it.
It would kick in with the example you gave.
Not necessarily, it would depend on the context of the expression I gave.
That is true. Which is probably a bad thing.
Feb 27 2013
On Tue, 2013-02-26 at 22:03 +0400, Dmitry Olshansky wrote:The fact that empty can't be "enum empty = false;" is a problem since that's how infinite ranges are statically distinguished.
Thanks for the feedback on DIP26 :-) The isInfinite template is also satisfied if empty is a static function because of CTFE) Best regards, Robert
Feb 27 2013
On Wednesday, 27 February 2013 at 07:26:47 UTC, deadalnix wrote:On Wednesday, 27 February 2013 at 06:15:29 UTC, dennis luehring wrote:Am 27.02.2013 06:54, schrieb deadalnix:In current D, the ambiguity is _already_ resolved - if you want to function address, use & operator.
D behave very much like C on that regard, so I don't really see how this can be true.
void (*functionPtr)(); //both are valid and working in C functionPtr xyz = &foo; functionPtr zxy = foo; //<- this is solved in D
I don't think D solved that. Only partially. Both are conflated here for instance : void foo() {} foo(); <=> (&foo)(); Is another presentation of the same conflation. The DIP propose to effectively solve that by removing completely the entity represented by foo in &foo . You can't have conflation with something that do not exists.
No, in D there is no conflation between this two. The fact that you write (&foo)() instead of foo() (if foo is pointer) says about it. What Andrei, Kenji and Jonathan try to say (I guess) that function type in C in all cases is implicitly convertible to function pointer except when it is used with sizeof, Alignof and & operators (iso/iec $6.3.2). This is among the first differences I noticed when came from C. If such implicit conversion is performed in D, taking into account D complexity and corner cases may lead to collisions on using function name - is it a pointer or a type?
Feb 27 2013
On Wednesday, 27 February 2013 at 14:17:57 UTC, Timon Gehr wrote:On 02/27/2013 02:08 PM, Maxim Fomin wrote:.... If such implicit conversion is performed in D, taking into account D complexity and corner cases may lead to collisions on using function name - is it a pointer or a type?
It's a function. I think the only technical problem of DIP27 outside the optional parentheses part is that it does not specify what is(T==function) will do.
That is very true. To be fair, I think that is expression is an horrible three headed monster :D But I added it.
Feb 27 2013
On 2/27/13, Timon Gehr <timon.gehr gmx.ch> wrote:I think the only technical problem of DIP27 outside the optional parentheses part is that it does not specify what is(T==function) will do.
The only problem? How about breaking every single piece of code ever written in D? It seems to me like people assume we can easily force people to rewrite everything. It ain't gonna happen. This DIP was DOA from the start.
Feb 27 2013
On Wednesday, 27 February 2013 at 15:57:12 UTC, Andrej Mitrovic wrote:On 2/27/13, Timon Gehr <timon.gehr gmx.ch> wrote:I think the only technical problem of DIP27 outside the optional parentheses part is that it does not specify what is(T==function) will do.
The only problem? How about breaking every single piece of code ever written in D? It seems to me like people assume we can easily force people to rewrite everything. It ain't gonna happen. This DIP was DOA from the start.
That is fallacy. PHP did massive breaking changes from 5 to 5 and still managed the change. And believe me, you'll find *WAY* more code written in PHP than in D even at the time. Breaking are not a problem in themselves and this reaction tells us more about our inability to do the most basic release management than anything else. On a more personal level, every single version of dmd break my code, so I'm kind of fed up when people don't want to fix actual broken stuff to not break code. D break code all the time, that is a fact already. Many breakage don't even have a good reason to exists (alias this syntax, I'm looking at you, but you are not the only one).
Feb 27 2013
On 2/27/13, deadalnix <deadalnix gmail.com> wrote:That is fallacy.
void func(T...)(T args) { } int foo() { return 1; } float bar() { return 2.0; } void main() { func(foo, bar); // ??? } What will this do? If address-of on functions is banned then this must pass functions by default, and not their return types. Which is a complete change to what it does now. So now you have to carefully inspect every function call because you don't know whether you're passing a pointer to a function or you're invoking the function and passing the return type. How on earth does this simplify anything and justify code breakage?
Feb 27 2013
On Wednesday, 27 February 2013 at 17:30:16 UTC, Andrej Mitrovic wrote:So now you have to carefully inspect every function call because you don't know whether you're passing a pointer to a function or you're invoking the function and passing the return type.
One more reason to hate optional parens, hah!
Feb 27 2013
On Wednesday, 27 February 2013 at 17:30:16 UTC, Andrej Mitrovic wrote:On 2/27/13, deadalnix <deadalnix gmail.com> wrote:That is fallacy.
void func(T...)(T args) { } int foo() { return 1; } float bar() { return 2.0; } void main() { func(foo, bar); // ??? } What will this do? If address-of on functions is banned then this must pass functions by default, and not their return types. Which is a complete change to what it does now.
Yes it is.So now you have to carefully inspect every function call because you don't know whether you're passing a pointer to a function or you're invoking the function and passing the return type.
This ambiguity is what the DIP intend to solve. Here foo can refers to different entity types depending on the context. When you do &foo, you refers to function in the C meaning of the term, when you do foo, you refers to function call.How on earth does this simplify anything and justify code breakage?
It remove an entity type from the language, so remove an entire line and column in the feature matrix, so it simplify its definition, its implementation and get rid of a whole class of corner cases. It reduces the number of cases you have to account for in generic code as well. It remove ambiguities that currently exists on the usage of unary & operator. It makes D more friendly for functional style of code.
Feb 27 2013









Timon Gehr <timon.gehr gmx.ch> 