🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: comp.std.c
Article #3661

Re: Incrementing a bool

#3661
From: Peter Seebach
Date: Sun, 06 Aug 1995 13:29
156 lines
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-mail
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>

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