[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