February 27, 2006
Walter Bright wrote:
> "Ivan Senji" <ivan.senji_REMOVE_@_THIS__gmail.com> wrote in message news:dttebh$2kqq$1@digitaldaemon.com...
> 
>>>Ever seen this:
>>>
>>>while(1)
>>
>>I sure did, and it scares the hell out of me :)
> 
> 
> Why? This is a practice I got into with C/C++, and I did it because 1 cannot be redefined by the preprocessor into something goofy. I.e., I *knew* what it was without having to go spelunking through header files. 
> 

The reason should be obvious. While(condition). Condition should be boolean (true or false). 1 is neither. It is an integer. Using 1 (or any other int) in a conditions place just isn't type safe.

What if you (as a compiler writer) decide (how ever unlikely) that true should for some good reasons be implemented as being 0, or bool should be implemented as float, or something else).

PS
No need to answer because I know this is one topic where we can't convince you. :)
February 27, 2006
Georg Wrede wrote:
> Kyle Furlong wrote:
> 
>> Georg Wrede wrote:
>>
>>>
>>>
>>> This is getting hilarious...
> 
> 
> 
>> Georg, reading your posts on this NG has given me great insight into the breadth of your knowledge and the depth of your wisdom. Your sarcasm is always poigniant and appropo. Your jibes at your fellow NG's always in good taste. And your blind cheerleading and bandwagoning the height of prudence and solid judgement. Keep up the good work!
> 
> 
> Thanks!
> 
> Which reminds me, better go to bed before it gets too hilarious...
> 
> georg
> 
> PS, haven't had this much fun for a long time. I hope everyone else enjoyed it too!

Me too. NG chating is a funny thing.
February 27, 2006
Walter Bright wrote:
> "Ivan Senji" <ivan.senji_REMOVE_@_THIS__gmail.com> wrote in message news:dttebh$2kqq$1@digitaldaemon.com...
> 
>>>Ever seen this:
>>>
>>>while(1)
>>
>>I sure did, and it scares the hell out of me :)
> 
> 
> Why? This is a practice I got into with C/C++, and I did it because 1 cannot be redefined by the preprocessor into something goofy. I.e., I *knew* what it was without having to go spelunking through header files. 

One more thing. I heared from a Ruby user that in Ruby 0 means true.
To that user while(1) is pefectly obvious it is a block of code executed exactly once. No problems in understanding that for a Ruby user.

But to me 1 isn't true, and isn't false. It is an implementation detail that should be hidden from users.

As I said in another thread: programming language constructs should have a meaning when translated to a human language.

What would: "if 75 then some people dont like type safety" mean? To me and a lot more people it means nothing.
February 27, 2006
In article <dtuatr$l0k$1@digitaldaemon.com>, Ivan Senji says...
>
>Walter Bright wrote:
>> "Ivan Senji" <ivan.senji_REMOVE_@_THIS__gmail.com> wrote in message news:dttebh$2kqq$1@digitaldaemon.com...
>> 
>>>>Ever seen this:
>>>>
>>>>while(1)
>>>
>>>I sure did, and it scares the hell out of me :)
>> 
>> 
>> Why? This is a practice I got into with C/C++, and I did it because 1 cannot be redefined by the preprocessor into something goofy. I.e., I *knew* what it was without having to go spelunking through header files.
>> 
>
>The reason should be obvious. While(condition). Condition should be boolean (true or false). 1 is neither. It is an integer. Using 1 (or any other int) in a conditions place just isn't type safe.

One of my students once had code written like this:

bool b1 = ... complex expression ... ;
..
bool b2 = ... complex expression ... ;
..
bool b3 = ... complex expression ... ;
..
if (b1 || (b2 && 3))
{
.. remove the file ...
}

(note the 'b' missing from 'b3').
Its program obviously removed the file at every run, no matter how it set the
three variables, even when the debugger said they were false all the three.
When I explained the student that 3 is always true, he asked to me: "Why? What
'3' has in common with 'true'?". I didn't know what to say.
Then the students complained at me that the compiler was buggy, since it didn't
signal that construct as an error. It took me one hour to explain this C/C++
design flaw/decision, but I think I didn't convince them all.

Ciao


February 27, 2006
Ivan Senji wrote:
> One more thing. I heared from a Ruby user that in Ruby 0 means true.

