Community

Here I ask for opinions about a small enhancement request about BigInt that Don has refused:
http://d.puremagic.com/issues/show_bug.cgi?id=7079
It's not a very important thing, so I will probably avoid further arguing after this post :-)
In some languages like the ones derived from Pascal, like Ada, and in some other languages Java the boolean type is very distinct from the integer values. So to test if a integer value is zero you write something like:
int x = 10;
if (x == 0) {
// do A ...
} else {
// do B ...
}
In languages derived from C, like C++ and D and many others, like Python too, the integer values are valid in a boolean context too. This is valid C/C++/D code:
int x = 10;
if (x) {
// do B ...
} else {
// do A ...
}
This is handy in some situations, like when you want to count how many true cases there are:
void main() {
auto s1 = "hello";
auto s2 = "hallo";
int hamming_distance = 0;
assert(s1.length == s2.length);
foreach (i, c1; s1)
hamming_distance += c1 != s2[i];
assert(hamming_distance == 1);
}
While in a Delphi/Java language you need something like:
if (c1 != s2[i])
hamming_distance++;
The implicit conversion from boolean to integer is equally handy in Python:
s1 = "hello"
s2 = "hallo"
hamming_distance = sum(c1 != c2 for c1,c2 in zip(s1, s2))
assert hamming_distance == 1
D language regards boolean values as a subset of integers so it allows implicit conversion from bool to integer, but not from int to bool. I don't think this will ever change in D2/D3:
void main() {
int x = 1;
bool b = true;
x = b; // bool -> int is OK
int y = x > 3; // bool -> int is OK
b = x; // int -> bool is an Error
}
While multi-precision numbers are not the fixed size integers, it is wise to give multi-precision numbers the same rules and usages of the normal fixed size integers _everywhere this is possible and handy_. This has some advantages like:
- Reduces the cognitive burden to remember where they differ;
- Allows for less work to adapt routines that work with integers to work with BigInts. This is handy for generic code and for manual translation of code.
I have said everywhere this is possible and handy, because this is not always possible. You can't use a BigInt to index an array, and there are some situations where BigInts require a different algorithm (example: http://d.puremagic.com/issues/show_bug.cgi?id=7102 ). So I am not asking BigInt to be a drop-in replacement for int in all cases.
But I have seen a hundred cases where in Python it's handy to use the built-in multi-precision integers with normal algorithms useful for normal integers too.
So I have asked to allow implicit bool -> BigInt too:
import std.bigint;
void main() {
BigInt b = true;
}
This allows BigInt to be used as an int in a situation where it causes no harm. Introducing an usage difference here between int and BigInt in my opinion is gratuitous, doesn't help reduce bugs, it asks the programmer to remember one difference between them that gives nothing useful back. So that code should be accepted.
Bye,
bearophile

On 12/23/2011 01:42 PM, bearophile wrote:
>
> This allows BigInt to be used as an int in a situation where it causes no harm. Introducing an usage difference here between int and BigInt in my opinion is gratuitous, doesn't help reduce bugs, it asks the programmer to remember one difference between them that gives nothing useful back. So that code should be accepted.
>
> Bye,
> bearophile
+1.

