March 08, 2006
Chris Miller wrote:
> On Tue, 07 Mar 2006 19:47:38 -0500, Georg Wrede <georg.wrede@nospam.org>  wrote:
> 
>> but more like
>>
>>      bool x = strcmp("foo", "bar");
>>      if (!x) { /* do stuff */ }        // match
>>      else { /* call the cops! */ }     // no match
> 
> You shouldn't even be doing that! You're inverting the meaning of true and  false. Use int.

Yeah, I know. (In hindsight, in this NG, maybe I should have tried to find a C function that returns 0 on failure. :-) )

Then again it's supposed to be easy to use C from D, and there are a lot of functions that return int values such that zero signifies true and anything else signifies false, and, one is also supposed to be able to use the particular [nonzero] return value for other purposes. (Call this old school efficiency or whatever, but as long as we are supposed to use C libraries, that's what we'll have to live with.)

>> Now what happens to
>>
>>      if (stcmp("foo", "bar")) {}
> 
> 
> If this wasn't allowed I'd be furious.

I bet you wouldn't be alone!


In the first example, the reason for using bool was to be explicit about *not* intending to use the value for other than true/false, otherwise of course an int would be used instead.

Admittedly,

    bool x = strcmp("foo", "bar");

is bad code. Inverted meaning of x, and also a nonobvious name for a boolean variable. Better would be

    bool areDifferent = strcmp("foo", "bar");

