digitalmars.D - explicit castable to bool for predicate restraints?
- monarch_dodra (71/71) Dec 17 2012 I had a discussion a little while ago, regarding the validation
- Jonathan M Davis (4/6) Dec 17 2012 How about we just require that they all return bool? I see no reason to
- monarch_dodra (5/13) Dec 18 2012 That seems excessive to me. I think a lot of predicates,
- Jonathan M Davis (6/23) Dec 18 2012 Then wrap them in a lambda. int is not a boolean value in D, and I reall...
- Jonathan M Davis (13/36) Dec 18 2012 We're probably stuck with std.algorithm allowing implict conversions to ...
- monarch_dodra (6/16) Dec 18 2012 Hum...
I had a discussion a little while ago, regarding the validation of predicates. Basically, fearing that someone may write a predicate that returned some weird user-defined type that wasn't bool-able, I wrote: //---- void foo(Range, S)(Range r, S s) if (isForwardRange!Range && is(typeof(r.front == s) : bool)) { ... } or void foo(alias pred, Range, S)(Range r, S s) if (isForwardRange!Range && is(typeof(unaryFun!pred(r.front)) : bool)) { ... } //---- I just realized that the problem with this (which I need to fix asap in phobos, since I was recently pulled), is that this test will fail if the predicate returned something that was not *implicitly* castable to bool, but still *explicitly* castable to bool. For example: //---- int cmp() { return 4; } void main() { static if (cmp()) static assert(is(typeof(cmp()) : bool)); //Here } //---- This code will enter the static if (which means the result of cmp *can* be used inside an if), however, it will fail the assert (here). Conclusion: using `is(typeof(bla) : bool)` is bad form, as many (valid) comparators (and even opEquals) return int. So the "better" test would be to test with cast(bool), as such: //---- void foo(Range, S)(Range r, S s) if (isForwardRange!Range && is(typeof(cast(bool)(r.front == s))) { ... } or void foo(alias pred, Range, S)(Range r, S s) if (isForwardRange!Range && is(typeof(cast(bool)unaryFun!pred(r.front)))) { ... } //---- So here are my two questions: 1. Is there a more "elegant" way to write this test? Is there a more convenient "is explicitly castable syntax"? 2. Is this test even worth it? It bogs down the restriction (which needs to be as_clear_as_possible for our callers). Could we just say "Phobos expects any and all predicates to be useable in an if", and not bother? On the one hand, it needs testing, but on the other, the check's "cognitive cost" could be too high... Maybe we could have the functions match on any predicate return, but then consider that an invalid return type is a checked error (static assert)? //---- void foo(Range, S)(Range r, S s) if (isForwardRange!Range && is(typeof(r.front == s)) { static assert(typeof(cast(bool)(r.front == s)), "The supplied predicate does not return a testable result."); ... } //---- Opinions? Just want to know how which direction to take my future developments.
Dec 17 2012
On Monday, December 17, 2012 10:23:45 monarch_dodra wrote:Opinions? Just want to know how which direction to take my future developments.How about we just require that they all return bool? I see no reason to support anything else. - Jonathan M Davis
Dec 17 2012
On Monday, 17 December 2012 at 23:40:19 UTC, Jonathan M Davis wrote:On Monday, December 17, 2012 10:23:45 monarch_dodra wrote:That seems excessive to me. I think a lot of predicates, especially if they have C linkage, will return a (u)int whose values are just 0 or 1. I see no reason to not support this.Opinions? Just want to know how which direction to take my future developments.How about we just require that they all return bool? I see no reason to support anything else. - Jonathan M Davis
Dec 18 2012
On Tuesday, December 18, 2012 10:23:18 monarch_dodra wrote:On Monday, 17 December 2012 at 23:40:19 UTC, Jonathan M Davis wrote:Then wrap them in a lambda. int is not a boolean value in D, and I really don't think that we should be treating it as such. No D functions should be returning int for a boolean value, and I would expect using C functions with std.algorithm to be quite rare. - Jonathan m DavisOn Monday, December 17, 2012 10:23:45 monarch_dodra wrote:That seems excessive to me. I think a lot of predicates, especially if they have C linkage, will return a (u)int whose values are just 0 or 1. I see no reason to not support this.Opinions? Just want to know how which direction to take my future developments.How about we just require that they all return bool? I see no reason to support anything else. - Jonathan M Davis
Dec 18 2012
On Tuesday, December 18, 2012 01:45:14 Jonathan M Davis wrote:On Tuesday, December 18, 2012 10:23:18 monarch_dodra wrote:We're probably stuck with std.algorithm allowing implict conversions to bool due to the fact that a fair bit of it has accepted that for a while, but accepting anything which explictly casts to bool would be tantamount to turning explicit casts into implicit casts and would be very dangerous. The language is _very_ restrictive about where it does that precisely because of all the problems caused by implicit conversions in C++. Conditions inside of if statements and loops are the only place in the language where an explicit cast is implicitly done. And it's somewhat surprising that it does even that given how restrictive it is about implicit conversions in general. Everywhere else, an explicit cast is required to get an explicit cast. It's trivial to create a lambda to wrap functions which require explicit casts. - Jonathan M DavisOn Monday, 17 December 2012 at 23:40:19 UTC, Jonathan M Davis wrote:Then wrap them in a lambda. int is not a boolean value in D, and I really don't think that we should be treating it as such. No D functions should be returning int for a boolean value, and I would expect using C functions with std.algorithm to be quite rare.On Monday, December 17, 2012 10:23:45 monarch_dodra wrote:That seems excessive to me. I think a lot of predicates, especially if they have C linkage, will return a (u)int whose values are just 0 or 1. I see no reason to not support this.Opinions? Just want to know how which direction to take my future developments.How about we just require that they all return bool? I see no reason to support anything else. - Jonathan M Davis
Dec 18 2012
On Tuesday, 18 December 2012 at 10:08:12 UTC, Jonathan M Davis wrote:We're probably stuck with std.algorithm allowing implict conversions to bool due to the fact that a fair bit of it has accepted that for a while, but accepting anything which explictly casts to bool would be tantamount to turning explicit casts into implicit casts and would be very dangerous. [SNIP] - Jonathan M DavisHum... For now, I'll simply remove the newly enforced restrictions then, as it may break existing code. I'll put in more thinking before doing anything else.
Dec 18 2012