August 28, 2001
"Dan Hursh" <hursh@infonet.isl.net> wrote in message news:3B8730FA.2A998BC0@infonet.isl.net...
> Well, I can't offer any technical reasons but I agree with your feeling here.  I find the C style logical operator very powerful.  Frankly I wish you would add perl style 'until' and 'unless' structures as well as the ability to have a statement followed by a loop or conditional statement since I find it to be very expressive.  I find these help make intentions clearer in certain cases.  I had no good technical reason for that either so I head off asking.

I'm a big fan of 'unless' & 'until' myself. From a compiler implementation point of view, it's very cheap syntactical sugar but, as you suggest, 'unless (...)' can frequently express intent much more clearly than 'if (!...)'

> In any case, I'm glad to see labeled breaks and continues, a redo might be nice to avoid a goto, and I hope you keep the logical ops I know and love.  They allow me to say more meaningful things with less verbage.



September 05, 2001
Time to argue with myself (a bit).

I just was at a code review and saw people testing bit flags against a state variable:

if(foo | INTERESTING_FLAG)
   ....
else if(bar | BORING_FLAG)
   ....

If we take my advice, this code becomes:

if(foo | INTERESTING_FLAG == INTERESTING_FLAG)
  ....

I *really* don't like the extra typing.  Plus, it's much harder to read. So, I pondered a bit, and I'm thinking that maybe we could use the 'in' keyword.  It would be as readable (or more) than the C version:

if(INTERESTING_FLAG in foo)
    ....

In the integer/integer context, in is just syntax sugar:
     intA in intB
is expanded by the compiler to
     ((intA | intB) == intA)
which obviously returns bool.

September 05, 2001
> if(foo | INTERESTING_FLAG == INTERESTING_FLAG)

That one will be -always- true :/

I guess you mean:

> if(foo & INTERESTING_FLAG == INTERESTING_FLAG)

But you can also write it this way:

> if(foo & INTERESTING_FLAG != 0)

resulting in the same, and is the same logic as the implizid C statement: everything but zero is true, zero is false.

- Axel
September 05, 2001
Axel Kittenberger wrote:

> > if(foo | INTERESTING_FLAG == INTERESTING_FLAG)
>
> That one will be -always- true :/

Grimace...you're right, the code is wrong (needs to be an AND)...but no, it won't always be true...if foo has bits set that are not part of INTERESTING_FLAG, then it would be false...

> I guess you mean:
>
> > if(foo & INTERESTING_FLAG == INTERESTING_FLAG)

Righto.

> But you can also write it this way:
>
> > if(foo & INTERESTING_FLAG != 0)
>
> resulting in the same, and is the same logic as the implizid C statement: everything but zero is true, zero is false.

Double grimace...don't know why I didn't think of that.  Wish I could say that it was late at night when I posted, but it wasn't :(

Ok, so there is a faster way to do this than I said.  Yours *is* much cleaner.

September 05, 2001
Russ Lewis wrote:

> Axel Kittenberger wrote:
>
> > > if(foo | INTERESTING_FLAG == INTERESTING_FLAG)
> >
> > That one will be -always- true :/
>
> Grimace...you're right, the code is wrong (needs to be an AND)...but no, it won't always be true...if foo has bits set that are not part of INTERESTING_FLAG, then it would be false...
>
> > I guess you mean:
> >
> > > if(foo & INTERESTING_FLAG == INTERESTING_FLAG)
>
> Righto.
>
> > But you can also write it this way:
> >
> > > if(foo & INTERESTING_FLAG != 0)
> >
> > resulting in the same, and is the same logic as the implizid C statement: everything but zero is true, zero is false.
>
> Double grimace...don't know why I didn't think of that.  Wish I could say that it was late at night when I posted, but it wasn't :(
>
> Ok, so there is a faster way to do this than I said.  Yours *is* much cleaner.

Ack, got a problem here.  I just realized that unless we use some funky (perhaps confusing) rules, unifying && and & breaks some precedence rules. Look at this code:

if(foo & INTERESTING_FLAG != 0 &
   bar & BORING_FLAG != 0)
   ....

In old C syntax, & had high precedence, != had middle, and && had low.  Thus, the C test worked

if(foo & INTERESTING_FLAG != 0 &&
   bar & BORING_FLAG != 0)

Theorhetically, it's not hard to tell the difference between the bool context and the int context.  But if you use bison to parse it, you have a problem.

How onerous is it, do you think, to require the syntax to be:

if( (foo & INTERESTING_FLAG) &
    (bar & BORING_FLAG))

I think that that would be bug-prone, unfortunately.  I still like the theory of unifying the operators...anybody have a good syntax for it?

September 05, 2001
> Ack, got a problem here.  I just realized that unless we use some funky (perhaps confusing) rules, unifying && and & breaks some precedence rules. Look at this code:
> 
> if(foo & INTERESTING_FLAG != 0 &
>    bar & BORING_FLAG != 0)
>    ....
> 
> In old C syntax, & had high precedence, != had middle, and && had low. Thus, the C test worked
> 
> if(foo & INTERESTING_FLAG != 0 &&
>    bar & BORING_FLAG != 0)
> 
> Theorhetically, it's not hard to tell the difference between the bool
> context
> and the int context.  But if you use bison to parse it, you have a
> problem.
> 
> How onerous is it, do you think, to require the syntax to be:
> 
> if( (foo & INTERESTING_FLAG) &
>     (bar & BORING_FLAG))
> 
> I think that that would be bug-prone, unfortunately.  I still like the theory of unifying the operators...anybody have a good syntax for it?

