June 02, 2004
"Walter" <newshound@digitalmars.com> wrote in message news:c9l2q1$2gui$1@digitaldaemon.com...
>
> "Matthew" <matthew.hat@stlsoft.dot.org> wrote in message news:c9k5lf$16nj$1@digitaldaemon.com...
> > The fact is that Walter is in an almost solitary minority on the bool
> issue, in
> > terms of the opinions expressed in this forum.
>
> The debate on bool goes back long, long before D. If there was consensus on what it should do, it would have been designed that way in C and C++, both languages more or less independently came up with a bool type, there were no legacy backwards compatibility issues, and in both languages bool implicitly converts to integral types. C and C++ doing it one way does not dictate what D does, but since D is meant to appeal to C/C++ programmers, diverging from C/C++ semantics has to have a pretty strong case for it.
>
> BTW, both C# and Java do not allow implicit conversion of bool to int.

As you well know, from reviewing "Imperfect C++", I think C/C++ have made a grave
mistake by not prescribing that sizeof(bool) == sizeof(int), and why compiler
manufacturers have "utilised" that missing prescription to blunder and defined
sizeof(bool) == 1.

I don't advocate that D do either of these things - i.e. fail to prescribe the size and presribe/use it as 1 - but D actually goes even further from the poor situation with sizeof(bool), since it defines it as a bit. This merely compounds the problems of having it as == 1, and adds the new hassles of addressing elements in arrays of "bool"s.

> > Also, the bit/int opEquals() point is well made.
>
> The reason for it being the int 0/!0 is because converting it to 0/1 adds 3
> instructions:
>     cmp    EAX,1
>     sbb    EAX,EAX
>     inc    EAX
> When sorting/searching a lot of data, this can add up.

Isn't this a clear argument for why we should prefer int to bit, and, therefore, why the bool alias should be int? If not, then I'm totally lost on your point.

> > That's fair enough, it's his party after all, even though it does rankle considerably. One's choice is to stay involved, and either live with it or endeavour to change it eventually, or to find a better language. I can
> tell you
> > that Walter would prefer that people with diverse opinions and experience
> should
> > stay around, even if, as I'm sure we've done with "bool", it it happens to irritate the hell out of him.
>
> No, it doesn't irritate the hell out of me <g>. I'm in the wrong business if it did. It does seem to irritate others, though, and I don't really understand why.

Well, I know you're skin's even thicker than mine, but you clearly _seem_ at a point of some exasperation to state that "and it's going to stay that way. There's a lot of very cool stuff coming for D, and I can't wait to get it implemented. I've had as much as I can take on the whole 15 years of bool business".

That reads to me like "I'm sick of this debate. I'm not changing my mind. You should all (let me) get on with more important things."


> > For the record, I completely disagree with Walter's apparent opinion that
> other,
> > presumably more complex things, are more important. Now that doesn't mean
> I'm
> > making personal attacks or anything, just that AJ's prophecy of standards committees needlessly raking over old ground is likely to come true, to
> all our
> > detriments. It's a shame, because I've personally had reactions from
> experienced
> > C++ (and other languages) exponents, and pretty much the first things they
> say
> > are
> >     - get rid of C's evil implicit conversions - which Walter's ruled out
>
> Languages that don't do implicit conversions are relative failures, and I've used some of those languages and know why. They're a pain to use. They require lots of casting to get real work done, and peppering one's routine code with casts is LESS typesafe than well understood implicit type conversions. Furthermore, complex C/C++ expressions will exhibit subtle changes in behavior when converted to D. This can be a disaster if it is, for example, crypto code.

I can see some sense in that, but I remain skeptical. If conditional (sub-)expressions are boolean, and not convertible to int

Now here's an idea. We (almost) all agree that we don't want pragmas, warnings or compiler-options that basically change the definition of the language. However, since we're in the pre-1.0 stage, why not allow a compiler flag -strict_boolean that will switch on a boolean type, sub-expressions and switch off interconversions. Then we can test, rather than debate, just how beneficial/onerous this stuff would be.

Yes, this more work, but the advantages would be:
1. It would kill this argument forever
2. It would make a great article
3. It would make a great chapter when we write "The Design and Evolution of D".
4. We could use this uncontestable knowledge in the many language-bashing/lauding
wars that are to come.

