www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Bits

reply Arcane Jill <Arcane_member pathlink.com> writes:
Some problems and inconsistencies with bits.

(1). The expression:

       (a == b)
yields type int, not type bit. Indeed, the statement:
       bit b = (a == b);
is rejected by the compiler, and must be transofmed into:
       bit b = cast(bit)(a==b);
in order to compile. (2) (BUG). The statements:
       bit b = true;
       uint i = -b;
leave i containing the value 0x000000FF. I would have expected 0xFFFFFFFF. (3) The declaration:
       bit[256] b;
creates an array of 256 bytes, not 32 bytes (which would be 256 bits in total). Arcane Jill
May 24 2004
next sibling parent reply "Matthew" <matthew.hat stlsoft.dot.org> writes:
Yep, it stinks. A proper boolean type, that's not implicitly convertible to any
other type, is required. All (sub-)expressions should be of boolean type.


"Arcane Jill" <Arcane_member pathlink.com> wrote in message
news:c8s7tg$1b7s$1 digitaldaemon.com...
 Some problems and inconsistencies with bits.

 (1). The expression:

       (a == b)
yields type int, not type bit. Indeed, the statement:
       bit b = (a == b);
is rejected by the compiler, and must be transofmed into:
       bit b = cast(bit)(a==b);
in order to compile. (2) (BUG). The statements:
       bit b = true;
       uint i = -b;
leave i containing the value 0x000000FF. I would have expected 0xFFFFFFFF. (3) The declaration:
       bit[256] b;
creates an array of 256 bytes, not 32 bytes (which would be 256 bits in total). Arcane Jill
May 24 2004
parent Juan C <Juan_member pathlink.com> writes:
Yep, it stinks. A proper boolean type, that's not implicitly convertible to any
other type, is required. All (sub-)expressions should be of boolean type.
Not implicitly convertible _from_ either.
May 24 2004
prev sibling next sibling parent reply "Ben Hinkle" <bhinkle mathworks.com> writes:
I can't reproduce items 1 or 3. Here's the code I ran:

int main() {
  int a1,a2;
  a1 = 3;
  a2 = 4;
  bit b = (a1 == a2);
  printf("%d\n",b);

  bit b2 = true;
  uint i = -b2;
  printf("%u\n",i);

  bit[256] b3;
  printf("%d\n",b3.sizeof);

  return 0;
}

results in

0
255
32

Personally item 2 seems like an odd programming practice so the current
behavior doesn't bother me.

"Arcane Jill" <Arcane_member pathlink.com> wrote in message
news:c8s7tg$1b7s$1 digitaldaemon.com...
 Some problems and inconsistencies with bits.

 (1). The expression:

       (a == b)
yields type int, not type bit. Indeed, the statement:
       bit b = (a == b);
is rejected by the compiler, and must be transofmed into:
       bit b = cast(bit)(a==b);
in order to compile. (2) (BUG). The statements:
       bit b = true;
       uint i = -b;
leave i containing the value 0x000000FF. I would have expected 0xFFFFFFFF. (3) The declaration:
       bit[256] b;
creates an array of 256 bytes, not 32 bytes (which would be 256 bits in
total).
 Arcane Jill
May 24 2004
parent reply Arcane Jill <Arcane_member pathlink.com> writes:
In article <c8t5d2$2ngh$1 digitaldaemon.com>, Ben Hinkle says...
I can't reproduce items 1 or 3. Here's the code I ran:

