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

Re: Some easy ones (?)



    Date: 23 Jul 1986 22:27-EDT
    From: NGALL@G.BBN.COM

	
	Date: Wed, 23 Jul 86 13:08 EDT
	From: David C. Plummer <DCP@QUABBIN.SCRC.Symbolics.COM>
	To: NGALL@G.BBN.COM, Fahlman@C.CS.CMU.EDU
	Subject: Re: Some easy ones (?)
	In-Reply-To: <[G.BBN.COM]23-Jul-86 02:30:50.NGALL>
	Message-ID: <860723130828.1.DCP@FIREBIRD.SCRC.Symbolics.COM>
    
	    Date: 23 Jul 1986 02:30-EDT
	    From: NGALL@G.BBN.COM
    
	    Taking into account the other comments on this function (the ones that
	    I agree with at least), how about this proposal
	    (PARSE-BODY body &optional environment
				       declarations-allowed-p
				       doc-string-allowed-p)
	    Parses a BODY argument of the form
	    ({declaration|doc-string}* {form}*)
		...
    
	Until somebody says something profound to change my mind, I hold that if
	a "body" may not contain either declarations or doc-strings, it is not a
	true body, and therefore you have no right to call PARSE-BODY.  I have
	no idea what the reference to CASE and PROGN was.  If the claim that
	each clause of a CASE contained a "body" you are wrong; it contains an
	"implicit PROGN".  Implicit PROGNs are not suitable arguments to
	PARSE-BODY.
    
    This may not be profound, but its true.  A robust macro definition of
    CASE, i.e., one that performs an expansion time check to ensure that
    the initial forms after the KEYFORM are not declarations, can be
    written much more easily with DECLARATIONS-ALLOWED-P, e.g.,

    (defmacro case (keyform &rest clauses &environment env)
      (multiple-value-bind (decls doc clauses)
			   (parse-body clauses env nil)
			   (declare (ignore decls doc))
	;; At this point I can rest assured that parse-body has detected
	;; any illegal declarations.
	...)

Congradulations, you just broke CASE.  Three things: First, you are
calling parse-body on an &REST.  The is semantically 100% incorrect.
Second, this form won't work:
	(case foo
	  (declare (print "FOO's value was DECLARE"))
	  (otherwise (print "FOO's value was not DECLARE")))
Third, this breaks worse
	(macrolet ((uncalled-macro (&rest ignore)
		     (error "Loser!!")))
	  (case foo
	    (uncalled-macro (print "FOO's value was UNCALLED-MACRO"))
	    (otherwise (print "FOO's value was something else"))))
I think both are obvious.

    Things are easier still if we adopt my proposal for &body:

    (defmacro case (keyform &body (&forms clauses))
      ;; At this point I can rest assured that parse-body has detected
      ;; any illegal declarations.
      ...)

    Profound enough?

Wrong again.  (Adding complex syntax doesn't help, either.)  They aren't
forms.  They are case clauses.  Here's the full syntactic definition of
case, I think (it differs slightly from page 117):
	(case
	 { ( { atom-not-t-nil-otherwise | ( {atom}* ) }
	     . implicit-progn ) }*
	 { nothing | ( { otherwise | t }
		       . implicit-progn ) }
	 )
There is no body in here what-so-ever.  Therefore, parse-body is
conceptually the wrong thing.  Maybe what you want is something called
VERIFY-IMPLICIT-PROGN?  The contract of this is to make sure there
aren't any declarations?