> Consider, for example, the following code:
>
> class A { void foo() { } }
> void test() { A a; a.foo(); }
>
> Which would work in C++, but fails in D. This regularly trips up people coming to D from C++. Fortunately, the code fails predictably in a manner that pinpoints the problem, the solution is explained, and one goes on. This will not happen if implicit conversion rules are changed

Not based on any of the changes I'd want. The compiler would simply fail to compile on the formerly-convertible expression. Nothing subtle about that.

>- the program will
> appear to work, but the result of the expression will be subtly different. Even worse, it will compute the same result with some values of the operands, and different results with others.
>
> So, one general principle I try to follow is that if D changes the rules, if one tries it the C++ way, one gets an obvious failure rather than a subtle, erratic one. This effectively rules out changing things like implicit conversion rules and operator precedence.
>
> >     - make typedefs strong - which D has done. Hurrah!
> >     - stop bool being an integral type - which Walter's ruled out
> >     - make an ABI - which has so far been ignored
>
> The ABI will happen, it's just premature.

Understood. I didn't mean to imply that it's not going to happen, just that it's not done so yet.

> >     - has it got libraries - which I would suggest more of us would be
> doing if
> > there was not still such fertile ground for language debates at a very low/fundamental level
>
> Fundamental language debates will go on as long as there are two or more programmers <g>.

True. And in the spirit of that, I will formally state that, despite my disagreeing with it, I can live with the implicit conversions between bool and int. What I cannot live with, and won't program to, is the fact that the boolean type (or alias) bool is a bit. This means that in all my D coding I'm going to have to continue to define the "boolean" type, based on int, albeit that I will move (and have already in the recent upgrade of recls) from it being a typedef to being an alias.

Can you meet me (/ us) halfway, and at least change the standard alias of bool from bit to int, and I can jettison all my "boolean"-based code?

>
> >     - give me decent templates - which we're certainly working towards
> >
> > So, we in our out? I'm still in. ;)
>
> And I'm glad you are, and hope Arcane Jill will stick around, too.

Limpet-like. :-)


June 02, 2004
Matthew wrote:
>>Fundamental language debates will go on as long as there are two or more
>>programmers <g>.
> 
> 
> True. And in the spirit of that, I will formally state that, despite my
> disagreeing with it, I can live with the implicit conversions between bool and
> int. What I cannot live with, and won't program to, is the fact that the boolean
> type (or alias) bool is a bit. This means that in all my D coding I'm going to
> have to continue to define the "boolean" type, based on int, albeit that I will
> move (and have already in the recent upgrade of recls) from it being a typedef to
> being an alias.
> 
> Can you meet me (/ us) halfway, and at least change the standard alias of bool
> from bit to int, and I can jettison all my "boolean"-based code?

I agree with Matthew that bool should be an int.

But, there is one thing that should be considered. If true is defined as !=0 instead of 1 then the following code will not work as intuitively expected:

bool a=1; //true
bool b=2; //also true

if(a && b!=a)
	printf("b=false");	//wrong answer


I think we could definitely put this to rest if bool was an int with one modification: a==b should be rewritten as (a && b) || (!a && !b).

Yes, it would cost performance but only when two bools are compared. And this happens VERY rarely (at least in my code). Plus an advanced compiler probably could optimize this back down to a single compare in a local context where it knows that true will always be 1.

When a bool is a bit, on the other hand, bool arrays will be slow and (more importantly) not easily slicable. And bool arrays are not quite that rare.

Hauke


June 03, 2004
"Matthew" <matthew.hat@stlsoft.dot.org> wrote in message news:c9ln6r$du0$1@digitaldaemon.com...
> As you well know, from reviewing "Imperfect C++", I think C/C++ have made
a grave
> mistake by not prescribing that sizeof(bool) == sizeof(int), and why
compiler
> manufacturers have "utilised" that missing prescription to blunder and
defined
> sizeof(bool) == 1.

Your argument that sizeof(bool) should be fixed and not left up to the implementation is sound, and is done in D. Your other argument that bool should be the same size as int for efficiency reasons isn't as compelling. To convert an into a bool requires something equivalent to (i?1:0), regardless of the size of the bool. Having random bool variables be int sized is no problem, but having arrays of them is a problem.

