[net.unix] typedefs, etc.

jreuter@cincy.UUCP (Jim Reuter) (12/28/83)

I agree with almost everything Steve Summit (azure!stevesu) has to
say about typedefs, readability, and other things, but I strongly
disagree with the following statement:

	...
	I once had points taken off on a programming assignment for
	writing something like

		if(a == b) return(TRUE);
		else return(FALSE);

	The grader said I should have "more succinctly" said

		return(a == b);

	I realize now that he was wrong, and I wish I'd realized it then,
	and called him on it.  He was obviously a fully indoctrinated
	member of the "hacks are beautiful" school.  Those two fragments
	do do the same thing, and this is a case where the second one
	might even generate slightly more efficient code.  But I have to
	look at something like "return(a == b)" twice or even three times
	to convince myself that it's identical to what I conceptualize as
	"if a equals b it's true, otherwise it's not."  Why make things
	difficult?  I know the idiom, and it still gets in my way. 
	...

I think his confusion may arise from the fact that in C, boolean values
are integers.  In some programming languages, booleans are completely
separate from integer types, and one can declare a function of boolean
type that will return TRUE or FALSE as the result of a boolean
(comparison) operation.  In fact, this is just what boolean operators
are.

Perhaps if he used the much discussed typedef, and wrote

	typedef int BOOL;

	BOOL
	somefunc( a, b )
	int a,b;
	{
		return( a == B );
	}

things would seem clearer.  I disagree with his statement that his
first example is clearer, and I can show several examples of
similar constructs which are definitely NOT clearer:

	c = a > b ? a : b;

	is worse than

	#define	max(a,b) (a > b ? a : b)

	c = max( a, b );

or perhaps

	if (i == 5)
		i = 6;
	if (i == 4)
		i = 5;
	if (i == 3)
		i = 4;
	if (i == 2)
		i = 3;
	if (i == 1)
		i = 2;

	is far worse than

	i = i + 1;

	or even

	i++;

This last example I saw three years ago in an article about some
programming atrocities that real, practicing, "professional programmers"
were commiting.  It was written by a manager of a programming staff.
I realize it is a bit extreme, but it is of the same style.

ucbesvax.turner@ucbcad.UUCP (12/30/83)

#R:cincy:-116500:ucbesvax:23100004:000:646
ucbesvax!turner    Dec 30 03:26:00 1983

Re: returning crafty boolean expressions

    typedef int BOOL;	/* ?! */

That's not what I do!  I have (in ~turner/include/macros.h):

    typedef enum { FALSE, TRUE } bool;

With this bool-type, the following causes a type-clash on return value warning:

    bool yes( )
    {
	    return getchar( ) == 'y';
    }

I would have to (and am willing to) say, instead:

    bool yes( )
    {
	    if (getchar( ) == 'y')
		return TRUE;
	    else
		return FALSE;
    }

If this grosses you out, you probably wouldn't want to look at any of the
rest of my code.  I like weak languages to be strongly typed.
---
Michael Turner (ucbvax!ucbesvax.turner)

tim@unc.UUCP (12/31/83)

Indeed, you could make a case that the conditional form

	if ( a == b ) return( TRUE );
	else return( FALSE );

is the hacky one, and not

	return( a == b );

The idea of a Boolean expression is a part of all procedural languages I'm
familiar with, including C, Pascal, and so on.  If the programmer can't
understand the idea of a Boolean expression yielding a Boolean value, that's
his blind spot, and it will lead to inferior code.
--
Tim Maroney, University of North Carolina at Chapel Hill
duke!unc!tim (USENET), tim.unc@csnet-relay (ARPA)

keesan@bbncca.ARPA (Morris Keesan) (01/03/84)

-----------------------------------

>ucbesvax!turner    Dec 30 03:26:00 1983
>Re: returning crafty boolean expressions
>    typedef int BOOL;	 /* ?! */
>That's not what I do!  I have (in ~turner/include/macros.h):
>    typedef enum { FALSE, TRUE } bool;
>With this bool-type, the following causes a type-clash on return value warning:
>    bool yes( )
>    {
>	     return getchar( ) == 'y';
>    }
>I would have to (and am willing to) say, instead:
>    bool yes( )
>    {
>	     if (getchar( ) == 'y')
>		 return TRUE;
>	     else
>		 return FALSE;
>    }
>>>>>>>>>

    I question the utility of a 'bool' type which generates type-clashes
