Re: [OT] Converting booleans to numbers
On 9/21/17 3:24 PM, Timon Gehr wrote: This is a good alternative, maybe arrange it like this: dfs(a + 1, b); dfs(a, b + 1); dfs(a - 1, b); dfs(a, b - 1); Yes, better! Just need to make sure no code is duplicated. (For example, there could be more work to do in each loop iteration, and then you'd need to use a local function.) Hm... I suppose you would do that work at the beginning of dfs, like you check the limits? -Steve
Re: [OT] Converting booleans to numbers
On 21.09.2017 17:53, Steven Schveighoffer wrote: On 9/21/17 11:48 AM, Steven Schveighoffer wrote: On 9/21/17 11:06 AM, Timon Gehr wrote: foreach(i; 0 .. 4){ dfs(a + (i==0) - (i==1), b + (i==2) - (i==3)); } So am I, but I wasn't commenting on trade-offs, only the view that there are no good uses. This seems way easier for me to grok, and is how I would write it. dfs(a + 1, 0); dfs(a - 1, 0); dfs(0, b + 1); dfs(0, b - 1); Of course, without bugs :) ... It was the same bug in every copy. Impressive! ;) dfs(a + 1, b); dfs(a - 1, b); dfs(a, b + 1); dfs(a, b - 1); -Steve This is a good alternative, maybe arrange it like this: dfs(a + 1, b); dfs(a, b + 1); dfs(a - 1, b); dfs(a, b - 1); Just need to make sure no code is duplicated. (For example, there could be more work to do in each loop iteration, and then you'd need to use a local function.)
Re: [OT] Converting booleans to numbers
On Wednesday, 20 September 2017 at 19:25:58 UTC, Timon Gehr wrote: Actually, it is useful enough to have a Wikipedia page: https://en.wikipedia.org/wiki/Iverson_bracket Example of a good use: void floodFill(dchar[][] data,dchar c,int i,int j) { void dfs(int a, int b) { if (a<0 || a >= data.length) return; if (b<0 || b >= data[a].length) return; if (data[a][b] == c) return; data[a][b] = c; foreach(i; 0 .. 4){ dfs(a + (i==0) - (i==1), b + (i==2) - (i==3)); } } dfs(i, j); } I would rather use an explicit function for such use cases: int delta(bool x) { return x == true ? 1 : 0; }
Re: [OT] Converting booleans to numbers
On 9/21/17 11:48 AM, Steven Schveighoffer wrote: On 9/21/17 11:06 AM, Timon Gehr wrote: foreach(i; 0 .. 4){ dfs(a + (i==0) - (i==1), b + (i==2) - (i==3)); } So am I, but I wasn't commenting on trade-offs, only the view that there are no good uses. This seems way easier for me to grok, and is how I would write it. dfs(a + 1, 0); dfs(a - 1, 0); dfs(0, b + 1); dfs(0, b - 1); Of course, without bugs :) dfs(a + 1, b); dfs(a - 1, b); dfs(a, b + 1); dfs(a, b - 1); -Steve
Re: [OT] Converting booleans to numbers
On 9/21/17 11:06 AM, Timon Gehr wrote: foreach(i; 0 .. 4){ dfs(a + (i==0) - (i==1), b + (i==2) - (i==3)); } ... So am I, but I wasn't commenting on trade-offs, only the view that there are no good uses. This seems way easier for me to grok, and is how I would write it. dfs(a + 1, 0); dfs(a - 1, 0); dfs(0, b + 1); dfs(0, b - 1); -Steve
Re: [OT] Converting booleans to numbers
On 20.09.2017 23:13, nkm1 wrote: Example of a good use: void floodFill(dchar[][] data,dchar c,int i,int j) { void dfs(int a, int b) { Example of a good use: void floodFill(dchar[][] data,dchar c,int i,int j) { void dfs(int a, int b) { if (a<0 || a >= data.length) return; if (b<0 || b >= data[a].length) return; if (data[a][b] == c) return; data[a][b] = c; foreach(i; 0 .. 4){ dfs(a + (i==0) - (i==1), b + (i==2) - (i==3)); } } dfs(i, j); } I don't agree it's a good use. Well, you can trust me that it is. ;) Actually, that seems quite obfuscated to me. It's actually straightforward. This C code is obfuscated: #define C , #define S(X) "Fizz"X"Buzz" int main(){ char j[]="00",*k=j+1,*g[]={k,S(C),S()}; while(':'-*j) ++*k>'9'&&++*j&&(1<:*g=j:>='0'), puts(g[!((*j+*k)%3)|2*(3==*k%5)]); return 0; } (And yet, you are probably able to guess what it does.) Consider: (I had considered that.) foreach (point; [[1, 0], [-1, 0], [0, 1], [0, -1]]) { dfs(a + point[0], b + point[1]); } void floodFill(dchar[][] data,dchar c,int i,int j) @nogc { I.e., I'd possibly call this a bad use of array literals. ;) (The fix is to initialize a static array of static arrays.) Also, it's not really a point, rather, it's a delta. Finds some random 10 programmers and ask them what's easier to understand... Personally, I think it is a tie as both are obvious. Also, in my experience (in C and C++) it is extremely rare for programmers to use booleans in arithmetic. So even if in some situation you would have to replace this thing with more verbose (i == 0 ? 1 : 0), it's no big deal. I didn't say it was. OTOH, booleans being numbers is a source of some bugs (just like other cases of weak typing). Not a ton of bugs, but the utility of implicit conversion to numbers is so unnoticeable that I'm sure it's just not worth it. So am I, but I wasn't commenting on trade-offs, only the view that there are no good uses.
Re: [OT] Converting booleans to numbers
On Wednesday, September 20, 2017 21:13:58 nkm1 via Digitalmars-d-learn wrote: > OTOH, booleans being numbers is a source of some bugs (just like > other cases of weak typing). Not a ton of bugs, but the utility > of implicit conversion to numbers is so unnoticeable that I'm > sure it's just not worth it. I think that most of us would agree with you, but the last time it was serious discussed, Walter couldn't be convinced. Based on more recent discussions with him, he did seem to now agree that we're probably too liberal with how many implicit conversions we allow, but I don't know which ones specifically he'd be willing to do differently if we didn't care about breaking code. But since breaking code would definitely be a problem with any implicit conversion that was removed, I doubt that it would be easy to talk him into making any changes to the implicit conversions now even if you could get him to agree that we ideally would. - Jonathan M Davis
Re: [OT] Converting booleans to numbers
On Wednesday, 20 September 2017 at 19:25:58 UTC, Timon Gehr wrote: Actually, it is useful enough to have a Wikipedia page: https://en.wikipedia.org/wiki/Iverson_bracket Mmmm... "The notation was originally introduced by Kenneth E. Iverson in his programming language APL". APL... yeah :) Programmers didn't like it, did they. Anyway, that seems to be explicit notation, analogous to (cond ? 1 : 0). Example of a good use: void floodFill(dchar[][] data,dchar c,int i,int j) { void dfs(int a, int b) { if (a<0 || a >= data.length) return; if (b<0 || b >= data[a].length) return; if (data[a][b] == c) return; data[a][b] = c; foreach(i; 0 .. 4){ dfs(a + (i==0) - (i==1), b + (i==2) - (i==3)); } } dfs(i, j); } I don't agree it's a good use. Actually, that seems quite obfuscated to me. Consider: foreach (point; [[1, 0], [-1, 0], [0, 1], [0, -1]]) { dfs(a + point[0], b + point[1]); } Finds some random 10 programmers and ask them what's easier to understand... Also, in my experience (in C and C++) it is extremely rare for programmers to use booleans in arithmetic. So even if in some situation you would have to replace this thing with more verbose (i == 0 ? 1 : 0), it's no big deal. OTOH, booleans being numbers is a source of some bugs (just like other cases of weak typing). Not a ton of bugs, but the utility of implicit conversion to numbers is so unnoticeable that I'm sure it's just not worth it.
Re: [OT] Converting booleans to numbers
On Wednesday, 20 September 2017 at 19:25:58 UTC, Timon Gehr wrote: On 19.09.2017 23:17, nkm1 wrote: ... OTOH, booleans converting to numbers is a very questionable feature. > I certainly have never seen any good use for it. ... Actually, it is useful enough to have a Wikipedia page: https://en.wikipedia.org/wiki/Iverson_bracket [snip] While it's also possible to do this with filter, this is what I'd probably most often use it for. import std.algorithm : sum; void main() { bool[] x = [true, false, true]; int[] y = [1, 2, 3]; y[] = x[] * y[]; assert(sum(y[]) == 4); } It would be nice to be able to do: assert(sum(x[] * y[]) == 4);
[OT] Converting booleans to numbers
On 19.09.2017 23:17, nkm1 wrote: ... OTOH, booleans converting to numbers is a very questionable feature. > I certainly have never seen any good use for it. ... Actually, it is useful enough to have a Wikipedia page: https://en.wikipedia.org/wiki/Iverson_bracket Example of a good use: void floodFill(dchar[][] data,dchar c,int i,int j) { void dfs(int a, int b) { if (a<0 || a >= data.length) return; if (b<0 || b >= data[a].length) return; if (data[a][b] == c) return; data[a][b] = c; foreach(i; 0 .. 4){ dfs(a + (i==0) - (i==1), b + (i==2) - (i==3)); } } dfs(i, j); } unittest { import std.algorithm, std.conv, std.array; auto data = ["###....##"d, "##...#..."d, "..###.###"d, "##...###...##"d, "...#."d, "#.#.#.#.#.#.#"d, "#.###"d] .map!(to!(dchar[])).array; floodFill(data, '#', 1, 1); assert(data==["#"d, "#"d, "#.###"d, "...##"d, "."d, "#.#.###.#.#.#"d, "#"d]); }