int main() {
  int a1,a2;
  a1 = 3;
  a2 = 4;
  bit b = (a1 == a2);
  printf("%d\n",b);
It appears that ints behave differently from objects in this regard. The following (very similar) code fails to compile: class A {} int main() { A a1,a2; a1 = new A; a2 = new A; bit b = (a1 == a2); return 0; } The error message is "cannot implicitly convert int to bit". Curious.
  bit[256] b3;
  printf("%d\n",b3.sizeof);
I was wrong. False alarm. My error was due to the fact that MS visual studio reports b3 as being of type unsigned char[256] when you use that to step through the code. But upon investigation, visual studio is simply wrong. I must assume therefore that the debug information in the .obj file is somehow storing the type incorrectly - which does not change the execution of the program one iota.
Personally item 2 seems like an odd programming practice so the current
behavior doesn't bother me.
I noticed it because I encountered it. It's a normal thing to do in a subtract routine where you have to propogate a carry bit (note: bit) to the next uint of a multiprecision integer. Personally, I would favor two distinct types: bit and bool, with bit being considered an arithmetic type (like a one bit wide unsigned integer), and bool able only to take values true and false. In this scenario, bits could be auto-promoted to int or uint (since those would be widening conversions) but bool could not (because logical types should not auto-convert to arithmetic types).
May 24 2004
next sibling parent Juan C <Juan_member pathlink.com> writes:
Personally, I would favor two distinct types: bit and bool, with bit being
considered an arithmetic type (like a one bit wide unsigned integer), and bool
able only to take values true and false. In this scenario, bits could be
auto-promoted to int or uint (since those would be widening conversions) but
bool could not (because logical types should not auto-convert to arithmetic
types).
Yay, another vote!
May 24 2004
prev sibling next sibling parent "Ben Hinkle" <bhinkle mathworks.com> writes:
"Arcane Jill" <Arcane_member pathlink.com> wrote in message
news:c8t9sf$2uua$1 digitaldaemon.com...
 In article <c8t5d2$2ngh$1 digitaldaemon.com>, Ben Hinkle says...
I can't reproduce items 1 or 3. Here's the code I ran:

int main() {
  int a1,a2;
  a1 = 3;
  a2 = 4;
  bit b = (a1 == a2);
  printf("%d\n",b);
It appears that ints behave differently from objects in this regard. The following (very similar) code fails to compile: class A {} int main() { A a1,a2; a1 = new A; a2 = new A; bit b = (a1 == a2); return 0; } The error message is "cannot implicitly convert int to bit". Curious.
Yes, that is curious. Also note bit b = (a1 is a2); works.
May 24 2004
prev sibling next sibling parent reply Derek Parnell <derek psych.ward> writes:
On Mon, 24 May 2004 17:03:11 +0000 (UTC), Arcane Jill wrote:

[snip]
 
 Personally, I would favor two distinct types: bit and bool, with bit being
 considered an arithmetic type (like a one bit wide unsigned integer), and bool
 able only to take values true and false. In this scenario, bits could be
 auto-promoted to int or uint (since those would be widening conversions) but
 bool could not (because logical types should not auto-convert to arithmetic
 types).
100% agree. 'bit' is a very small unsigned integer whose value is in the range 0 (zero) to 1 (one). And I presume 'sizeof(bit)' should return the number of bytes the the implementation uses. 'bool' is NOT an integer. It can only have either of two values - TRUE or FALSE. But to make some people's lives a bit easier 'cast(bit)bool' ==> 0 for FALSE and 1 for TRUE. -- Derek 25/May/04 8:36:43 AM
May 24 2004
parent reply "Bruno A. Costa" <bruno codata.com.br> writes:
Derek Parnell wrote:

 On Mon, 24 May 2004 17:03:11 +0000 (UTC), Arcane Jill wrote:
 
 [snip]
  
 Personally, I would favor two distinct types: bit and bool, with bit
 being considered an arithmetic type (like a one bit wide unsigned
 integer), and bool able only to take values true and false. In this
 scenario, bits could be auto-promoted to int or uint (since those would
 be widening conversions) but bool could not (because logical types should
 not auto-convert to arithmetic types).
100% agree. 'bit' is a very small unsigned integer whose value is in the range 0 (zero) to 1 (one). And I presume 'sizeof(bit)' should return the number of bytes the the implementation uses. 'bool' is NOT an integer. It can only have either of two values - TRUE or FALSE. But to make some people's lives a bit easier 'cast(bit)bool' ==> 0 for FALSE and 1 for TRUE.
This is good. I vote for a bool type. Or at least an implicit cast from boolean expressions to bit. Bruno.
May 25 2004
parent reply "Matthew" <matthew.hat stlsoft.dot.org> writes:
"Bruno A. Costa" <bruno codata.com.br> wrote in message
news:c8vc34$k50$1 digitaldaemon.com...
 Derek Parnell wrote:

 On Mon, 24 May 2004 17:03:11 +0000 (UTC), Arcane Jill wrote:

 [snip]

 Personally, I would favor two distinct types: bit and bool, with bit
 being considered an arithmetic type (like a one bit wide unsigned
 integer), and bool able only to take values true and false. In this
 scenario, bits could be auto-promoted to int or uint (since those would
 be widening conversions) but bool could not (because logical types should
 not auto-convert to arithmetic types).
100% agree. 'bit' is a very small unsigned integer whose value is in the range 0 (zero) to 1 (one). And I presume 'sizeof(bit)' should return the number of bytes the the implementation uses. 'bool' is NOT an integer. It can only have either of two values - TRUE or FALSE. But to make some people's lives a bit easier 'cast(bit)bool' ==> 0 for FALSE and 1 for TRUE.
This is good. I vote for a bool type.
Good.
 Or at least an implicit cast
 from boolean expressions to bit.
Bad, IMO. May I ask what uses you see for implicit conversion, and/or your objections to all such bool-integral conversions being explicit? Cheers Matthew
May 25 2004
parent "Bruno A. Costa" <bruno codata.com.br> writes:
Matthew wrote:

 
 "Bruno A. Costa" <bruno codata.com.br> wrote in message
 news:c8vc34$k50$1 digitaldaemon.com...
 Derek Parnell wrote:

 On Mon, 24 May 2004 17:03:11 +0000 (UTC), Arcane Jill wrote:

 [snip]

 Personally, I would favor two distinct types: bit and bool, with bit
 being considered an arithmetic type (like a one bit wide unsigned
 integer), and bool able only to take values true and false. In this
 scenario, bits could be auto-promoted to int or uint (since those
 would be widening conversions) but bool could not (because logical
 types should not auto-convert to arithmetic types).
100% agree. 'bit' is a very small unsigned integer whose value is in the range 0 (zero) to 1 (one). And I presume 'sizeof(bit)' should return the number of bytes the the implementation uses. 'bool' is NOT an integer. It can only have either of two values - TRUE or FALSE. But to make some people's lives a bit easier 'cast(bit)bool' ==> 0 for FALSE and 1 for TRUE.
This is good. I vote for a bool type.
Good.
 Or at least an implicit cast
 from boolean expressions to bit.
Bad, IMO. May I ask what uses you see for implicit conversion, and/or your objections to all such bool-integral conversions being explicit? Cheers Matthew
Well, as I said, my vote is for a bool type. The second option (but not the best option) is just to avoid casts like: bit b; b = cast(bit) (a==c); So, I think we should stay witn the best. Bruno.
May 25 2004
prev sibling next sibling parent reply J Anderson <REMOVEanderson badmama.com.au> writes:
Arcane Jill wrote:

Personally, I would favor two distinct types: bit and bool, with bit being
considered an arithmetic type (like a one bit wide unsigned integer), and bool
able only to take values true and false. 
I'm against having two types. Bit and bool overlap on just about all functionality. However I do think bit should work for all cases a bool would work. -- -Anderson: http://badmama.com.au/~anderson/
May 25 2004
next sibling parent reply "Matthew" <matthew.hat stlsoft.dot.org> writes:
 Arcane Jill wrote:

Personally, I would favor two distinct types: bit and bool, with bit being
considered an arithmetic type (like a one bit wide unsigned integer), and bool
able only to take values true and false.
I'm against having two types. Bit and bool overlap on just about all functionality. However I do think bit should work for all cases a bool would work.
In what ways do they overlap? bit is a 1-bit integer value, whereas a boolean type is exactly that. I see no more commonality between them as between a pointer and, on a 32-bit architecture, int. We very much need a boolean type, otherwise the (IMO) majority of us who want/need one will provide our own (as I have in std.recls, std.windows.registry, etc.) and we'll end up in exactly the same still-stinking mess that C/C++ is in.
May 25 2004
parent reply J Anderson <REMOVEanderson badmama.com.au> writes:
Matthew wrote:

Arcane Jill wrote:

    

Personally, I would favor two distinct types: bit and bool, with bit being
considered an arithmetic type (like a one bit wide unsigned integer), and bool
able only to take values true and false.

      
I'm against having two types. Bit and bool overlap on just about all functionality. However I do think bit should work for all cases a bool would work.
In what ways do they overlap? bit is a 1-bit integer value, whereas a boolean type is exactly that.
I see a bit as a flag. It's on or off, true or false. bool x; if (x) { } bit x; if (x) { } what's the difference between these functions? bit x = true; bool x = true; What's the difference? bit has more functionality but it still supports all the functionality of bool.
I see no more commonality between them as between a pointer and, on a 32-bit
architecture, int.

We very much need a boolean type, otherwise the (IMO) majority of us who
want/need one will provide our own (as I have in std.recls,
std.windows.registry,
etc.) and we'll end up in exactly the same still-stinking mess that C/C++ is in.
  
Ok I've thought about it a bit more. Your probably right, as long as bit doesn't loose all the functionality it has now I guess a bool type could be useful as sub-set of bit to prevent users from specifying numbers into functions. -- -Anderson: http://badmama.com.au/~anderson/
May 25 2004
next sibling parent reply "Matthew" <matthew.hat stlsoft.dot.org> writes:
"J Anderson" <REMOVEanderson badmama.com.au> wrote in message
news:c8vbnc$jfd$1 digitaldaemon.com...
 Matthew wrote:

Arcane Jill wrote:



Personally, I would favor two distinct types: bit and bool, with bit being
considered an arithmetic type (like a one bit wide unsigned integer), and
bool
able only to take values true and false.
I'm against having two types. Bit and bool overlap on just about all functionality. However I do think bit should work for all cases a bool would work.
In what ways do they overlap? bit is a 1-bit integer value, whereas a boolean type is exactly that.
I see a bit as a flag. It's on or off, true or false. bool x; if (x) { } bit x; if (x) { } what's the difference between these functions? bit x = true; bool x = true; What's the difference?
What's the difference between bit x = true; if(x){} void *pv = cast(void*)(1); if(pv){} It's the same argument. Too logically unrelated types can be made to seem to have the same semantics in a limited set of circumstances. But this is a fool's paradise - not saying you're a fool, of course; I'd be direct if I was saying that ;) - since it is the ways in which the similarities fall down which catch us out. <self-promotion>I give a good long rant about this in Imperfect C++ - only a couple more months ...</self-promotion> IMO, the "if(pv)" above should be illegal, and all conditional (sub-)expressions must be explicitly boolean. Thus int i; if(i) // error if(i != 0) // ok if(pv) // error if(null !== pv) // ok This does not appeal to fans of terse code, but it does appeal to fans of maintenance and unambiguity. Flame away, sigh ...
 bit has more functionality but it still supports all the functionality
 of bool.

I see no more commonality between them as between a pointer and, on a 32-bit
architecture, int.

We very much need a boolean type, otherwise the (IMO) majority of us who
want/need one will provide our own (as I have in std.recls,
std.windows.registry,
etc.) and we'll end up in exactly the same still-stinking mess that C/C++ is
in.

 Ok I've thought about it a bit more.  Your probably right, as long as
 bit doesn't loose all the functionality it has now I guess a bool type
 could be useful as sub-set of bit to prevent users from specifying
 numbers into functions.
I don't propose any change in bit whatsoever, save that true and false may no longer be implicitly used by it, or any other integral type. I want a boolean type that is: - not implicitly convertible to any other type - is the type of all conditional expressions - is of variable size, according to context. It would default to a (time) efficiently representation as the same size as the architecture, e.g. 32-bits, in order to avoid the costs in the implicit "b = !b ? 0 : 1" evaluation. However, it could be align'd to any alignment, right down to 1-bit, according to the user's decision. The compiler will handle all issues regarding accessing by pointer. (The one issue here is that accessing a bit by pointer is tricky, but could be achieve by having a boolean ptr as a two-value entity. Not sure about this one as yet, however ...) These changes would make things ridiculously simple and umabiguous, without causing any of the storage or performance or correctness problems encountered in the boolean types of C/C++/Java.
May 25 2004
next sibling parent reply Hauke Duden <H.NS.Duden gmx.net> writes:
Matthew wrote:
 I don't propose any change in bit whatsoever, save that true and false may no
 longer be implicitly used by it, or any other integral type. I want a boolean
 type that is:
 
 - not implicitly convertible to any other type
 - is the type of all conditional expressions
 - is of variable size, according to context. It would default to a (time)
 efficiently representation as the same size as the architecture, e.g. 32-bits,
in
 order to avoid the costs in the implicit "b = !b ? 0 : 1" evaluation. However,
it
 could be align'd to any alignment, right down to 1-bit, according to the user's
 decision. The compiler will handle all issues regarding accessing by pointer.
 (The one issue here is that accessing a bit by pointer is tricky, but could be
 achieve by having a boolean ptr as a two-value entity. Not sure about this one
as
 yet, however ...)
For what it's worth, I completely agree with Matthew. At least with his first two points. I'm not sure if the size saving argument of point 3 really justifies the complexity of having a type with a variable size, though. My gut tells me that this kind of thing can cause lots of headaches and bug opportunities, both for the compiler writer and for the programmer who uses it. I'd be happy if bool would be implemented(!) as an int, where !=0 is the same as true and 0 is false. So it basically means that the compiler has to translate bool==true to bool!=0 instead of bool==1 and boolA==boolB to a suitable construct that ensures correctness. Otherwise it could internally be treated as a typedef'ed int without arithmetic operations. Even Walter could use such a bool type ;) (he currently uses int instead of bit because int is faster). The need to conserve memory for bools is so rare that I think this would be sufficient and it has the added benefit of being dead simple. If size should really become an issue (for example with huge bool arrays) the programmer still has the option to use bit instead. He won't have the advantages of a real bool type then, but at least he will be aware of the issues (since he explicitly chose bit) and can deal with them properly. Note that I'm only talking about the internal implementation here. Bool should still be a completely independent type, of course, with no implicit conversions. Hauke
 
 These changes would make things ridiculously simple and umabiguous, without
 causing any of the storage or performance or correctness problems encountered
in
 the boolean types of C/C++/Java.
 
 
 
 
May 25 2004
parent "Matthew" <matthew.hat stlsoft.dot.org> writes:
"Hauke Duden" <H.NS.Duden gmx.net> wrote in message
news:c8vg4g$r6t$1 digitaldaemon.com...
 Matthew wrote:
 I don't propose any change in bit whatsoever, save that true and false may no
 longer be implicitly used by it, or any other integral type. I want a boolean
 type that is:

 - not implicitly convertible to any other type
 - is the type of all conditional expressions
 - is of variable size, according to context. It would default to a (time)
 efficiently representation as the same size as the architecture, e.g.
32-bits, in
 order to avoid the costs in the implicit "b = !b ? 0 : 1" evaluation.
However, it
 could be align'd to any alignment, right down to 1-bit, according to the
user's
 decision. The compiler will handle all issues regarding accessing by pointer.
 (The one issue here is that accessing a bit by pointer is tricky, but could
be
 achieve by having a boolean ptr as a two-value entity. Not sure about this
one as
 yet, however ...)
For what it's worth, I completely agree with Matthew. At least with his first two points. I'm not sure if the size saving argument of point 3 really justifies the complexity of having a type with a variable size, though. My gut tells me that this kind of thing can cause lots of headaches and bug opportunities, both for the compiler writer and for the programmer who uses it. I'd be happy if bool would be implemented(!) as an int, where !=0 is the same as true and 0 is false. So it basically means that the compiler has to translate bool==true to bool!=0 instead of bool==1 and boolA==boolB to a suitable construct that ensures correctness. Otherwise it could internally be treated as a typedef'ed int without arithmetic operations. Even Walter could use such a bool type ;) (he currently uses int instead of bit because int is faster). The need to conserve memory for bools is so rare that I think this would be sufficient and it has the added benefit of being dead simple. If size should really become an issue (for example with huge bool arrays) the programmer still has the option to use bit instead. He won't have the advantages of a real bool type then, but at least he will be aware of the issues (since he explicitly chose bit) and can deal with them properly. Note that I'm only talking about the internal implementation here. Bool should still be a completely independent type, of course, with no implicit conversions.
Actually, I completely agree with you. I was just pandering to the violent objectors, if they're still involving themselves, that came out the last time I asked for sizeof(boolean) to be sizeof(register), late last year.
May 25 2004
prev sibling parent Juan C <Juan_member pathlink.com> writes:
- not implicitly convertible to any other type
Nor _from_ any type.
May 25 2004
prev sibling parent Arcane Jill <Arcane_member pathlink.com> writes:
In article <c8vbnc$jfd$1 digitaldaemon.com>, J Anderson says...

