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

Structure sharing in arguments

    Date: Wed, 23 Jul 86 14:24 EDT
    From: Brad Miller <miller@UR-ACORN.ARPA>
	Date: Wed, 23 Jul 86 13:21 EDT
	From: David C. Plummer <DCP@QUABBIN.SCRC.Symbolics.COM>
	    Date: Tue, 22 Jul 86 21:39:37 pdt
	    From: hpfclp!diamant@hplabs.HP.COM
		    From: Scott Fahlman <fahlman@C.CS.CMU.EDU>
		    Subject: Some easy ones (?)
		    Proposal #13: Structure Sharing in Arguments
		    Specify that the &REST or &BODY argument to a macro may be the very list
		    from the macro call, and not a copy, and therefore the user should not
		    perform destructive operations on it.
		    Similarly, a function that takes a &REST argument should not
		    destructively modify it because in some implementations its top-level
		    list structure might share with a list that the user gave as the last
		    argument to APPLY.

	    I don't really care whether you add a restriction not to do destructive
	    operations on a &REST or &BODY argument, but it better be clear that the
	    list returned may not be something which will go away on exiting the function
	    (which could happen if the parameter list were stored on the stack and a
	    pointer to that list was returned -- apparently what Symbolics does).
	    Nothing currently in CLtL limits me from doing the following (nor should it):
	    (defun foo (&rest x) x)
	[Yes, Symbolics uses stack-consed &rest lists, and they will screw you
	every now and then. ...]

	I'm fairly convinced that disallowing destructive operations on &rest
	lists is funtionally equivalent to not being allowed to store them in
	stable storage or to return them. ...

    Now wait a second. (defun foo (&rest x) x) is not destroying the rest
    argument. The problem is that the programmer who uses the result of foo
    may destroy that result. Should he have to know how foo is implemented
    to know what he is allowed to do to the result? I should think not....

I think the lesson here is that, in general, you shouldn't ever clobber
a CONS if you don't know where it has been.  Certain CL primitives do
guarantee to cons up fresh lists, and you can safely clobber their
results.  Everything else you ought to be careful with, and that
includes &rest arguments, the results of PARSE-BODY, the results of FOO,
and so on.  Unless a function or other construct is clearly documented
to indicate that it is okay to clobber its result, then you should avoid
doing so.