[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Void



    Date: Monday, 12 May 1986  06:28-EDT
    From: Kent M Pitman <KMP at SCRC-STONY-BROOK.ARPA>
    Re:   Void

        Date: Sun, 11 May 1986  21:06 EDT
        From: Rob MacLachlan <RAM@C.CS.CMU.EDU>

         The only places where a void expression may be legal are:
          1] Any place where the value is immediately discarded: PROGN, etc.
          2] Any place in a function that can return multiple values.  In
    	 addition to tail-recursive positions, this includes the protected
    	 form of UNWIND-PROTECT and the values form for
    	 MULTIPLE-VALUE-PROG1 when these forms are in such a
    	 multiple-value position. 
        
    I'm sorry, but I find this completely ridiculous. Many valid
    programs can be written which use `void' values in ways other than
    this without being ill-formed.

        Note that in either case, a void value may be illegal because the
        result was declared to be of some other type:

        (proclaim '(function frob-foo (foo) void))
        (defun frob-foo (foo) ...)
        
        (proclaim '(function make-foo ((member t nil)) foo))
        (defun make-foo (frob-p)
          (let ((foo (cons-a-foo)))
    	(if frob-p
    	    (frob-foo foo)
    	    foo)))

    Suppose that FROB-FOO puts the FOO on the heap somewhere. Then suppose that
    I have a function, CREATE-FOO, which is the only call of MAKE-FOO and is 
    defined as: 

    (DEFUN CREATE-FOO (STASH-P)
      (COND (PUT-IN-HEAP 
    	 (MAKE-FOO T)
    	 (VALUES NIL NIL))
    	(T
    	 (VALUES (MAKE-FOO NIL) T))))

    There's nothing ill-formed about the collection of programs which include
    my program and yours.

Not true.  I declared that MAKE-FOO *always* returns a FOO.  VOID is
not a FOO, ever.

    The programming problem you're worried about is a common one, but
    the technique you're proposing for fixing it is just not
    practical. This situation comes up in legitimate code (especially
    when macros are involved) all the time.

I am aware of the macro problem that you describe, but I am not
convinced that it is significant.  Any macro in Common Lisp which has
an implicit PROGN cannot get this effect by saving the value in a
variable, since the body might want to return multiple values.  A
macro which knows nothing about its body must place it in a
multiple-value context.  This is why there is a relation between
multiple-value contexts and legal VOID expressions.

    Consider the following common situation: I have a macro MYBLOCK
    which binds the variable * to the value of the previous
    computation at the same level.  For example:

    (DEFMACRO MYBLOCK (&BODY FORMS)
      `(LET ((* *))
         ,@(MAPCAR #'(LAMBDA (FORM) `(SETQ * ,FORM)) FORMS)))

In my reality, this macro assumes that each body form is not VOID.
I don't really see all these bad implications of adding a VOID type.
If you think that declaring things VOID crimps your style, then don't
do it.  If the compiler barfs because you are using the value of
something that some other bozo declared VOID, then you can always say
(PROGN xxx NIL).

  Rob