bool x;

if (x)
{

}

bit x;

if (x)
{

}

what's the difference between these functions?
The first would be legitimate. The second would be a syntax error. The compiler would require if (x==1).
bit x = true;

bool x = true;

What's the difference?
The first would be syntax error. The compiler would require bit x = 1; The second would be legitimate.
Ok I've thought about it a bit more.  Your probably right, as long as 
bit doesn't loose all the functionality it has now I guess a bool type 
could be useful as sub-set of bit to prevent users from specifying 
numbers into functions.
Not a subset. In fact, not interchangable AT ALL without an explicit cast. Arcane Jill
May 25 2004
prev sibling next sibling parent reply James McComb <alan jamesmccomb.id.au> writes:
J Anderson wrote:

 I'm against having two types.  Bit and bool overlap on just about all 
 functionality.
I understand what you mean, but strictly speaking, if bit is arithmetic and bool is logical, they don't overlap at all. Interface for bit: +, -, * , / etc. Interface for bool: &&, || etc. James McComb
May 25 2004
parent reply J Anderson <REMOVEanderson badmama.com.au> writes:
James McComb wrote:

 J Anderson wrote:

 I'm against having two types.  Bit and bool overlap on just about all 
 functionality.
I understand what you mean, but strictly speaking, if bit is arithmetic and bool is logical, they don't overlap at all. Interface for bit: +, -, * , / etc. Interface for bool: &&, || etc. James McComb
So a bit isn't a integer like Matthew suggests then? -- -Anderson: http://badmama.com.au/~anderson/
May 25 2004
parent reply James McComb <alan jamesmccomb.id.au> writes:
J Anderson wrote:

 Interface for bit: +, -, * , / etc.
 Interface for bool: &&, || etc.