with boolean expressions.  However, if you insist on using it, do you object
to 
	    return( (bool)(getchar() == 'y') );
?  This avoids the type-clash warning, and is guaranteed to work.
Saying
	    if( getchar() == 'y' ) return TRUE; else return FALSE;
is only one step away from
	    if( (getchar() == 'y') == TRUE ) return TRUE; else return FALSE;
and equally silly.  The whole point of boolean types/values is that they reflect
the values which can be held by boolean expressions.
-- 
					Morris M. Keesan
					{decvax,linus,wjh12}!bbncca!keesan
					keesan @ BBN-UNIX.ARPA

gwyn%brl-vld@sri-unix.UUCP (01/03/84)

From:      Doug Gwyn (VLD/VMB) <gwyn@brl-vld>

I think one's programming style is improved if he carefully maintains
the distinction between boolean data and integer data, even though the
C language does not.  Examples:

	if ( p != NULL )
		fputs( p, stdout );
rather than
	if ( p )
		fputs( p, stdout );

	while ( *p != '\0' )
		putchar( *p++ );
rather than
	while ( *p )
		putchar( *p++ );

Although the above alternatives lead to identical machine code and are
not obviously superior taken out of context, they say precisely what is
intended without requiring the reader to remember C-specific language
peculiarities.  I find that careful attention to data typing, of which
boolean-vs-integer is a small part, contributes to error-free coding.

gwyn%brl-vld@sri-unix.UUCP (01/04/84)

From:      Doug Gwyn (VLD/VMB) <gwyn@brl-vld>

You have discovered why one should NOT typedef "boolean" as an enum.

ajs@hpfcla.UUCP (01/04/84)

#R:cincy:-116500:hpfcla:43800001:000:715
hpfcla!ajs    Jan  2 17:50:00 1984

I also prefer "return (a == b);" to a less-concise form.  But that's not
what  bugs me.  What I'd  like to know  is, why did the  authors  of the
articles  on the  subject  write  "return(  a == b );" as they  did?  In
English we don't( usually )use parentheses that way, and English is what
most of us are used to reading.

It seems commonsensical to me to use lexical forms when programming that
most approximate our natural  language.  Why do most programmers seem to
behave as if they  disagreed?  (See my recent  flames about  quoting and
commenting styles...)

Alan Silverstein, Hewlett-Packard Fort Collins Systems Division, Colorado
{ihnp4 | hplabs}!hpfcla!ajs, 303-226-3800 x3053, N 40 31'31" W 105 00'43"

chris@umcp-cs.UUCP (01/05/84)

Re:
	From: keesan@bbncca.UUCP

	[ Re: ...  typedef enum { FALSE, TRUE } bool; ... ]

	I question the utility of a 'bool' type which generates
	type-clashes with boolean expressions.  However, if you
	insist on using it, do you object to 

		return( (bool)(getchar() == 'y') );

	?  This avoids the type-clash warning, and is guaranteed
	to work.

Unfortunately it's not *guaranteed* to work, unless you use

	typedef enum { FALSE = 0, TRUE = 1 } bool;

to ensure that (bool) 0 == FALSE and (bool) 1 == TRUE.  Otherwise
the result of a boolean expression may be neither FALSE nor TRUE!

Personally I just use integers as boolean-variables.  (As if anyone
cares.)
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci
UUCP:	{seismo,allegra,brl-bmd}!umcp-cs!chris
CSNet:	chris@umcp-cs		ARPA:	chris.umcp-cs@CSNet-Relay

ucbesvax.turner@ucbcad.UUCP (01/05/84)

#R:cincy:-116500:ucbesvax:23100006:000:401
ucbesvax!turner    Jan  4 03:50:00 1984

Could we move this to net.lang?  It's certainly no sillier than what's
going on there now--it even relates, tangentially.  The example could
serve as flame-thrower fuel for both sides, if the discussion so far is
any indication.  net.unix is supposed to be unix-consultant of last resort,
not a net.towering.inferno.  Sorry to be flaming (and metaflaming).
---
Michael Turner (ucbvax!ucbesvax.turner)

ron%brl-vgr@sri-unix.UUCP (01/05/84)

From:      Ron Natalie <ron@brl-vgr>