(which unfortunately doesn't compile on 0.149), or better

    bool stringsMatch = ! strcmp("foo", "bar");

but this would have diverted the point of the example, since the "!" makes the code compilable!

For C functions that return int to signify truth value, one now (as of 0.149) has to do a cast. That becomes cumbersome if one has to do a lot of C library usage. It also makes the code less readable.

Seems there are two options

    bool a,b,c,d;

    a = cast(bool) strcmp("foo", "bar");
    b = cast(bool) strcmp("foo", "baf");
    c = cast(bool) strcmp("foo", "bag");
    d = cast(bool) strcmp("foo", "bad");

or the newly found "cast to bool operator", brought up by BCS (in D.announce 3032)

    a = !! strcmp("foo", "bar");
    b = !! strcmp("foo", "baf");
    c = !! strcmp("foo", "bag");
    d = !! strcmp("foo", "bad");

This is certainly less typing, and it shrouds less the original code. If it weren't for this discovery, I'd have a *hard time* living with this last change in D.

So the "!!" might become a much used idiom in D now. I wonder what the reaction from the C++ crowd will be.

---

(Aside:) In real code of course, one should never invert booleans, and one should always use variable names with semantic content for the reader. Thus, one probably would write something like


    bool match;

    match = ! strcmp("foo", "bar");

    if (match)
    {
        /* do stuff */
    }
    else
    {
        /* call the cops! */
    }
March 08, 2006
Georg Wrede skrev:
> or the newly found "cast to bool operator", brought up by BCS (in D.announce 3032)
> 
>     a = !! strcmp("foo", "bar");
>     b = !! strcmp("foo", "baf");
>     c = !! strcmp("foo", "bag");
>     d = !! strcmp("foo", "bad");
> 
> This is certainly less typing, and it shrouds less the original code. If it weren't for this discovery, I'd have a *hard time* living with this last change in D.
> 
> So the "!!" might become a much used idiom in D now. I wonder what the reaction from the C++ crowd will be.

I've used !! to clamp a value to {0,1} in C since ages. One advantage of having to use !! is that the performance penalty of converting to bool is no longer hidden. (This may not be so bad on x86 (or, setne), but may on other architectures involve branching).

/Oskar
March 08, 2006
Walter Bright wrote:
> "Derek Parnell" <derek@psych.ward> wrote in message news:1o1ukrzuobjw5$.19cyl0ofx7fqs$.dlg@40tude.net...
>> It seems that arithmetic operators also work on booleans so I guess the
>> operator list above is either not correct or this is a bug.
> 
> It's a bug. Sigh. It always takes me two tries to get this right :-( 
> 
> 
It's more than a bug. It is impossible to have arithmetic operators not work on booleans, if you have implicit conversion from bool to int. Because bools will be threated like an int. Isn't it right?

What we should have, is not have implicit conversion from bool to non-bool.

Let me recall a post I made, which I don't know if you read, for more info:
news://news.digitalmars.com:119/du9cnl$2h9j$3@digitaldaemon.com


-- 
Bruno Medeiros - CS/E student
http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#D
March 08, 2006
On Wed, 08 Mar 2006 21:49:22 +1100, Georg Wrede <georg.wrede@nospam.org> wrote:

> For C functions that return int to signify truth value, one now (as of 0.149) has to do a cast. That becomes cumbersome if one has to do a lot of C library usage. It also makes the code less readable.

I'd like to bring up two points about this. Firstly, the strcmp() function is not really the one you need to have as an example of C-programs-that-return-an-int-as-a-boolean. This function is actually designed to return one of *three* values - not a boolean. It returns zero if the two strings are equal, an integer less than zero if the first string is less than the second, and an integer greater than zero if the first string is greater than the second. So the proper way to use this return value is to compare it to zero.

   if (strcmp("foo", datafld ) == 0) // equal strings
   if (strcmp("foo", datafld ) < 0) // "foo" is less than datafld
   if (strcmp("foo", datafld ) > 0) // "foo" is greater than datafld
   if (strcmp("foo", datafld ) != 0) // "foo" is different to datafld

etc ...
Using the result as if it is a boolean is a mistake.


The second point is that C is not D. When interfacing with any foreign data source, one must expect to do data conversions when the two systems implement similar paradigms differently. Thus if one is interfacing to a C function and that C function returns a boolean that is implemented as an int, the D program ought to convert the C data into the equivalent D data form. This is a good programming practice.

By the way, if strcmp() was even converted to a pure D function, it still wouldn't return a bool.

> Seems there are two options
>
>      bool a,b,c,d;
>
>      a = cast(bool) strcmp("foo", "bar");
>      b = cast(bool) strcmp("foo", "baf");
>      c = cast(bool) strcmp("foo", "bag");
>      d = cast(bool) strcmp("foo", "bad");
>
> or the newly found "cast to bool operator", brought up by BCS (in D.announce 3032)
>
>      a = !! strcmp("foo", "bar");
>      b = !! strcmp("foo", "baf");
>      c = !! strcmp("foo", "bag");
>      d = !! strcmp("foo", "bad");
>
> This is certainly less typing, and it shrouds less the original code. If it weren't for this discovery, I'd have a *hard time* living with this last change in D.

But it is wrong to treat strcmp this way, but I understand that this is not your point really. Clarity in code is to write in such a way as to make your intentions obvious to other readers of your code.

> So the "!!" might become a much used idiom in D now.

I don't think so...it is too obtuse and not very clear.

>
> ---
>
> (Aside:) In real code of course, one should never invert booleans, and one should always use variable names with semantic content for the reader. Thus, one probably would write something like
>
>
>      bool match;
>
>      match = ! strcmp("foo", "bar");
>
>      if (match)
>      {
>          /* do stuff */
>      }
>      else
>      {
>          /* call the cops! */
>      }

Actually, it probably should be more like ...

   match = (strcmp("foo", "bar") == 0);

-- 
Derek Parnell
Melbourne, Australia
March 08, 2006
Hasan Aljudy wrote:
> Lucas Goss wrote:
>> Walter Bright wrote:
>>
>>> Changed on_scope keywords per the general consensus of the n.g.
>>
>> nooooooooooooooooooooooooo... I guess I was the only one that didn't like the proposed change of scope(...). Inconsistencies in d drive me mad (crazy). I love the language and hate it at the same time.
> 
> What's the inconsistency here?

The inconsistency is in the style of the language. Where else in the language is there a keyword inside another keyword? Yes I know exit, success, and failure aren't necessarily keywords, but they are within the context of scope() (or scope of scope, :) ). The only other instance I can think of is switch(), but "case" is in the block of the switch statement (not inside the parenthesis). All other keywords with ()'s have expressions/conditions inside.

It kinda reminds me of the English language (my native tongue by the way), where some things just stick out like a sore thumb...

Bologna - pronounced Bolony?

Well I guess it allows us to add stuff later, as in:
scope(creep)

hahaha... sorry I couldn't resist :)
March 08, 2006
Lucas Goss wrote:
> Hasan Aljudy wrote:
> 
>> Lucas Goss wrote:
>>
>>> Walter Bright wrote:
>>>
>>>> Changed on_scope keywords per the general consensus of the n.g.
>>>
>>>
>>> nooooooooooooooooooooooooo... I guess I was the only one that didn't like the proposed change of scope(...). Inconsistencies in d drive me mad (crazy). I love the language and hate it at the same time.
>>
>>
>> What's the inconsistency here?
> 
> 
> The inconsistency is in the style of the language. Where else in the language is there a keyword inside another keyword?

while(true) :)