So a bit isn't a integer like Matthew suggests then?
Yes, I think that bit should be a type of integer. A bit should be an integer with a value ranging from 0 to 1 inclusive. It could be safely promoted to larger integer types. A bool should be a type with the non-numeric values true and false. An explicit cast would be required to convert to and from bool. I believe Arcane Jill is advocating the same thing. James McComb
May 25 2004
next sibling parent reply James McComb <alan jamesmccomb.id.au> writes:
James McComb wrote:

 A bit should be an integer with a value ranging from 0 to 1 inclusive.
 It could be safely promoted to larger integer types.
 
 A bool should be a type with the non-numeric values true and false.
 An explicit cast would be required to convert to and from bool.
In addition, I'm also happy with the idea of bool being implemented internally as an int. James McComb
May 25 2004
parent reply "Matthew" <matthew.hat stlsoft.dot.org> writes:
"James McComb" <alan jamesmccomb.id.au> wrote in message
news:c913e1$8ho$1 digitaldaemon.com...
 James McComb wrote:

 A bit should be an integer with a value ranging from 0 to 1 inclusive.
 It could be safely promoted to larger integer types.

 A bool should be a type with the non-numeric values true and false.
 An explicit cast would be required to convert to and from bool.
In addition, I'm also happy with the idea of bool being implemented internally as an int.
It's inefficient. Consider the following boolean sub-expression: void *pv = ... if(null !== pv) {} That's all ok, and perfectly efficient. The compiler simply tests pv against 0. However, what if we want to remember the expr, as in bool b = (null !== pv); The compiler then has to do the following (assuming 32-bit arch): b = (0 != (cast(uint)(pv) & 0xffffffff) ? 1 : 0 This is what happens in C++ with a vast majority of current C++ compilers not warning you about the performance hit. (See "Imperfect C++", in Sept, for the full details for this and other boolean blunders.) Thus, a boolean type must be the size of the natural int size of the architecture. The only question remains whether we have something special going on for boolean arrays or not. If we do, and if an element in the boolean array is < 1-byte, then there are the addressing problems. Unless I've seriously missed something in my deliberations on this subject over several years, along with all the people who've opined on this issue on this NG for the last couple of years, there is *no way* to satisfy all the requirements of space efficiency, time efficiency and addressability of a boolean type. That being the case, maybe the way forward is to have the boolean type the size of the natural int size of the architecture, and have standard library bit container(s)? Thoughts, everyone?
May 25 2004
parent reply Andy Friesen <andy ikagames.com> writes:
Matthew wrote:

 Unless I've seriously missed something in my deliberations on this subject over
 several years, along with all the people who've opined on this issue on this NG
 for the last couple of years, there is *no way* to satisfy all the requirements
 of space efficiency, time efficiency and addressability of a boolean type.
 
 That being the case, maybe the way forward is to have the boolean type the size
 of the natural int size of the architecture, and have standard library bit
 container(s)?
 
 Thoughts, everyone?
This sounds fine to me. It's consistent, easy to explain (and thus understand), and convenient for the hardware. One thing that kind of bugs me, though, is what all those other bits mean. In a "nice" D application, they would always be unset, but D code doesn't have to be nice. (pointer coersion and so forth) So is the truth value of a bool based on its zero-ness, purely on the lowest bit, or what? (does it even matter?) -- andy
May 25 2004
parent reply "Matthew" <matthew.hat stlsoft.dot.org> writes:
"Andy Friesen" <andy ikagames.com> wrote in message
news:c915cr$bv0$1 digitaldaemon.com...
 Matthew wrote:

 Unless I've seriously missed something in my deliberations on this subject
over
 several years, along with all the people who've opined on this issue on this
NG
 for the last couple of years, there is *no way* to satisfy all the
requirements
 of space efficiency, time efficiency and addressability of a boolean type.

 That being the case, maybe the way forward is to have the boolean type the
size
 of the natural int size of the architecture, and have standard library bit
 container(s)?

 Thoughts, everyone?
This sounds fine to me. It's consistent, easy to explain (and thus understand), and convenient for the hardware. One thing that kind of bugs me, though, is what all those other bits mean. In a "nice" D application, they would always be unset, but D code doesn't have to be nice. (pointer coersion and so forth) So is the truth value of a bool based on its zero-ness, purely on the lowest bit, or what? (does it even matter?)
It would depend on the context. For boolean sub-expression testing we can use the architecture-width optimistically efficient "if" or "if not". Hence, the following code void *pv = int i = short s = if( null === pv && 0 == i && 0 != s) would be translatable to (machine speak) if( 0 == pv && /* This is a 32-bit test, e.g. cmp eax, 0. (Remember, pv is an int, to the processer) */ 0 == i && /* So is this. */ 0 != s) /* This is a 16-bit test, e.g. cmp ax, 0 */ However, for conversions, which would be explicit, the compiler would have to step in. Consider void *pv = cast(void*)(0xffff0000); bit t = cast(boolean)(pv !== null); If the (second) cast only passed the bit pattern, the truncation error would yield b = 0. Not what we wanted, since the integral value of the boolean sub-expression "pv !== null" is true, which must convert to 1, not 0, in integral form. This means that the compiler must do the inefficient comparison and value selection mentioned in a previous post, as in void *pv = cast(void*)(0xffff0000); bit t = (pv !== null) ? 1 : 0; This is one more reason, along with logic, and avoidance of errors, why conversions to and from boolean types (and sub-expressions) must be only available with a cast, since they are inefficient. Walter, you convinced yet?
May 25 2004
parent reply Roberto Mariottini <Roberto_member pathlink.com> writes:
In article <c9179j$fag$1 digitaldaemon.com>, Matthew says...

[...]
This is one more reason, along with logic, and avoidance of errors, why
conversions to and from boolean types (and sub-expressions) must be only
available with a cast, since they are inefficient.

Walter, you convinced yet?
He, he, I think it's just impossible to convince Walter about this. We'll add the boolean type in the first ISO standard draft ;-) BTW, would you like to add your good argumentation on the wiky page at http://www.wikiservice.at/wiki4d/wiki.cgi?BooleanNotEquBit Ciao
May 26 2004
parent reply "Matthew" <matthew.hat stlsoft.dot.org> writes:
"Roberto Mariottini" <Roberto_member pathlink.com> wrote in message
news:c91il7$10h8$1 digitaldaemon.com...
 In article <c9179j$fag$1 digitaldaemon.com>, Matthew says...

 [...]
