[net.lang] 'lint' and strong typing

apratt@iuvax.UUCP (01/13/84)

#N:iuvax:11800011:000:697
iuvax!apratt    Jan 12 21:06:00 1984

<:>

Into the strong-typing fray:
	Could somebody tell me why a pre-processor couldn't be used to flag
type conflicts, rather than writing them into the language?  "Lint" is the
obvious example, and, if you want to be stern, you could require that each
line of code which fails "lint" must be justified in writing, subject to
somebody's approval. If the application lends itself to type-mixing, you
should certainly be allowed to do it. An example: using (char *) in C to
point to an arbitrary object. Specifically with reference to the previous
note about the space program, frozen implementations mean never having to
say you're portable.
							-- Allan Pratt
					...ihnp4!inuxc!iuvax!apratt

tjt@kobold.UUCP (01/14/84)

Allan Pratt has suggested using "lint" (or some other pre-processor) to
implement strong type checking in C.  Unfortunately, as long the
type-checking system must be applied manually, it will require an iron
will (and an iron hand on the whip) to administer.  It's much easier to
adhere to if it *enforced* by the compiler.  How many C programmers have
continued to ignore the "warnings" already produced by the type
checking in the pre-System V compilers (I understand that these are now
*errors* in System V).
-- 
	Tom Teixeira,  Massachusetts Computer Corporation.  Westford MA
	...!{ihnp4,harpo,decvax}!masscomp!tjt   (617) 692-6200 x275

gam@proper.UUCP (Gordon Moffett) (01/15/84)

> From: tjt@kobold.UUCP, Organization: Masscomp, Westford, MA
> 
>                                   ... Unfortunately, as long the
> type-checking system must be applied manually, it will require an iron
> will (and an iron hand on the whip) to administer.  It's much easier to
> adhere to if it *enforced* by the compiler.  How many C programmers have
> continued to ignore the "warnings" already produced by the type
> checking in the pre-System V compilers
> 	Tom Teixeira,  Massachusetts Computer Corporation.  Westford MA
> 	...!{ihnp4,harpo,decvax}!masscomp!tjt   (617) 692-6200 x275

This is beginning to sound more like a problem of programmers' behavior
than of any type-checking mechanism we might come up with.  I think
we should view this sort of type-checking as part of the programmer's
job of creating `correct' code.  If a programmer is not going to use
the tools at his/her disposal to avoid such problems, I don't think
that should be accepted as a `style' but sheer laziness/incompetence.

chuqui@nsc.UUCP (Chuq Von Rospach) (01/17/84)

The strongest argument against type checking in a pre processor is simply
that in most shops, as deadlines approach reality, code quality and
maintainability approach negative infinity. Anything that isn't enforced
by the compiler won't be enforced at all.


-- 
-- Diogenes looked in and laughed--
From the house at Pooh Corner		Chuqui (a Silly Old Bear)
					{fortune,menlo70}!nsc!chuqui

~And as I lived my role I swore I'd sell my soul for one love
 who would stand by me and give me back the gift of laughter~
		- Winslow Leech

phipps@fortune.UUCP (Clay Phipps) (01/18/84)

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

In regard to the following comments:

    Could somebody tell me why a pre-processor couldn't be used 
    to flag type conflicts, rather than writing them into the language?  
    "Lint" is the obvious example, ...

For reasons that have nothing to do with human nature,
some type checking must be done by a compiler, rather than by a preprocesor,
to determine when widening or data conversions must be performed
by the emitted code, such as in the notorious case of

    int_var *= float_var

Therefore, you can't avoid them entirely.  In languages that are more-or-less
strongly typed, e.g., Pascal, the code already required by the language
definition to check type compatibility of subranges has the side effect
(or can, with a clean compiler design) of emitting the code to check 
whether array indices are within bounds (disabling this could be optional).
In my view, array bounds checking is best done by the compiler or hardware,
not by a preprocessor.

If you don't write the type-checking rules into the language definition,
you will have the problem of having source code that looks like C code
being rejected by one preprocessor but not another,
because each is checking for different things.
This will not have a positive effect on program portability.
Aren't there already enough problems with C compilers
that don't exactly conform to K&R (i.e., any of those based on the 
"Portable C Compiler"), without adding additional variation
in the selection of a preprocessor ?