> I don't advocate that D do either of these things - i.e. fail to prescribe
the
> size and presribe/use it as 1 - but D actually goes even further from the
poor
> situation with sizeof(bool), since it defines it as a bit. This merely
compounds
> the problems of having it as == 1, and adds the new hassles of addressing elements in arrays of "bool"s.

A 'bit' by itself has a size of 1 byte. Only when turned into an array are they packed into bit positions in memory. While this doesn't address the bit array slicing problem, it seems to work rather well otherwise.

> > > Also, the bit/int opEquals() point is well made.
> > The reason for it being the int 0/!0 is because converting it to 0/1
adds 3
> > instructions:
> >     cmp    EAX,1
> >     sbb    EAX,EAX
> >     inc    EAX
> > When sorting/searching a lot of data, this can add up.
> Isn't this a clear argument for why we should prefer int to bit, and,
therefore,
> why the bool alias should be int?

No, because even if it is an int it still has to go through the (i?1:0)
operation.

> Well, I know you're skin's even thicker than mine, but you clearly _seem_
at a
> point of some exasperation to state that "and it's going to stay that way.
> There's a lot of very cool stuff coming for D, and I can't wait to get it
> implemented. I've had as much as I can take on the whole 15 years of bool
> business".
> That reads to me like "I'm sick of this debate. I'm not changing my mind.
You
> should all (let me) get on with more important things."

Ok, I can see how you read it that way. But I just wanted to point out that, while it's fun debating these things, it's time for D to move on.

> If conditional
> (sub-)expressions are boolean, and not convertible to int

What's the problem with converting them to int? Why pretend it isn't what it is, a 1 or a 0? I've built TTL hardware, single board computers from scratch, etc., and 0/1, true/false, on/off, yes/no, +5V/0V are all the same in my mind. (In fact, the only reason true and false are keywords in D is not because they are that useful, but because so many programmers believe they are useful <g> and would otherwise produce multiple conflicting definitions of them. It's also there to drive a stake in the heart of the execrable BASIC convention that true is 0xFFFF, and to thwart the equally miserable attempts to make tristate or even quadstate 'bools'.)

> Now here's an idea. We (almost) all agree that we don't want pragmas,
warnings or
> compiler-options that basically change the definition of the language.
However,
> since we're in the pre-1.0 stage, why not allow a compiler
flag -strict_boolean
> that will switch on a boolean type, sub-expressions and switch off interconversions. Then we can test, rather than debate, just how beneficial/onerous this stuff would be.

Having an alias of bool to int will mean that one could, for example, store '3' in a so-called bool. This is just no good. A bool needs to be constrained to be 0 or 1, or it isn't a bool. The D 'bit' type enforces this constraint, and so is the bool candidate.

The basic problem is there are tradeoffs with the semantics of bool and its implementation. Any time there are tradeoffs, there will be controversy. There is no design for it that will put things to rest once and for all.


> > Consider, for example, the following code:
> >
> > class A { void foo() { } }
> > void test() { A a; a.foo(); }
> >
> > Which would work in C++, but fails in D. This regularly trips up people coming to D from C++. Fortunately, the code fails predictably in a
manner
> > that pinpoints the problem, the solution is explained, and one goes on.
This
> > will not happen if implicit conversion rules are changed
>
> Not based on any of the changes I'd want. The compiler would simply fail
to
> compile on the formerly-convertible expression. Nothing subtle about that.

That's true for implicit narrowing conversions.

> > The ABI will happen, it's just premature.
> Understood. I didn't mean to imply that it's not going to happen, just
that it's
> not done so yet.

It's actually quite a bit of work to write.

> True. And in the spirit of that, I will formally state that, despite my disagreeing with it, I can live with the implicit conversions between bool
and
> int. What I cannot live with, and won't program to, is the fact that the
boolean
> type (or alias) bool is a bit. This means that in all my D coding I'm
going to
> have to continue to define the "boolean" type, based on int, albeit that I
will
> move (and have already in the recent upgrade of recls) from it being a
typedef to
> being an alias.

All right.

> Can you meet me (/ us) halfway, and at least change the standard alias of
bool
> from bit to int, and I can jettison all my "boolean"-based code?

Ack <g>


