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