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

Re: Argument lists: a proposal to shoot at



	
    Date: Thu, 26 Jun 1986  23:51 EDT
    From: "Scott E. Fahlman" <Fahlman@C.CS.CMU.EDU>
    To:   NGALL@BBNG.ARPA
    Subject: Argument lists: a proposal to shoot at
    In-Reply-To: Msg of 26 Jun 1986  19:17-EDT from NGALL at G.BBN.COM
    Message-ID: <FAHLMAN.12218049604.BABYL@C.CS.CMU.EDU>
    
    
	Your encoding scheme does not let me see the number of
	'probably-stack-based' parameters (i.e., P+Q) given a function that
	has a &rest param and no &key params.  This makes it impossible to
	provide an encapsulation that would use &rest only where necessary (it
	would force the use of a &rest parameter for all args beyond the
	required parameters).
    
    Sorry, maybe I'm being dense, but I don't understand this.  What is it
    that an encapsulation can do better if it can see P+Q ?  Why do you want
    to rip the lid off this particular black box?
    
    -- Scott
    
What follows is some code that demonstrates what I had in mind.  The
function ENCAPPED is the function that my encapsulation program has to
put a wrapper around.  ENCAP1 is an example of the kind of wrapper
that is possible when both Q and P are known.  ENCAP2 is an example of
the kind of wrapper that must be used when only Q is known.  (I am
ignore the issue of keywords here.)


(defvar *defaulted-optional-marker* (make-symbol "DEFAULTED-OPTIONAL-MARKER"))

(defun encap1 (r1 r2 &optional (o1 *defaulted-optional-marker*)
                               (o2 *defaulted-optional-marker*)
                               (o3 *defaulted-optional-marker*)
                     &rest rest)
   (declare (optimize (speed 3) (safety 0) (space 0)))
   (prog2
       t ;; (before)
       (cond ((eq o1 *defaulted-optional-marker*)
              (encapped r1 r2))
             ((eq o2 *defaulted-optional-marker*)
              (encapped r1 r2 o1))
             ((eq o3 *defaulted-optional-marker*)
              (encapped r1 r2 o1 o2))
             ((null rest)
              (encapped r1 r2 o1 o2 o3))
             (t (apply #'encapped r1 r2 o1 o2 o3 rest)))
     ;; (after)
     ))

(defun encap2 (r1 r2 &rest rest)
   (declare (optimize (speed 3) (safety 0) (space 0)))
   (prog2
       t ;; (before)
       (apply #'encapped r1 r2 rest)
     ;; (after)
     ))

(defun encapped (r1 r2 &optional (o1 1) (o2 2) (o3 3) &rest rest)
  (setf foor1 r1)
  (setf foor2 r2)
  (setf fooo1 o1)
  (setf fooo2 o2)
  (setf fooo3 o3)
  (setf foorest rest))

(defun tencap1 (n)
  (time (dotimes (i n) (encap1 'a 'b 'c 'd 'e))))

(defun tencap2 (n)
  (time (dotimes (i n) (encap2 'a 'b 'c 'd 'e))))


Note that ENCAP1 has exactly the same lambda-list-signature as
ENCAPPED.

ENCAP1 benchmarks considerably faster in three CLs that I tried it in
than ENCAP2.

Now it is true that one could always use an arbitrary number of
optionals in the wrapper lambda-list, but one could not be sure that
one had used enough or too many, e.g., if I always use 10 optionals,
the wrapper could slow things down if the encapsulated function never
took more than 3 args. after the requireds.

Its not a big deal, but then neither is returning P.

	-- Nick