June 03, 2004
On Thu, 03 Jun 2004 01:47:36 +0200, Hauke Duden wrote:

> Matthew wrote:
>>>Fundamental language debates will go on as long as there are two or more programmers <g>.
>> 
>> True. And in the spirit of that, I will formally state that, despite my disagreeing with it, I can live with the implicit conversions between bool and int. What I cannot live with, and won't program to, is the fact that the boolean type (or alias) bool is a bit. This means that in all my D coding I'm going to have to continue to define the "boolean" type, based on int, albeit that I will move (and have already in the recent upgrade of recls) from it being a typedef to being an alias.
>> 
>> Can you meet me (/ us) halfway, and at least change the standard alias of bool from bit to int, and I can jettison all my "boolean"-based code?
> 
> I agree with Matthew that bool should be an int.
> 
> But, there is one thing that should be considered. If true is defined as !=0 instead of 1 then the following code will not work as intuitively expected:
> 
> bool a=1; //true
> bool b=2; //also true
> 
> if(a && b!=a)
> 	printf("b=false");	//wrong answer

I'm now sure I didn't have enough sleep last night ;-)
I thought that because 'a' and 'b' are declared as bool that the above
statement is interpreted by D as ...

 bool a=1; //true
 bool b=2; //also true

 if( (a!=0) && ((b!=0)!=(a!=0)))
 	printf("b=false");	//wrong answer

> I think we could definitely put this to rest if bool was an int with one modification: a==b should be rewritten as (a && b) || (!a && !b).

And thus 'a==b' is really '(a!=0)==(b!=0)'

> Yes, it would cost performance but only when two bools are compared. And this happens VERY rarely (at least in my code). Plus an advanced compiler probably could optimize this back down to a single compare in a local context where it knows that true will always be 1.
> 
> When a bool is a bit, on the other hand, bool arrays will be slow and (more importantly) not easily slicable. And bool arrays are not quite that rare.

Agreed. Arrays of bools are definitely used.

-- 
Derek
3/Jun/04 11:46:11 AM
June 03, 2004
On Wed, 2 Jun 2004 07:37:10 +0000 (UTC), Arcane Jill wrote:

> In article <c9j8jo$2t58$1@digitaldaemon.com>, Walter says...
>>
>> There is no consensus, nobody agrees

[snip]
> - but regarding
> the principle that a bool is not arithmetic, if you have been following this
> forum, you'll know you are in a very small minority here.

void main( )
{
    char[] myHat = "red";
    char[] myCoat = "blue";
    bool a = (myHat == "red");
    bool b = (myCoat == "blue");
    int  c;

    c = (3*a) + (b*b);

    printf("%d %d %d\n",a,b,c);
}


LOL!!!! Why this code above should compile is beyond my understanding. In
English it is like saying "Q:What is the sum of three times (is my hat
red?) and the square of (is my coat blue?)?  A: 4!"

It is *so* Douglas Adams/Monty Python/Lewis Carroll !

-- 
Derek
3/Jun/04 11:59:01 AM
Truth is not a number.
June 03, 2004
On Thu, 3 Jun 2004 12:21:24 +1000, Derek Parnell <derek@psych.ward> wrote:
> On Wed, 2 Jun 2004 07:37:10 +0000 (UTC), Arcane Jill wrote:
>
>> In article <c9j8jo$2t58$1@digitaldaemon.com>, Walter says...
>>>
>>> There is no consensus, nobody agrees
>
> [snip]
>> - but regarding
>> the principle that a bool is not arithmetic, if you have been following this
>> forum, you'll know you are in a very small minority here.
>
> void main( )
> {
>     char[] myHat = "red";
>     char[] myCoat = "blue";
>     bool a = (myHat == "red");
>     bool b = (myCoat == "blue");
>     int  c;
>
>     c = (3*a) + (b*b);
>
>     printf("%d %d %d\n",a,b,c);
> }
>
>
> LOL!!!! Why this code above should compile is beyond my understanding. In
> English it is like saying "Q:What is the sum of three times (is my hat
> red?) and the square of (is my coat blue?)?  A: 4!"
>
> It is *so* Douglas Adams/Monty Python/Lewis Carroll !

This works in C++ also, simply change "char[]" to "char *", you even get the same results.
(tho it depends on what the compiler does with those static strings!)