To clarify, since that makes it sound a bit too much like "...and 1 means false": in Ruby the only two things that are false are, of course, false itself, and nil, which is similar to D's null. 0, like all other numbers, is true.
February 27, 2006
Georg Wrede skrev:
> Tom wrote:
>> Georg Wrede says...
>>> Ivan Senji wrote:
>>>> Georg Wrede wrote:
>>>>> Ivan Senji wrote:
>>>>>> Georg Wrede wrote:
>>>>>>> Derek Parnell wrote:
>>>>>>>> Georg Wrede wrote:

[snip]

> In this post alone, there's a half dozen references to "my kind of bool" or "your kind of bool", by various people.
> 
> Probably somebody should start making a table of their properties! :-)

Lets try. First the two extremes:

Numerical bool
-------------
True is 1, false is 0. Math is computed in a modulo-2 algebra (the result of all operations is computed mod (%) 2).
This bool is an integer type, and should also be implicitly castable to int. Analogous to the unsigned integer types:

bool:   mod 2 algebra
ubyte:  mod 256 algebra
ushort: mod 65536 algebra
uint:   mod 4294967296 algebra
ulong:  mod 18446744073709551616 algebra

Boolean operators (&,|,^,~,...) works as expected and are implementable efficiently. Arithmetic operators have the following properties:

+ behaves like xor (1+1 = 0)
* behaves like and

This type can be implemented efficiently as an (1, 2, 4, ...)-byte integer by either a) always mask the result of any operation cast to a bool by by &1 or b) consider all bits but the least significant to be undefined (meaning mask &1 when cast to a longer type)

Downside: Even integers (2,4,...) would be cast into a boolean 0 (false).

This is the pure numeric bool type. CPU-friendly.


Logical bool
------------
True and false are the only allowed values of this boolean variable. The internal representation is irrelevant.

Boolean operators behaves as expected. Arithmetic operators should either be:

a) forbidden, or
b) defined as in boolean algebra (* == and, + == or, ~ == not).

This bool should not be implicitly convertible to anything and should not be allowed to take place in arithmetics with other types.

Is this less CPU-friendly than a numerical bool? See comments below.


C++ bool, C99 _Bool
-------------------
C++ and C99 defines its boolean somewhere in between the Numerical and the Logical boolean (i.e. gets none of them right). The bool type is defined to be a numeric type implicitly castable to int (and therefore promotes to int/uint). Casting anything (x) to a bool yields 1 unless x == 0. This makes this bool-type quite different from a pure numeric type:  (Consider x a boolean variable.)

There are no overflows:
++x, x++, x += 1 all sets x to 1.
But there are underflows:
--x, x--, x -= 1 flips the value of x.

Even though much caution is taken making sure a bool only ever has the value 1 or 0, the integer promotion breaks everything:

bool a = true;
bool b = a+a;
assert(b == true); // OK
assert(a+a == true); // FAILS
assert(a+true == true); // FAILS
assert(true+true == true); // FAILS

Hence the rule: Never compare anything to true. (Or never use arithmetic operations on a bool.)


Java boolean
------------
The Java boolean follows the definition of Logical bool above, and disables arithmetic operators. Bools are never promoted to ints. Bools can not even be cast to ints.

There are no caveats using the Java boolean type, but you occasionally need to write a bit more code to make the compiler happy.


D bool
------
I'm not fully aware how bools now are defined in D. The basic idea seems to be the same as C99/C++, but with one small difference:
- Can not implicitly convert integer literals other than 0 and 1 to bool.

This difference feels slightly inconsistent because you can implicitly convert a non literal integer to a bool.

(There is also another difference that is likely a bug (*) )

Can anyone please fill in what other differences there are?


Comments
--------
Integer promotion makes "== true" a trap just waiting to be sprung for a numerical bool. The advantages of being able to do arithmetics on a bool are cases such as:

bool addPadding = something();
int pos = 10 + addPadding * 5;

Compared to:
int pos = 10 + addPadding ? 5 : 0;

Could help a compiler avoid a branching instruction... But you get the branching when forcing the bool to {0,1} instead.

Are there any other advantages?

Could a logical bool not be defined as being true when !0 and false otherwise, without the need to clamp it to {0,1}? Would this not be more efficient than the current bool? This would mean that the argument against opEquals returning a bool would vanish for instance. The only thing that would be less efficient would be comparing two boolean variables with each other (a rare occurrence) and that would not be less efficient than today unless there are many more comparisons than assignments.

With dead horses in mind, my suggestion would be to make the D bool a _logical_ bool that is implicitly convertible _from_ any type that can be used as a condition expression (if(...)) but not _to_ any other type. Internal representation is irrelevant (could even be an ABI-thing).

/Oskar

---

*) The other difference in D bool that is likely a bug:
- Like C99/C++, D makes sure that anything (x) cast to a bool yields 1 unless x == 0, but differs when arithmetics are done on the bool type itself:

bool a = 0;
--a;
assert(a == false || a == true); // FAILS(!) (a is set to 255)

bool t = true;
bool b = t+t;
assert(b == true); //OK
bool c = 0;
c++;
c++;
assert(c == true || c == false); // FAILS

But:

bool d = 0;
d += 2;
assert(d == true || d == false); // OK

The last case works due to promotion bool -> int -> bool but the failing cases do not take that route.

(being consistent, the definitions of post/predec of a bool should be to flip its value and post/preinc should set it to true)
February 27, 2006
Deewiant wrote:
> Ivan Senji wrote:
> 
>>One more thing. I heared from a Ruby user that in Ruby 0 means true.
> 
> 
> To clarify, since that makes it sound a bit too much like "...and 1 means
> false": in Ruby the only two things that are false are, of course, false itself,
> and nil, which is similar to D's null. 0, like all other numbers, is true.

Thanks for the clarification. It is really interesting how Ruby takes a completly different approach. Not that I agree with it. Strange and arbitrary decision IMO to make all numbers true. Why not make all numbers false?

February 27, 2006
Ivan Senji wrote:
> Deewiant wrote:
>> Ivan Senji wrote:
>>
>>> One more thing. I heared from a Ruby user that in Ruby 0 means true.
>>
>>
>> To clarify, since that makes it sound a bit too much like "...and 1 means
>> false": in Ruby the only two things that are false are, of course,
>> false itself,
>> and nil, which is similar to D's null. 0, like all other numbers, is
>> true.
> 
> Thanks for the clarification. It is really interesting how Ruby takes a completly different approach. Not that I agree with it. Strange and arbitrary decision IMO to make all numbers true. Why not make all numbers false?
> 

Probably because of Ruby's TIMTOWTDI approach - There Is More Than One Way To Do
It. Thus, it tries to cater to programmers of all languages - including C, and
so if you liked to write "while (1)" before you can still write "while (1)". You
can also write "loop do", "for (;;)", "while (true)", and probably do the same
thing in at least a dozen other ways.

Point being that Ruby has no reason - and it might even be against its idioms - to take so clearly a deviant approach to true and false as to declare numbers false, when in most languages people nowadays use everything apart from 0 is true.

Why, then, 0 is true, I cannot say; probably because all other numbers are true,
and 0 has no need to be an exception. It might be true in other languages
because they are strongly typed (or at least somewhat strongly - C isn't that
strongly typed, and even in D pointer arithmetic can do quite a bit to break the
type system, AFAIK), and a "false" value is very handy for a function that
returns an integer. In Ruby, you can just return false or nil, whichever is
appropriate, on error, even if the method in question normally returns an integer.
February 27, 2006
"Thomas Kuehne" <thomas-dloop@kuehne.cn> wrote in message news:0fo9d3-mb8.ln1@birke.kuehne.cn...
> # import std.stdio;
> #
> # int main(){
> # int i = 3;
> # bool a = true;

The next line goes around the type system completely, invalidates any invariants on the contents, and so any "surprising" results should be unsurprising:

> # bool b = *(cast(bool*)cast(void*) &i);

> #
> # writefln("a: %s", a);
> # writefln("b: %s", b);
> # writefln("int: %s", cast(int)b); // line 9
> # writefln("a+b: %s", a+b); // line 10
> #
> # return 0;
> # }
>
> I know, nobody writes code like that ...
>
> surprise:
> true -> 3 // line 9
> true + true -> 4 // line 10


February 27, 2006
"Ivan Senji" <ivan.senji_REMOVE_@_THIS__gmail.com> wrote in message news:dtuatr$l0k$1@digitaldaemon.com...
> Walter Bright wrote:
>> Why? This is a practice I got into with C/C++, and I did it because 1 cannot be redefined by the preprocessor into something goofy. I.e., I *knew* what it was without having to go spelunking through header files.
> The reason should be obvious. While(condition). Condition should be boolean (true or false). 1 is neither. It is an integer. Using 1 (or any other int) in a conditions place just isn't type safe.

1 isn't type safe??

> What if you (as a compiler writer) decide (how ever unlikely) that true should for some good reasons be implemented as being 0, or bool should be implemented as float, or something else).

That would break just about every C and C++ program in existence. Not going to happen. The reason I used 1 was because *it could never break* and because it has the property of being "inspectible." Inspectible means I can look at it and know what it does without having to refer to other things.

> PS No need to answer because I know this is one topic where we can't convince you. :)

LOL, I agree with you there.