And what about the poor "maintenance and enhancement" programmer,
who will have no clue from the source code about how stringently
(if at all) a C program was type-checked ?
After all, the UNIX custom seems to be for compilers not to produce
a listing that could tell a programmer what options were used 
for compilation or preprocessing, and there is no guarantee 
that such an important listing, even if produced, would be retained.

    ... if you want to be stern, 
    you could require that each line of code which fails "lint" 
    must be justified in writing, subject to somebody's approval. 

C'mon, now !  If a programmer is going to skip a simple procedure
like use of "lint" because s/he feels pressed for time,
or because some of "lint"'s messages are an annoyance,
how can you expect her/him to submit to blatant paperwork ?
It was only about a week ago that one of my colleagues (highly regarded
and working to a tight schedule) admitted something to the effect that
"I can't believe how long it took me to find that bug ...
... if I had run 'lint' on the program, it would have caught it right away".
It might be worthwhile to make a rule that code walkthroughs
would be based on "lint" output rather than raw source file listings,
on the principle that your colleagues will view with scorn
anyone who wastes their time by using them to perform "lint"-like checks
on code you didn't take the time to run through "lint" yourself.
Unfortunately, code walkthroughs are unpracticed in many organizations.

    If the application lends itself to type-mixing, 
    you should certainly be allowed to do it. 
    An example: using (char *) in C to point to an arbitrary object. 

Your example just points out the need for a programmer to be able
to specify, in source code, that an arbitrary object has no specific type,
rather than having to pretend that it is an array of characters.
The latter is reminiscent of the FORTRAN practice of hiding printable
characters in arrays declared to have the INTEGER type.
My view is that the character data type should be limited to bytes
that could be printed or displayed, and not used for arbitrary bit patterns;
this is not the way C was designed, and may be an unpopular view here.
Euclid has a "StorageUnit" type that is very close to what I have in mind,
and I think that Modula-2 does, also; C ought to.
For other kinds of mixing, aren't explicit casts sufficient ?

I must admit that I have not yet been absorbed into the C culture,
so it is possible that I missed the point of the followup I have excerpted.

-- Clay Phipps
    
-- 
   {allegra,amd70,cbosgd,dsd,floyd,harpo,hollywood,hpda,ihnp4,
    magic,megatest,nsc,oliveb,sri-unix,twg,varian,VisiA,wdl1}
   !fortune!phipps

tjt@kobold.UUCP (01/24/84)

> From: gam@proper.UUCP, Organization: Proper UNIX, San Leandro, CA

> This is beginning to sound more like a problem of programmers' behavior
> than of any type-checking mechanism we might come up with.  I think
> we should view this sort of type-checking as part of the programmer's
> job of creating `correct' code.

If you want to view type-checking as part of the programmer's job, why
not include translating the program to assembly language or machine
language as part of the job also?  Many of the early entries in
"Collected Algorithms from the ACM" use Algol 60 as a specification
language and state that the algorithm was verified by being translated
to Fortran or machine language.  I would hope you would agree that
modern computer languages are more useful as *programming* languages
than as *specification* languages.  The distinction I would use is that
in a specification language there is no machine-verified correspondence
between the program and what is executed by the computer, while there
is such a correspondence created by the compiler for a programming
language.

> If a programmer is not going to use the tools at his/her disposal to
> avoid such problems, I don't think that should be accepted as a `style'
> but sheer laziness/incompetence.

Laziness?  Definitely!  Incompetence?  Perhaps.

The basic premise of a high-level language is that a programmer is lazy
and incompetent.  Anybody capable of writing a program in a high level
language is capable of being taught how to write or translate that
program in machine language.  Most people are too lazy perform that
translation and are have great difficulty doing so without errors.

Similarly, strong type checking is nothing that cannot be done by the
programmer, by hand.  Again, most programmers are too lazy to do this
checking by hand, and will generally make errors when doing so.
Actually, in most programming environments the programmer *does* do
this type checking by hand when he writes the program, and *does* make
errors.  A system in which the programmer does *no* preliminary type
checking would be some sort of language specific editor that prompts
the programmer for arguments/operands/whatever and indicates acceptable
data types.

Anyway, if you believe that strong type-checking is a valuable tool,
you should be willing to make it a standard part of your compiler so
that a programmer will not be able to give in to his natural (and
valuable) inclination to be lazy:

If programmers weren't lazy, we'd still be writing in machine language
(or programming Turing machines).


-- 
	Tom Teixeira,  Massachusetts Computer Corporation.  Westford MA
	...!{ihnp4,harpo,decvax}!masscomp!tjt   (617) 692-6200 x275