This is one more reason, along with logic, and avoidance of errors, why
conversions to and from boolean types (and sub-expressions) must be only
available with a cast, since they are inefficient.

Walter, you convinced yet?
He, he, I think it's just impossible to convince Walter about this. We'll add the boolean type in the first ISO standard draft ;-)
Well, if he wants me to write a book about D, I'm going to be giving my true and honest opinions. ;)
 BTW, would you like to add your good argumentation on the wiky page at
 http://www.wikiservice.at/wiki4d/wiki.cgi?BooleanNotEquBit
No, but I'm happy for you to quote me, if you have the time.
May 26 2004
parent reply Arcane Jill <Arcane_member pathlink.com> writes:
Walter, you convinced yet?
He, he, I think it's just impossible to convince Walter about this. We'll add the boolean type in the first ISO standard draft ;-)
There is another, as yet unmentioned reason, why the type bool should exist, and should NOT be considered arithmetic. How many times have you guys written the following bug into your code? :
       if (a = b)
instead of:
       if (a == b)
Show me someone who answers "never", and I'll show you someone who doesn't write software. With a bool type, that bug would be a compile-time error, requiring you to change it to one of:
       if (a == b)         // if it was a bug, or
       if ((a = b) != 0)   // if it was deliberate
Convinced yet? There's almost unanimous support for a non-arithmetic bool... Arcane Jill
May 27 2004
next sibling parent reply "Ivan Senji" <ivan.senji public.srce.hr> writes:
"Arcane Jill" <Arcane_member pathlink.com> wrote in message
news:c943n8$1mdk$1 digitaldaemon.com...
Walter, you convinced yet?
He, he, I think it's just impossible to convince Walter about this. We'll add the boolean type in the first ISO standard draft ;-)
There is another, as yet unmentioned reason, why the type bool should
exist, and
 should NOT be considered arithmetic. How many times have you guys written
