From: Burton Samograd
Subject: Parameter type checking
Date: 
Message-ID: <87vfwavd0r.fsf@kruhft.vc.shawcable.net>
Hi,

After about a month of reading I've actually started getting some
actual experiece by doing some of the examples from SICP in CL.  I'm
currently doing the digital circuit simulator and I'm having some
confusion with whether I should be checking the types of the function
arguments that are coming in.  I've been programming for years and
know the difference between "textbook code" and "real world" code, so
naturally I think (coming from a C background) that the types should
be checked by the function before they are used.  For example:

(defstruct wire
        (signal 0)
        (action-procs '())

;; textbook type code
(defun get-signal (wire)
        (wire-signal-value wire)

;; real world code
(defun not-a-wire (x)
        (error "~S is not a wire" x))

(defun get-signal-rw (wire)
        (if (wire-p wire)
                (wire-signal-value wire)
        (not-a-wire wire)))

Is checking types before using them this considered good or bad Lisp
programming practice?  If it is bad, how might be this handled with
better style, or am I just worrying about nothing here?

-- 
burton samograd
······@kruhft.dyndns.org
http://kruhftwerk.dyndns.org

From: Barry Margolin
Subject: Re: Parameter type checking
Date: 
Message-ID: <xbcxa.19$Cl.1061@paloalto-snr1.gtei.net>
In article <··············@kruhft.vc.shawcable.net>,
Burton Samograd  <······@hotmail.com> wrote:
>(defstruct wire
>        (signal 0)
>        (action-procs '())
>
>;; textbook type code
>(defun get-signal (wire)
>        (wire-signal-value wire)
>
>;; real world code
>(defun not-a-wire (x)
>        (error "~S is not a wire" x))
>
>(defun get-signal-rw (wire)
>        (if (wire-p wire)
>                (wire-signal-value wire)
>        (not-a-wire wire)))
>
>Is checking types before using them this considered good or bad Lisp
>programming practice?  If it is bad, how might be this handled with
>better style, or am I just worrying about nothing here?

Unless you use (declaim (optimize (safety 0))), all the accessors created
automatically by DEFSTRUCT perform their own type checking.  So checking it
yourself is redundant, and is not usually done.

But if you *are* going to do type checking, you should use the CHECK-TYPE
macro.  It signals a standard error type, so that your type checks will be
consistent with the system's.

-- 
Barry Margolin, ··············@level3.com
Genuity Managed Services, a Level(3) Company, Woburn, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.
From: Steven M. Haflich
Subject: Re: Parameter type checking
Date: 
Message-ID: <BBFxa.1035$ep.102013123@newssvr13.news.prodigy.com>
Barry Margolin wrote:

> Unless you use (declaim (optimize (safety 0))), all the accessors created
> automatically by DEFSTRUCT perform their own type checking.  So checking it
> yourself is redundant, and is not usually done.

Huh?  To my knowledge the ANS places no requirements that defstruct slot
accessors do type checking.  Can you cite some justification for your
statement?
From: Nikodemus Siivola
Subject: Re: Parameter type checking
Date: 
Message-ID: <ba3kb5$5gjco$1@midnight.cs.hut.fi>
Burton Samograd <······@hotmail.com> wrote:

> Is checking types before using them this considered good or bad Lisp
> programming practice?  If it is bad, how might be this handled with

In addition to the redundancy issue already mentioned, you are crippling
the code: imagine if you later decide to change some function to a method,
to take adantage of polymorphism. With the additional type checks in place
this requires you to get rid of them first.

If the type is important (and unlikely to change in the future) you may
also prefer to DECLARE it instead of checking it, so that the compiler
may generate more efficient code. 

Though smart compilers are likely to use the CHECK-TYPE to infer the type
anyway, and optimize the whole check away if the type can be proved at
compile time. Or so one can hope. ,)=

Cheers,

  -- Nikodemus
From: Steven M. Haflich
Subject: Re: Parameter type checking
Date: 
Message-ID: <3EC72892.6070907@alum.mit.edu>
Burton Samograd wrote:

> (defstruct wire
>         (signal 0)
>         (action-procs '())
> ...
> Is checking types before using them this considered good or bad Lisp
> programming practice?  If it is bad, how might be this handled with
> better style, or am I just worrying about nothing here?

More modern usage would be to use defclass and avoid defstruct.  Since
accessors and other functions defined on standard-objects are generic
functions composed out of specialized methods, the kind of type checking
you want is essentially automatic, and enforced by clever implementation
mechanisms probably more efficient than you would imagine.  A gf can be
augmented to handle new classes without rewriting manually-inserted
typechecking.  New methods will handle new classes, and if there is no
applicable method, no-applicable-method will be called (to signal error,
by default) reliably at all compilation settings.

Some members of X3J13 felt that defstruct should almost be deprecated.
It buys only a small efficiency, but has no defined semantics for
redefinition.
From: Joe Marshall
Subject: Re: Parameter type checking
Date: 
Message-ID: <1xyuq3tg.fsf@ccs.neu.edu>
Burton Samograd <······@hotmail.com> writes:

> ;; textbook type code
> (defun get-signal (wire)
>         (wire-signal-value wire)
> 
> ;; real world code
> (defun not-a-wire (x)
>         (error "~S is not a wire" x))
> 
> (defun get-signal-rw (wire)
>         (if (wire-p wire)
>                 (wire-signal-value wire)
>         (not-a-wire wire)))

(defun get-signal-rw (w)
  (check-type w wire)
  (wire-signal-value w))

> Is checking types before using them this considered good or bad Lisp
> programming practice?  

It depends.  Under high safety, you would eventually get an error if
you passed the wrong type into GET-SIGNAL-RW, so you aren't going to
gain any extra safety.  What you DO gain is perspicuity.  Any casual
user of your source code will see that the argument W must be a wire.
Any user that passes in the wrong argument type will be notified
immediately what went wrong and why.

> If it is bad, how might be this handled with
> better style, or am I just worrying about nothing here?

You want to use CHECK-TYPE rather than rolling your own.  I use the
convention that API functions check their arguments, but lower level
`internal' functions assume that the API did its job.  Also, I try to
a convention in naming:  If two functions perform (roughly) the same
operation, they should have (roughly) the same name.  So I would have
named the non-checking version something like %WIRE-SIGNAL-VALUE (the
leading percent sign indicates `this is an internal function, it does
no checking') and the checking version would be named
WIRE-SIGNAL-VALUE.  (In addition, I might INLINE the non-checking
version.  I might EXPORT the checking version.)