I think we can all agree 'bool' is not an arithmetic type. Can't we?

Regan.

-- 
Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/
June 03, 2004
"Derek Parnell" <derek@psych.ward> wrote in message news:c9m1v3$sv4$1@digitaldaemon.com...
> > - but regarding
> > the principle that a bool is not arithmetic, if you have been following
this
> > forum, you'll know you are in a very small minority here.
>
> void main( )
> {
>     char[] myHat = "red";
>     char[] myCoat = "blue";
>     bool a = (myHat == "red");
>     bool b = (myCoat == "blue");
>     int  c;
>
>     c = (3*a) + (b*b);
>
>     printf("%d %d %d\n",a,b,c);
> }
>
>
> LOL!!!! Why this code above should compile is beyond my understanding. In
> English it is like saying "Q:What is the sum of three times (is my hat
> red?) and the square of (is my coat blue?)?  A: 4!"

Here are some uses that I use now and then:
--------------------------------
1) Assembling a 'flags variable' from boolean components:

    bool Carry;
    bool Overflow;
    uint flags = (Carry << 6) | Overflow;

2) Add booleans to state variable to, for example, conditionally advance to the next state in a state machine:

    state += (foo == bar);

3) Use bools as an index into an array:

char[] response[2];
printf("answer is %.*s\n", response[ foo == bar ]);
------------------------------------
Of course, these can all be uglified with cast(int)b, or with (b?1:0), but I
just don't see the paradigm problem with bool being a 1 or a 0 integer.


June 03, 2004
On Wed, 2 Jun 2004 20:00:26 -0700, Walter wrote:

> "Derek Parnell" <derek@psych.ward> wrote in message news:c9m1v3$sv4$1@digitaldaemon.com...
>>> - but regarding
>>> the principle that a bool is not arithmetic, if you have been following
> this
>>> forum, you'll know you are in a very small minority here.
>>
>> void main( )
>> {
>>     char[] myHat = "red";
>>     char[] myCoat = "blue";
>>     bool a = (myHat == "red");
>>     bool b = (myCoat == "blue");
>>     int  c;
>>
>>     c = (3*a) + (b*b);
>>
>>     printf("%d %d %d\n",a,b,c);
>> }
>>
>>
>> LOL!!!! Why this code above should compile is beyond my understanding. In
>> English it is like saying "Q:What is the sum of three times (is my hat
>> red?) and the square of (is my coat blue?)?  A: 4!"
> 
> Here are some uses that I use now and then:
> --------------------------------
> 1) Assembling a 'flags variable' from boolean components:
> 
>     bool Carry;
>     bool Overflow;
>     uint flags = (Carry << 6) | Overflow;

And I would have coded it more explicitly...

      uint flags = (Carry ? 1<<6 : 0) | (Overflow? 1 : 0);

or maybe even ...

      flags = 0;
      if (Carry )
          flags |= 1<<6;
      if (Overflow)
          flags |= 1;


> 2) Add booleans to state variable to, for example, conditionally advance to the next state in a state machine:
> 
>     state += (foo == bar);

Not explict enough for my 'self-documenting code' standards.

      if (foo == bar)
          state += 1;

> 3) Use bools as an index into an array:
> 
> char[] response[2];
> printf("answer is %.*s\n", response[ foo == bar ]);

  printf("answer is %.*s\n", response[ (foo == bar ? 0 : 1) ]);

or

  char[] response[2];
  char[] msg;

  // Because one day there might be more than two potential messages.
  switch (foo)
  {
    case foo:
        msg = response[0];
        break;
    default:
        msg = response[1];
  };
  printf("answer is %.*s\n", msg);


> ------------------------------------
> Of course, these can all be uglified with cast(int)b, or with (b?1:0),

"uglified"? One person's "ugly" is another person "documentation" ;-)

> but I just don't see the paradigm problem with bool being a 1 or a 0 integer.

True, its just a way of thinking. A metaphor, if you will.

I prefer writing code that other people can easily read, so that they can understand my intentions. Brevity, for its own sake, does not guarentee legibilty.

I would always prefer clearest code over fastest code.

-- 
Derek
3/Jun/04 1:27:35 PM
June 03, 2004
Arcane Jill wrote:

