Article View: comp.std.c
Article #3661Re: Incrementing a bool
From: Peter Seebach
Date: Sun, 06 Aug 1995 13:29
Date: Sun, 06 Aug 1995 13:29
156 lines
7382 bytes
7382 bytes
In article <3vq4uf$2lh@gabi.gabi-soft.fr>, J. Kanze <kanze@gabi-soft.fr> wrote:
>Peter Seebach (seebs@solutions.solon.com) wrote:
>|> In C, I don't say "if this pointer is not null". I say "if this pointer".
>|> I don't say "if this expression is non zero", I say "If this expression".
>This is a false analogy. `I am going to the store' is a statement that
>can be true or false. `This pointer' or `this expression' is not a
>complete statement.
No, but it's a complete *thing*. In C, 'expr;' is a statement; I consider
an expression a complete statement in C. When I'm thinking in C, I consider
pointers and other expressions (all ptrs are expressions) to be things
which make sense as the predicate of an if, while, or for.
>|> The comparison with falsehood is the basis of logical if in natural
>|> language, and is how it is done in the programming languages I know.
>|> The comparison with an appropriate false value is implicit.
>There is a misunderstanding here. I don't believe that you should ever
>compare anything with a logically false value.
This is actually one of the big style arguments; is it more sane to say
if (blah != FALSE)
or
if (blah)
>My argument centers on types. Something with a logically false value
>also has a logically true value, and no other values. True and false
>are not numeric values, nor are they pointers, and it makes no sense to
>declare them as such.
This is sort of true, but to me, after 10+ years of exposure, it's natural
to see non-zero as true. Are there apples? There are if there are more
than one; in otherwords, after
for (fruit = basket; fruit; fruit = fruit->next)
if (fruit->type == FTYPE_APPLE)
++apple;
if (apple)
makes perfectly good sense. "There are" or "There is" is a perfectly
workable implicit fragment.
>|> Similarly, for flags, I just use if(flag), not if(flag != 0). I consider
>|> the former clearer; it says exactly what I mean, without adding garbage
>|> that a good compiler will ignore.
>With flags, I agree. But then, my flags always have names like
>`isSomethingOrOther', with immediatly identify them as logical
>predicates.
Mine frequently don't; I try to favor 'fooflag' where 'foo' is sufficient
to identify intuitively which flag I mean.
>Again, a flag has two possible values: true and false. The number of
>operations on a flag is limited. A flag is a logical predicate, and I
>want the compiler to scream if I accidentally write `flag + 6'.
I don't, because I feel it makes sense for a flag to have many true values.
Do I have apples? Yes. How many apples? Two and four are different answers,
at this point - but they're both "at least one apple".
>|> Yes, but it's a reality that consists of an understanding of when something
>|> is true, not of a separate type to which everything else is converted.
>Correct. But only logic predicates are true or false (by definition).
>And I don't want everything else converted to bool (which is actually
>the status quo).
I do. Actually, what I really want, is I want the bool type to remain
implicit. I recognize there are problems here, if one overloads - but
then I want the conversion to always, *always* be implicitly there, so
I don't have to repeat the obvious for the compiler. I also don't want
it to take cycles when it doesn't have to; I have yet to see a processor
that doesn't have branch-on-zero or branch-on-nonzero instructions;
that is, for me, a compelling reason to keep the status quo. This is
assembly, after all, portable though it may be.
>Stated differently, since int's are numeric values, why should one
>numeric value (0) be priviledged? Why should I have a short form for:
> if ( i != 0 )
>and not for:
> if ( i != 3 )
>, for example?
Because 0 is a special case, both in hardware, and in real life. Why should
you have a special case for (i / 0) but not for (i / 3)? Because zero
is *different*. Any number you can survive without for >200 years is a
special case. ;-)
The key is, "None" and "At least one" are opposites (for positive-valued
things). Those are the two states, and naming them "false" and "true"
doesn't really matter.
>|> I don't want "if a is greater than b is true", I want "is a is greater than
>|> b."
>Agreed. So a > b should return a bool.
Or an int. Or a pointer to (int (*)(int, char **)) which is either main
or NULL. I don't care; it should Do The Right Thing. I also want it to
have a numeric value, ideally the currently enforced 0 or 1, so I can
add it to counters.
>|> Me too. But, long experience has taught me that a pointer *is* when it's
>|> non-null, and *isn't* when it's null. So, if (fp) is perfectly natural
>|> for me; it means "if my file pointer", and that's what I mean.
>Logically, however, saying just "if my file pointer" implies that `my
>file pointer' is a logical predicate, i.e.: a two valued type on which,
>e.g., addition is not defined.
Not really. "If my apples" doesn't mean I can't get more apples. It may
not be grammatical in English, but it currently is in C, and it's a good
thing it is.
>I have nothing wrong with the idea of wanting to have a short way of
>saying `isValid( ptr )', or whatever. Although as far as I'm concerned,
>`isValid( ptr )' already seems pretty concise to me.
But it's a hell of a lot longer than 'ptr'.
>That in some contexts, `ptr' really means `isValid( ptr )', and in other
>contexts, `ptr' means pointer.
It always means 'pointer'. The question is, what am I doing with it? If
I test a pointer, I want to know whether it points or not. If I dereference
it, I want to know where it points. If I compare it, I want to know whether
it is the same as another pointer within the same object.
>For me, at least, `ptr' is an object (with a set of values and a set of
>legal operations, thus with a specific type). An object is, in fact, a
>noun. Grammatically, a noun can only be used with a verb, thus:
> *ptr `*' == dereference, so dereference ptr
> ptr != NULL ptr is not equal to NULL
>and so on.
I believe in implicit verbs when they're obvious. Part of the elegance of
C has always been that it doesn't require you to type things that are
already obvious. I don't want to have to "produce" booleans any more than
I want to be forced to type
printf("hello, world!\n\0");
... Sure, the quoted string doesn't specify the \0, but that doesn't mean
it shouldn't provide one where appropriate.
-s
--
Peter Seebach - seebs@solon.com || seebs@intran.xerox.com --- C/Unix
proto-wizard -- C/Unix questions? Send mail for help. No, really!
Copyright 1995 Peter Seebach. Not for distribution through Microsoft Network.
a^n+b^n=c^n has integer solutions {a, b, c, n} only for n<=2. To prove, assume
Technical Details
Message-ID:
<402g4e$bgs@solutions.solon.com>Path:
arc1-ca.pugleaf.net!solon.com!not-for-mailReferences:
<KANZE.95Jul19114530@slsvhdt.lts.sel.alcatel.de> <3va943$im@gabi.gabi-soft.fr> <3vl72l$dp9@solutions.solon.com> <3vq4uf$2lh@gabi.gabi-soft.fr>Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!solon.com!not-for-mail From: seebs@solutions.solon.com (Peter Seebach) Newsgroups: comp.std.c Subject: Re: Incrementing a bool Date: 6 Aug 1995 08:29:50 -0500 Organization: Usenet Fact Police (Undercover) Message-ID: <402g4e$bgs@solutions.solon.com> References: <KANZE.95Jul19114530@slsvhdt.lts.sel.alcatel.de> <3va943$im@gabi.gabi-soft.fr> <3vl72l$dp9@solutions.solon.com> <3vq4uf$2lh@gabi.gabi-soft.fr> NNTP-Posting-Host: solutions.solon.com