@"#@%`*@ pinko computer science freaks...
Every hacker knows there is really only one data type--integer (in C "int").
Booleans are just wedged in there.  Real Fortran programmers have been
rounding integers by adding results of ".AND." to their INTEGER variables.
C just legitimizes this.  No real programmer uses floating point, too
ineffecient (he does this even on machines like HEP which compute
floating point faster than they do integers).  He just approximates by
using fixed integers again.  Characters are just integers made smaller.
Again, the real programmer null-terminates his strings with a "0" not a
"'\0'" or "NULL".  Everyone knows that space is 40(base 8) in ASCII and
40(base 16) in EBCDIC and ASCII characters less than 32 are no printing.
Don't forget that character constants in C are integers!

:->

thomas@utah-gr.UUCP (Spencer W. Thomas) (01/05/84)

Not to beat on an old subject too much (and, please, let's not start yet
another discussion on this matter), but the parentheses on the return
statement have not been required since Unix V6.  So, howcome everybody
keeps using them?  Is this just another example of "programmer
superstition?".  What gives?

The question "why use the style `return( a == b );'?" was raised.  Well,
I think that this is in analogy to a function call, where the
parentheses are part of the function call syntax, not the arguments.  E.g.,
I would write `f( a )' in preference to `f (a)'.  Now, in the return
statement, the parentheses are NOT a part of the syntax, so if you are
going to use them, you should probably write `return (a == b);' to remain
consistent.  But, `return a == b;' will do just as well.

=Spencer "I always remove parens from returns"

gwyn%brl-vld@sri-unix.UUCP (01/06/84)

From:      Doug Gwyn (VLD/VMB) <gwyn@brl-vld>

Not everyone on the Info-UNIX mailing list has access to net.lang.
Unless you want to volunteer to gateway it to the ARPAnet?

tim@unc.UUCP (01/09/84)

Note for Michael Turner:

"Boolean" in C happens to be represented by the same type as integers.  This
does not mean that there is no explicit concept of a Boolean data type or
expression.  There is a large set of operators which manipulate Boolean
data; there are concepts in which only Boolean data is permissible as the
value of an expression.  The idea is there; it is simply not made into a
data type with its own declaration syntax.
--
Tim Maroney, University of North Carolina at Chapel Hill
duke!unc!tim (USENET), tim.unc@csnet-relay (ARPA)

ucbesvax.turner@ucbcad.UUCP (01/09/84)

#R:cincy:-116500:ucbesvax:23100005:000:853
ucbesvax!turner    Jan  2 19:20:00 1984

>   /***** ucbesvax:net.unix / unc!UUCP /  8:30 am  Dec 31, 1983*/
>   The idea of a Boolean expression is a part of all procedural languages
>   I'm familiar with, including C, Pascal, and so on.  If the programmer
>   can't understand the idea of a Boolean expression yielding a Boolean
>   value, that's his blind spot, and it will lead to inferior code.
>   --
>   Tim Maroney, University of North Carolina at Chapel Hill

I wouldn't mind if "a==b" was a Boolean expression--I would be quite happy
with "return (a==b)" if it was really Boolean.  But in C, it's not.  It's
an integer-valued expression.  See K&R, if you don't believe me--there is
no intrinsic Boolean type.

If the compiler can't understand the idea of a Boolean expression, that's
its blind spot.  It does lead to inferior code, at that.
---
Michael Turner (ucbvax!ucbesvax.turner)

ajs@hpfcla.UUCP (01/09/84)

#R:cincy:-116500:hpfcla:43800003:000:1514
hpfcla!ajs    Jan  7 16:34:00 1984

Sigh...  I'm all for logical  arguments,  when they apply.  (I'm all for
posting to the right  group, too, but you have to wade into battle where
the action is.)  Anyway,  I'm  convinced  that there are few cases where
purely logical  arguments,  without reference to human nature, result in
software that IN PRACTICE is easier to maintain than otherwise.

For example, someone stated that function  parentheses are syntactically
part of the function call, not the  arguments, so you shouldn't  leave a
blank  between  the name and the left paren.  Sounds good in  principle,
but which of these is easier to read?

	myfunc(arg1, arg2, arg3);	/* barble one widget */

	myfunc (arg1, arg2, arg3);	/* barble one widget */

Like many people, I find that the left paren gets lost in the first case
(everything up to the comma looks like one token).  I suppose that:

	myfunc( arg1, arg2, arg3 );	/* barble it again */

might solve that  problem if it weren't so opposite of English (it hides
the function call and highlights the arguments).