> I've just noticed that the keyword "bool" is accepted by the compiler. Turns out
> this is because it's defined in "object.d" as an alias for bit.

My guess is, one of the reasons why Walter defined bool as an alias for bit was precisely to *prevent* people from defining it as an alias for int. However, Matthew immediately counter-attacked by defining a type called boolean which is an alias for int.

Walter can continue this battle by officially defining boolean as an alias for bit as well, and then Matthew will be forced to give his alias for int an awkward name like matthewsbool, or maybe truefalse.

Like many people who post to this group, I like the idea of a strongly-typed boolean type. But the language doesn't define one. So I move on. Instead of using bool, I use bit. Bool is just an alias for bit anyway, so why bother with bool? Just use bit, and move on. But what if I absolutely *must* have an int-based bool for performance reasons? Just use int, and move on.

What about Matthew's boolean type? I think that this type just creates confusion and inconsistency. Is D going to have *three* boolean types now, bit, bool and boolean? Let's cut this proliferation of boolean types off at the beginning. Just use bit (or if necessary, int).

But what about the strongly-typed boolean we want? By all means, keep requesting it. But the language does not define one (yet), so until and unless it does, please don't add to the confusion by trying to define your own.

James McComb

June 03, 2004
Come on, mate. We're entering crazy-land now.

What you've shown are three rare cases when using a boolean as an integral is useful. I agree that it can be useful, and I recognise at least two of these idioms myself. But you're now showing extreme bias in your arguments. These are rare cases, and for which the addition of an "uglifying" cast couldn't be termed onerous in anyone's imagination, no matter how hard one wants to prove a point.

There is absolutely no way I can take seriously the argument that uses such as these, easily facilitated by a cast, in any way compensate for the myriad cases where the convertibility causes problems.

Even were they anything more than about 1 to 1000 in prevalence, the fact is that adding the strength to bool would cause you (and me) to use a cast, when occasionally doing these things. Well, that's good! It makes the code clearer, not more obtuse.  But leaving things as they are for the sake of these marginal cases - cause let's be honest, it's not gorgeous code, is it? - means that we're subject to all the problems encountered in C, and especially C++, whereby a bool is passed as the length of a string, or the number of elements in a vector<>, or its "truth" is misrepresented by truncation, etc. etc. etc an infinitum.

Like I've said, at the end of the day I think you're going to say No! to us all on this bool issue because _you_ don't like it. Fair enough. I don't expect D to be perfect. If you're putting your foot down, just say so. I still respect you in the morning.

But please don't resort to this kind of stuff. Telling us black's white, and green's somewhere over there isn't going to wash.

:(

"Walter" <newshound@digitalmars.com> wrote in message news:c9m4di$10gd$1@digitaldaemon.com...
>
> "Derek Parnell" <derek@psych.ward> wrote in message news:c9m1v3$sv4$1@digitaldaemon.com...
> > > - but regarding
> > > the principle that a bool is not arithmetic, if you have been following
> this
> > > forum, you'll know you are in a very small minority here.
> >
> > void main( )
> > {
> >     char[] myHat = "red";
> >     char[] myCoat = "blue";
> >     bool a = (myHat == "red");
> >     bool b = (myCoat == "blue");
> >     int  c;
> >
> >     c = (3*a) + (b*b);
> >
> >     printf("%d %d %d\n",a,b,c);
> > }
> >
> >
> > LOL!!!! Why this code above should compile is beyond my understanding. In
> > English it is like saying "Q:What is the sum of three times (is my hat
> > red?) and the square of (is my coat blue?)?  A: 4!"
>
> Here are some uses that I use now and then:
> --------------------------------
> 1) Assembling a 'flags variable' from boolean components:
>
>     bool Carry;
>     bool Overflow;
>     uint flags = (Carry << 6) | Overflow;
>
> 2) Add booleans to state variable to, for example, conditionally advance to the next state in a state machine:
>
>     state += (foo == bar);
>
> 3) Use bools as an index into an array:
>
> char[] response[2];
> printf("answer is %.*s\n", response[ foo == bar ]);
> ------------------------------------
> Of course, these can all be uglified with cast(int)b, or with (b?1:0), but I
> just don't see the paradigm problem with bool being a 1 or a 0 integer.
>
>