the
 following bug into your code? :

       if (a = b)
instead of:
       if (a == b)
Show me someone who answers "never", and I'll show you someone who doesn't
write
 software. With a bool type, that bug would be a compile-time error,
requiring
 you to change it to one of:
I agree that we need a real bool type, but have you tried that? It doesn't work i get the error message: E:\Developement\D\Projects\factoriel\factoriel.d(20): '=' does not give a boolean result when i try if(a=b)
       if (a == b)         // if it was a bug, or
       if ((a = b) != 0)   // if it was deliberate
Convinced yet? There's almost unanimous support for a non-arithmetic
bool...
 Arcane Jill
I was allready convinced :)
May 27 2004
parent reply Arcane Jill <Arcane_member pathlink.com> writes:
Incidently (and again, this is only a semi-serious suggestion, and I don't care
if anyone floors this with a rational argument), is there any reason why the
type of the sizeof property has to be int for every type?

I mean, bit.sizeof were to return a float instead of an int, then it could
return its conceptual size of 0.125 bytes.

(Of course, malloc(float) and similar would then have to be defined to round up,
not down!)

Jill
May 27 2004
next sibling parent "Matthew" <matthew.hat stlsoft.dot.org> writes:
I certainly hope the type is not int _now_! It should be uint, and there's an
argument for it being ulong, although that's perhaps only in D-64.