> Yes I know exit, success, and failure aren't necessarily keywords, but they are within the context of scope() (or scope of scope, :) ). The only other instance I can think of is switch(), but "case" is in the block of the switch statement (not inside the parenthesis). All other keywords with ()'s have expressions/conditions inside.
> 

D inherits alot of inconsistencies from C ..

for loops vs while loops.. horrible inconsistency!! You actually but semi-colon seperated statements inside the for( .. )

switch/case/break construct doesn't really resemble anything!!

key_words_with_under_scores_are_worse
March 08, 2006
"Lucas Goss" <lgoss007@gmail.com> wrote in message news:dun5ej$2vej$1@digitaldaemon.com...
> The inconsistency is in the style of the language. Where else in the language is there a keyword inside another keyword? Yes I know exit, success, and failure aren't necessarily keywords, but they are within the context of scope() (or scope of scope, :) ).

extern(C)

pragma(msg, "hi")


March 08, 2006
Hasan Aljudy wrote:
> Lucas Goss wrote:
>> The inconsistency is in the style of the language. Where else in the language is there a keyword inside another keyword?
> 
> while(true) :)

Hmm, true. But while accepts a condition. So I can do:
while(myTimer < 1000), while(!done)
but I can't do:
scope(isFinished), scope(timerAbort)

> D inherits alot of inconsistencies from C ..

Yeah that's what kills me. I can use a nice consistent language like C# or Java, or a nice performing language like C/C++ or D. Why can't I have both... sigh.

> for loops vs while loops.. horrible inconsistency!! You actually but semi-colon seperated statements inside the for( .. )

I don't like those either.

> switch/case/break construct doesn't really resemble anything!!

Yeah, basically a bunch of if/else if/else statements in disguise.

> key_words_with_under_scores_are_worse

Yeah I don't like the key_words_with_underscores either, that's why I wanted a change, just not the kind with ()'s.
March 08, 2006
Jarrett Billingsley wrote:
> "Lucas Goss" <lgoss007@gmail.com> wrote in message news:dun5ej$2vej$1@digitaldaemon.com...
>> The inconsistency is in the style of the language. Where else in the language is there a keyword inside another keyword? Yes I know exit, success, and failure aren't necessarily keywords, but they are within the context of scope() (or scope of scope, :) ).
> 
> extern(C)
> 
> pragma(msg, "hi") 

I knew there was some I wasn't thinking of. And version(name) too.

Thinking about it, does that mean this can be done?:
scope(exit) {
   class1.cleanup();
   class2.cleanup();
}

I think of it more like an event accumulator stack, not really a statement, so this just seems strange:
scope(exit) class1.cleanup();
scope(exit) class2.cleanup();

Maybe because I don't do anything like:
if(thisIsTrue) okToExecute();
March 08, 2006
On Thu, 09 Mar 2006 07:53:20 +1100, Lucas Goss <lgoss007@gmail.com> wrote:


> Thinking about it, does that mean this can be done?:
> scope(exit) {
>     class1.cleanup();
>     class2.cleanup();
> }

Yes.

> I think of it more like an event accumulator stack, not really a statement, so this just seems strange:
> scope(exit) class1.cleanup();
> scope(exit) class2.cleanup();

However, the two are different in that the first example above the order of execution is class1.cleanup then class2.cleanup, but it is reversed in example #2 as they get run in reverse lexical order.


-- 
Derek Parnell
Melbourne, Australia