FWIW, I've just added logical operations to my decimal number
library (https://github.com/andersonpd/decimal) and boolean
interoperability arose as a byproduct.
From std.bigint docs:
"All arithmetic operations are supported, except unsigned shift
right (>>>). Logical operations are not currently supported."
Maybe when support for logical ops are added support for booleans
will be introduced for consistency.
On Friday, 23 December 2011 at 12:42:24 UTC, bearophile wrote:
> Here I ask for opinions about a small enhancement request about
> BigInt that Don has refused:
>
> http://d.puremagic.com/issues/show_bug.cgi?id=7079
>
> It's not a very important thing, so I will probably avoid
> further arguing after this post :-)
>
>
> In some languages like the ones derived from Pascal, like Ada,
> and in some other languages Java the boolean type is very
> distinct from the integer values. So to test if a integer value
> is zero you write something like:
>
>
> int x = 10;
> if (x == 0) {
> // do A ...
> } else {
> // do B ...
> }
>
>
> In languages derived from C, like C++ and D and many others,
> like Python too, the integer values are valid in a boolean
> context too. This is valid C/C++/D code:
>
> int x = 10;
> if (x) {
> // do B ...
> } else {
> // do A ...
> }
>
>
>
> This is handy in some situations, like when you want to count
> how many true cases there are:
>
>
> void main() {
> auto s1 = "hello";
> auto s2 = "hallo";
> int hamming_distance = 0;
> assert(s1.length == s2.length);
> foreach (i, c1; s1)
> hamming_distance += c1 != s2[i];
> assert(hamming_distance == 1);
> }
>
>
> While in a Delphi/Java language you need something like:
>
> if (c1 != s2[i])
> hamming_distance++;
>
>
> The implicit conversion from boolean to integer is equally
> handy in Python:
>
> s1 = "hello"
> s2 = "hallo"
> hamming_distance = sum(c1 != c2 for c1,c2 in zip(s1, s2))
> assert hamming_distance == 1
>
>
> D language regards boolean values as a subset of integers so it
> allows implicit conversion from bool to integer, but not from
> int to bool. I don't think this will ever change in D2/D3:
>
>
> void main() {
> int x = 1;
> bool b = true;
> x = b; // bool -> int is OK
> int y = x > 3; // bool -> int is OK
> b = x; // int -> bool is an Error
> }
>
>
> While multi-precision numbers are not the fixed size integers,
> it is wise to give multi-precision numbers the same rules and
> usages of the normal fixed size integers _everywhere this is
> possible and handy_. This has some advantages like:
> - Reduces the cognitive burden to remember where they differ;
> - Allows for less work to adapt routines that work with
> integers to work with BigInts. This is handy for generic code
> and for manual translation of code.
>
> I have said everywhere this is possible and handy, because this
> is not always possible. You can't use a BigInt to index an
> array, and there are some situations where BigInts require a
> different algorithm (example:
> http://d.puremagic.com/issues/show_bug.cgi?id=7102 ). So I am
> not asking BigInt to be a drop-in replacement for int in all
> cases.
> But I have seen a hundred cases where in Python it's handy to
> use the built-in multi-precision integers with normal
> algorithms useful for normal integers too.
>
>
> So I have asked to allow implicit bool -> BigInt too:
>
>
> import std.bigint;
> void main() {
> BigInt b = true;
> }
>
>
> This allows BigInt to be used as an int in a situation where it
> causes no harm. Introducing an usage difference here between
> int and BigInt in my opinion is gratuitous, doesn't help reduce
> bugs, it asks the programmer to remember one difference between
> them that gives nothing useful back. So that code should be
> accepted.
>
> Bye,
> bearophile

On 23.12.2011 14:42, bearophile wrote:
> D language regards boolean values as a subset of integers so it allows implicit conversion from bool to integer, but not from int to bool. I don't think this will ever change in D2/D3:
Discussing about pros and cons of such implicit conversion is one thing,
but that's already how it works for basic types, so I agree it must work
for more advanced ones.
After all, BigInt is a big int, and it should feel like that. If one
expects a += (b < c); to work for an int (and it works), it should work
for BigInts as well.
Another option is also disabling it for basic types, but better not
define different behavior for similar types.

On Fri, 23 Dec 2011 23:42:24 +1100, bearophile <bearophileHUGS@lycos.com>
wrote:
> Here I ask for opinions about a small enhancement request about BigInt
> that Don has refused ...
I'm with Don on this one because a boolean and an integer are not the same
concept, and even though many programming languages implement booleans
using integers, it still doesn't make them the same thing.
Using booleans as implicit integers can be seen as laziness (i.e. poor
documentation of coder's intent) or a legitimate mistake (i.e
unintentional usage by coder). By insisting that an explicit cast must be
used when one wants a boolean to behave as an integer allows the coder's
intent to become more apparent when reading their source code. This has
nothing to do with machine code generation, just source code legibility.
--
Derek Parnell
Melbourne, Australia

Derek Parnell:
> I'm with Don on this one because a boolean and an integer are not the same
> concept, and even though many programming languages implement booleans
> using integers, it still doesn't make them the same thing.
D doesn't implement booleans with integers, D has a boolean type. But D allows bools to implicitly cast to ints/longs.
Not allowing a BigInt to be initialized with a bool value introduce an inconsistency that makes BigInts more complex because there is one more rule to remember, less inter-operable with ints, and I don't think it introduces advantages.
> Using booleans as implicit integers can be seen as laziness (i.e. poor
> documentation of coder's intent) or a legitimate mistake (i.e
> unintentional usage by coder).
In my code such mistakes are uncommon.
> By insisting that an explicit cast must be
> used when one wants a boolean to behave as an integer allows the coder's
> intent to become more apparent when reading their source code. This has
> nothing to do with machine code generation, just source code legibility.
Casts are powerful tools, they shut up the compiler and they assume the programmer is perfectly right and has perfect knowledge of what's going on. In practice my experience shows that the programmer (me too) sometimes doesn't have perfect knowledge (usually because the code later was modified, turning the cast into a bug because casts are often silent). This is why it's better to avoid casts, not requiring them in the first place, unless they are useful. In this case I think a cast introduces more danger than the risks caused by implicit bool->int conversions.
Bye,
bearophile

On Friday, December 23, 2011 17:19:26 bearophile wrote:
> Derek Parnell:
> > I'm with Don on this one because a boolean and an integer are not the
> > same concept, and even though many programming languages implement
> > booleans using integers, it still doesn't make them the same thing.
>
> D doesn't implement booleans with integers, D has a boolean type. But D
> allows bools to implicitly cast to ints/longs.
I'd actually argue that that's a mistake. Implicitly converting an int to a
bool is one thing - that's useful in conditional expressions - but converting
from bool to int is something else entirely. I see no reason to expand that
problem into BigInt. _int_ shouldn't have it, let alone BigInt.
- Jonathan M Davis

On 12/23/2011 11:34 PM, Jonathan M Davis wrote:
> On Friday, December 23, 2011 17:19:26 bearophile wrote:
>> Derek Parnell:
>>> I'm with Don on this one because a boolean and an integer are not the
>>> same concept, and even though many programming languages implement
>>> booleans using integers, it still doesn't make them the same thing.
>>
>> D doesn't implement booleans with integers, D has a boolean type. But D
>> allows bools to implicitly cast to ints/longs.
>
> I'd actually argue that that's a mistake. Implicitly converting an int to a
> bool is one thing - that's useful in conditional expressions
Using an expression in a conditional amounts to an explicit cast. This
is an unrelated issue. Implicit int -> bool conversion is disallowed in
D. It loses information.
> - but converting from bool to int is something else entirely. I see no reason to expand that
> problem into BigInt. _int_ shouldn't have it, let alone BigInt.
>
> - Jonathan M Davis
There is really no problem with that. I have never seen anyone complain
about implicit bool -> int conversion. Why do you think it is bad? Does
anyone have an example to back up the claim that it is bad?

On Friday, December 23, 2011 23:52:00 Timon Gehr wrote:
> There is really no problem with that. I have never seen anyone complain
> about implicit bool -> int conversion. Why do you think it is bad? Does
> anyone have an example to back up the claim that it is bad?
They're completely different types and mean completely different things. It's
one thing to convert from a narrower integer to a wider one, but bool is _not_
an integer. Would you implicitly convert a string to an int? No. It's not a
number. I don't see any reason to treat bool any differently on that count.
bool isn't a number either. It's true or it's false. The problem is that C
conflated bool with int, and on some level that behavior still exists in D. But
bool and int are two entirely different types and entirely different concepts.
- Jonathan M Davis