"Arcane Jill" <Arcane_member pathlink.com> wrote in message
news:c96nrd$anp$1 digitaldaemon.com...
 Incidently (and again, this is only a semi-serious suggestion, and I don't care
 if anyone floors this with a rational argument), is there any reason why the
 type of the sizeof property has to be int for every type?

 I mean, bit.sizeof were to return a float instead of an int, then it could
 return its conceptual size of 0.125 bytes.

 (Of course, malloc(float) and similar would then have to be defined to round
up,
 not down!)

 Jill
May 28 2004
prev sibling parent J Anderson <REMOVEanderson badmama.com.au> writes:
Arcane Jill wrote:

Incidently (and again, this is only a semi-serious suggestion, and I don't care
if anyone floors this with a rational argument), is there any reason why the
type of the sizeof property has to be int for every type?

I mean, bit.sizeof were to return a float instead of an int, then it could
return its conceptual size of 0.125 bytes.

(Of course, malloc(float) and similar would then have to be defined to round up,
not down!)

Jill
  
Floats are allot less efficient to work with then fixed types. -- -Anderson: http://badmama.com.au/~anderson/
May 28 2004
prev sibling parent "Matthew" <matthew.hat stlsoft.dot.org> writes:
"Arcane Jill" <Arcane_member pathlink.com> wrote in message
news:c943n8$1mdk$1 digitaldaemon.com...
Walter, you convinced yet?
He, he, I think it's just impossible to convince Walter about this. We'll add the boolean type in the first ISO standard draft ;-)
There is another, as yet unmentioned reason, why the type bool should exist,
and
 should NOT be considered arithmetic. How many times have you guys written the
 following bug into your code? :

       if (a = b)
instead of:
       if (a == b)
Show me someone who answers "never", and I'll show you someone who doesn't
write
 software. With a bool type, that bug would be a compile-time error, requiring
 you to change it to one of:

       if (a == b)         // if it was a bug, or
       if ((a = b) != 0)   // if it was deliberate
Convinced yet? There's almost unanimous support for a non-arithmetic bool... Arcane Jill
I can't say "never", but I can say "not once in the last three years". See "Imperfect C++" (if you can wait for September 9th; http://www.awprofessional.com/titles/0321228774/) for several different pejorative rants on this topic. ;)
May 27 2004
prev sibling parent "Matthew" <matthew.hat stlsoft.dot.org> writes:
Sounds like we're all just about on the same page.

Walter?

"James McComb" <alan jamesmccomb.id.au> wrote in message
news:c912or$7mt$1 digitaldaemon.com...
 J Anderson wrote:

 Interface for bit: +, -, * , / etc.
 Interface for bool: &&, || etc.
So a bit isn't a integer like Matthew suggests then?
Yes, I think that bit should be a type of integer. A bit should be an integer with a value ranging from 0 to 1 inclusive. It could be safely promoted to larger integer types. A bool should be a type with the non-numeric values true and false. An explicit cast would be required to convert to and from bool. I believe Arcane Jill is advocating the same thing. James McComb
May 25 2004
prev sibling parent reply Derek Parnell <derek psych.ward> writes:
On Tue, 25 May 2004 19:22:30 +0800, J Anderson wrote:

 Arcane Jill wrote:
 
Personally, I would favor two distinct types: bit and bool, with bit being
considered an arithmetic type (like a one bit wide unsigned integer), and bool
able only to take values true and false. 
I'm against having two types. Bit and bool overlap on just about all functionality. However I do think bit should work for all cases a bool would work.
Well actually that turns out not to be the case. int a; bit b; bool c; int d; a = 5; b = 1; c = true; d = a + b; // Ok, makes sense. d = a + c; // Not ok. Does not make sense. d = a + cast(bit)c; // Well if you real have to... that last line is really another way of saying ... d = a + (c ? 1 : 0); -- Derek 26/May/04 9:30:45 AM
May 25 2004
parent reply Juan C <Juan_member pathlink.com> writes:
 d = a + cast(bit)c; // Well if you real have to...

that last line is really another way of saying ...

 d = a + (c ? 1 : 0);
No, the former line is evil, and the latter is preferred. The former would be kinda like trying to do int x = cast(int) "123" ; what are you going to get? Certainly not the integer value 123 which appears to be the goal. (Granted you may want to do this some time for some reason, I have.) <soapbox> Although I'm sure that if boolean is changed in the language as proposed it will be implemented in such a way that the former will work, but it's best not to expect it to. Why demand that boolean be a true (whoops) boolean and then allow non-boolean access thereto? There should be no meaningful way to cast to or from boolean, only a test should work. Think of the equality, relational, and trinary operators as "casts" for boolean. Part of the goal (in my mind anyway) is to retrain C programmers from thinking of booleans as integers. Booleans are _not_ numeric values! </soapbox>
May 25 2004
next sibling parent reply Derek Parnell <derek psych.ward> writes:
On Wed, 26 May 2004 00:37:38 +0000 (UTC), Juan C wrote:

 d = a + cast(bit)c; // Well if you real have to...