Pascal had exactly this problem, AND and OR where both binary and boolean operators, and additionally to their sense of being binary they had higher binding than the equal operators. (remember then single = means equals in pascal)

IF a = 1 AND b = 2 THEN
BEGIN
        foo;
END


Any pascal user will scream and say it has to be written as:
IF (a = 1) AND (b = 2) THEN

Or the compiler will implicitly see following:
IF (a = (1 AND b)) = 2 THEN

something very different :o)

I started learing programming with pascal, and later switched to C. And hence after all these years I'm still most times using these brackets even in C, altough it wouldn't need them, it's beeing a burned child. Just the same thing goes the other side, everytime i've now written a single equal sign meaning a compare my whole body cramps :o)

After actually trying the alternatives in practice one has to admit that a few C ideas weren't so bad after all :o) Okay c has still a lot of braindead quircks, but it's the only one that seems to satisfy industry :/

I for me have keeped the && and || parameters, in the sense of leaving the predecnce of all operator exactly as C. After having programmed both Pascal and C, having different precedence rules, I'm even after years not even having looked at pascal still unsure about their precedence, I don't want also to 'hurt' others like this :o)

Okay once you've coded a parser, you know them better :o) For C once you've looked at a parser for it, you realize what for braindead constructs the C grammar actually allows, no sane person could ever think of :o) Like anonymous structs in functions or

        void hallo (struct a {int i} b);

Okay but don't nail me if it's really correct C, just guessed it.

Hmm how about:
        void (*)(void) (* a)(int);
Should be a function pointer to a function returning a function pointer.

I don't know about C++, but the gcc guys moan constantly about it, but I guess Walter could tell you more about C++ parsing :o)

- Axel
September 28, 2001
Axel Kittenberger wrote in message <9n5vfr$2067$1@digitaldaemon.com>...
>I for me have keeped the && and || parameters, in the sense of leaving the predecnce of all operator exactly as C. After having programmed both Pascal and C, having different precedence rules, I'm even after years not even having looked at pascal still unsure about their precedence, I don't want also to 'hurt' others like this :o)

It's important to keep the same precedence rules as C. Nothing will screw programmers up more than to subtly shift them.



October 02, 2001
In article <9p29du$233h$1@digitaldaemon.com>,
 "Walter" <walter@digitalmars.com> writes:
|>
|> Axel Kittenberger wrote in message <9n5vfr$2067$1@digitaldaemon.com>...
|> >I for me have keeped the && and || parameters, in the sense of leaving the
|> >predecnce of all operator exactly as C. After having programmed both Pascal
|> >and C, having different precedence rules, I'm even after years not even
|> >having looked at pascal still unsure about their precedence, I don't want
|> >also to 'hurt' others like this :o)
|>
|> It's important to keep the same precedence rules as C. Nothing will screw
|> programmers up more than to subtly shift them.

I agree, but what about not permitting this:

 if ( a < b && c < d || b < e && istrue(f) || isfalse(g)) {
     // guess you don't know when you go by here
     exit(2);
 }

Precedence and associativity say it is the same as:

 if ( (a < b && c < d) || (b < e && istrue(f)) || isfalse(g)) {
     exit(2);
 }

gcc suggests to use explicit parenthesis aound && within ||, and I think this should be mandatory for D.

Ciao
October 02, 2001
In article <9pbvn5$1bes$1@digitaldaemon.com>, "Roberto Mariottini" <mario@jonathan.torino.artis.it> wrote:

> In article <9p29du$233h$1@digitaldaemon.com>,
>  "Walter" <walter@digitalmars.com> writes:
>
>
> gcc suggests to use explicit parenthesis aound && within ||, and I think this should be mandatory for D.

I agree.  Some C style guides recommend doing this sort of thing.   Rather than changing the precedence, we can just remove it.
October 03, 2001
Ben Cohen wrote:
> 
> In article <9pbvn5$1bes$1@digitaldaemon.com>, "Roberto Mariottini" <mario@jonathan.torino.artis.it> wrote:
> 
> > In article <9p29du$233h$1@digitaldaemon.com>,
> >  "Walter" <walter@digitalmars.com> writes:
> >
> >
> > gcc suggests to use explicit parenthesis aound && within ||, and I think this should be mandatory for D.
> 
> I agree.  Some C style guides recommend doing this sort of thing.   Rather than changing the precedence, we can just remove it.

	Funny, I always thought that the precedence of boolean operators were
as well understood and standard as those of addition and
multiplication.  Should we require explicit parens around all infix and
unary operations?
	I had AND taught to me as boolean multiplication and OR taught as
boolean addition.  XOR and implication was always a bit of gray area,
but AND and OR were well defined.  I'd hate to clutter the expressions
in the cases were it isn't really needed.

Dan