For  similar  reasons I like  parens  in  returns,  even if they are not
required.  They emphasize the "return" and enclose the value.

Nevermind,   it's  hopeless,   this  is  a  religious   issue!  Just  be
consistent,  whatever  you do, and take  pity on those who will  support
your code after you ascend to greater things.

Alan Silverstein, Hewlett-Packard Fort Collins Systems Division, Colorado
{ihnp4 | hplabs}!hpfcla!ajs, 303-226-3800 x3053, N 40 31'31" W 105 00'43"

tim@unc.UUCP (01/09/84)

Alan Silverstein is correct in criticizing the use of white space in my
"return( a == b );".  I should have said "return a == b;", which is the
clearest way to do it in C.
--
Tim Maroney, University of North Carolina at Chapel Hill
duke!unc!tim (USENET), tim.unc@csnet-relay (ARPA)

turner%ucbesvax%berkeley@sri-unix.UUCP (01/10/84)

From:  Michael Turner <turner%ucbesvax@berkeley>

Thank you for your opinion.  Offhand, I would compute its value as

	(0 ? 0 : 0) != (0 <= 0 ? (0 >= 0) : 1)

-mike

alan@allegra.UUCP (Alan S. Driscoll) (01/14/84)

	From: chris@umcp-cs.UUCP
	Newsgroups: net.unix
	Subject: Re: typedefs, etc. - (nf)

	Re:
		From: keesan@bbncca.UUCP

		[ Re: ...  typedef enum { FALSE, TRUE } bool; ... ]

		I question the utility of a 'bool' type which generates
		type-clashes with boolean expressions.  However, if you
		insist on using it, do you object to 

			return( (bool)(getchar() == 'y') );

		?  This avoids the type-clash warning, and is guaranteed
		to work.

	Unfortunately it's not *guaranteed* to work, unless you use

		typedef enum { FALSE = 0, TRUE = 1 } bool;

	to ensure that (bool) 0 == FALSE and (bool) 1 == TRUE.  Otherwise
	the result of a boolean expression may be neither FALSE nor TRUE!


You're wrong.  In fact,

	typedef enum { FALSE, TRUE } bool;

is guaranteed to do the right thing.  The C Reference Manual (September,
1980) states

	The identifiers in an enum-list are declared as constants, and
	may appear wherever constants are required.  If no enumerators
	with = appear, then the values of the corresponding constants
	begin at 0 and increase by 1 as the declaration is read from left
	to right.  An enumerator with = gives the associated indentifier
	the value indicated; subsequent identifiers continue the progression
	from the assigned value.

So, FALSE will be given the value 0 and TRUE the value 1 because of their
*positions* in the declaration.

It amazes me how much misinformation appears on the net.


	Alan S. Driscoll
	AT&T Bell Laboratories

obrien%rand-unix@sri-unix.UUCP (01/15/84)

	Unfortunately there's a problem with the 4.1BSD VAX compiler in that
"enum"s don't do the right thing.  They're really treated as a separate
data type and give type clashes.  This may have been fixed in other
compilers.  In fact in our compiler they can't even be ordinally compared;
you can only test for equality.  We're thinking of fixing this.

ajs@hpfcla.UUCP (01/22/84)

#R:cincy:-116500:hpfcla:43800004:000:1090
hpfcla!ajs    Jan 14 18:24:00 1984

Tim Maroney's statement that "<whatever> is the clearest way to do it in
C" cannot go unchallenged.  If there is one thing I have learned by now,
it is that  there  are no  absolutes,  at  least  not in this  business.
Things  only  seem  absolute  to  people   because  of  their   personal
perspectives.  "Absolutes" are just things almost everyone agrees on.

So, you do it your way,  I'll do it my way, and if we happen  to work on
each  other's  code and  don't  like it, we can  curse  each  other  out
publicly,  privately,  or under  our  breaths,  and  maybe  that  social
interaction  will  influence  us in ways that  bring us more  toward the
"accepted  standard",  and maybe not,  because  that's how it has always
really worked anyway; <flame off>.

Alan "I finally got to flame at Tim" Silverstein

PS:  I  reserve  to  right  to make  seemingly  inconsistent  absolutist
arguments in the future, because assertiveness is part of the game.

PPS:  Any cretin (and most other people) can see that "return (a == b);"
is clearer than "return a == b;", so there, nyaa, nyaa.  :-)