that last line is really another way of saying ...

 d = a + (c ? 1 : 0);
No, the former line is evil, and the latter is preferred.
I agree. I was just trying to suggest a compromise, or concession, to help get the bool/bit/int differentiation across the line. ;-)
 The former would be kinda like trying to do
 int x = cast(int) "123" ;
 what are you going to get? Certainly not the integer value 123 which appears to
 be the goal. (Granted you may want to do this some time for some reason, I
 have.)
Yeah, we all know what you intend here, so maybe this is not such an 'evil' example. The 'cast' is explicitly saying "please convert the subject into the format that I'm specifying". In your example, convert "123" into an integer.
 <soapbox>
 Although I'm sure that if boolean is changed in the language as proposed it
will
 be implemented in such a way that the former will work, but it's best not to
 expect it to. Why demand that boolean be a true (whoops) boolean and then allow
 non-boolean access thereto? There should be no meaningful way to cast to or
from
 boolean, only a test should work. Think of the equality, relational, and
trinary
 operators as "casts" for boolean.
 
 Part of the goal (in my mind anyway) is to retrain C programmers from thinking
 of booleans as integers. Booleans are _not_ numeric values!
 </soapbox>
Not a bad goal at all; sign me up for the Cause. -- Derek 26/May/04 10:44:50 AM
May 25 2004
parent Regan Heath <regan netwin.co.nz> writes:
On Wed, 26 May 2004 10:49:45 +1000, Derek Parnell <derek psych.ward> wrote:
 The former would be kinda like trying to do
 int x = cast(int) "123" ;
 what are you going to get? Certainly not the integer value 123 which 
 appears to
 be the goal. (Granted you may want to do this some time for some 
 reason, I
 have.)
Yeah, we all know what you intend here, so maybe this is not such an 'evil' example. The 'cast' is explicitly saying "please convert the subject into the format that I'm specifying". In your example, convert "123" into an integer.
OR.. is x supposed to be set to the bits involved in the ascii characters "123" in that order? This is not such a silly suggestion if you're writing a text encryption routine that swaps bits on 32 bit boundaries. Regan. -- Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/
May 25 2004
prev sibling parent "Matthew" <matthew.hat stlsoft.dot.org> writes:
"Juan C" <Juan_member pathlink.com> wrote in message
news:c90osi$2rmp$1 digitaldaemon.com...
 d = a + cast(bit)c; // Well if you real have to...

that last line is really another way of saying ...

 d = a + (c ? 1 : 0);
No, the former line is evil, and the latter is preferred. The former would be kinda like trying to do int x = cast(int) "123" ; what are you going to get? Certainly not the integer value 123 which appears to be the goal. (Granted you may want to do this some time for some reason, I have.) <soapbox> Although I'm sure that if boolean is changed in the language as proposed it
will
 be implemented in such a way that the former will work, but it's best not to
 expect it to. Why demand that boolean be a true (whoops) boolean and then allow
 non-boolean access thereto? There should be no meaningful way to cast to or
from
 boolean, only a test should work. Think of the equality, relational, and
trinary
 operators as "casts" for boolean.

 Part of the goal (in my mind anyway) is to retrain C programmers from thinking
 of booleans as integers. Booleans are _not_ numeric values!
 </soapbox>
Hear, hear!
May 25 2004
prev sibling parent James McComb <alan jamesmccomb.id.au> writes:
Arcane Jill wrote:

 Personally, I would favor two distinct types: bit and bool, with bit being
 considered an arithmetic type (like a one bit wide unsigned integer), and bool
 able only to take values true and false. In this scenario, bits could be
 auto-promoted to int or uint (since those would be widening conversions) but
 bool could not (because logical types should not auto-convert to arithmetic
 types).
+1. And expressions like (a == b) should return bool. James McComb
May 25 2004
prev sibling next sibling parent Roel Mathys <roel.mathys yucom.be> writes:
Arcane Jill wrote:
 Some problems and inconsistencies with bits.
 
 (1). The expression:
 
 
      (a == b)
yields type int, not type bit. Indeed, the statement:
      bit b = (a == b);
is rejected by the compiler, and must be transofmed into:
      bit b = cast(bit)(a==b);
in order to compile. (2) (BUG). The statements:
      bit b = true;
      uint i = -b;
leave i containing the value 0x000000FF. I would have expected 0xFFFFFFFF. (3) The declaration:
      bit[256] b;
creates an array of 256 bytes, not 32 bytes (which would be 256 bits in total). Arcane Jill
template F(bit value:true) { void f() {printf("true\n");} } template F(bit value:false) { void f() {printf("false\n");} } void main() { F!(cast(bit)(1==1)).f(); // F!(1==1).f(); // does crash the compiler } bye roel
May 24 2004
prev sibling parent Jesus <Jesus_member pathlink.com> writes:
(2) (BUG). The statements:

       bit b = true;
       uint i = -b;
leave i containing the value 0x000000FF. I would have expected
0xFFFFFFFF. This is because bit is implemented as a byte. b = 0x01 -b = 0xFF = 255 cast(uint)(-b) = 0x000000FF = 255 The problem is you're using 2's complement arithmetic on unsigned types which doesn't semantically make sense, unless you're intending to use modular arithmetic. If there were such a thing as a signed byte (there might be for all I know) and you converted it to a signed int with those statements then you would expect to get 0xFFFFFFFF = -1
Jun 30 2004