From: Karl B. Schwamb
Subject: Re: Are "destructive" functions really destructive?
Date: 
Message-ID: <8911291447.aa13784@PARIS.ICS.UCI.EDU>
········@Neon.Stanford.EDU (Michael Greenwald) writes:

>By the way, your implementation doesn't work when sequence is the
>result of function application.  It is illegal to "apply" (if such
>terminology is appropriate for a macro) SETF to something that isn't a
>"place".  Or is this one of the things you were referring to when you
>said "this doesn't do all the proper checking"?

Good point.  I guess special forms wouldn't help either, sigh.

>CL-delete doesn't side-effect the environment, while your macroized
>delete does.

I'm confused here.  The semantics of delete side-effects the environment
by changing the value of the sequence.  The macro form may side-effect 
a variable through a setf but I don't see any real difference between
that and altering its structure.

>Yes, CL-delete does side-effect sequence (and if sequence is shared,
>and isn't just an intermediate result, then the side-effect is visible
>in the "environment"), but if delete is always used "functionally"
>(for value) you can argue convincingly that cl-delete is cleaner than
>your delete (if you subscribe to the notion, as many do, that
>side-effects aren't particularly clean, and therefore should be
>minimized).

If you advocate a functional approach then it would seem that "remove"
should be used rather than "delete".  Since delete is designed to
be destructive, its only advantage seems to be speed since functional
style would advocate "equal" checks in subsequent code rather than 
"eq".  When functional style has to be abandoned in large systems
requiring efficiency or small systems requiring space, then it becomes
a question of how you'd like your destructive operations to work.
I agree that side-effects should be minimized, but I also think
they're rarely unavoidable in large systems.


······@think.com writes:

>For instance, what happens when sequence isn't a place that can be SETFed?

I would think this could be checked during code generation.

>Or what if you didn't really need to store the result back into the
>variable the list came from, e.g.

I think a better implementation would check if a list were being
used and the first element had been deleted.  Only in that special
case would a "setf" occur.  This seems a small price to pay to
get a consistent delete function.

Karl B. Schwamb                                  ·······@ics.uci.edu
Information and Computer Science                 
University of California, Irvine 92715           
From: Jeff Dalton
Subject: Re: Are "destructive" functions really destructive?
Date: 
Message-ID: <1514@skye.ed.ac.uk>
In article <··················@PARIS.ICS.UCI.EDU> ·······@ics.UCI.EDU ("Karl B. Schwamb") writes:
>
>········@Neon.Stanford.EDU (Michael Greenwald) writes:
>>CL-delete doesn't side-effect the environment, while your macroized
>>delete does.
>
>I'm confused here.  The semantics of delete side-effects the environment
>by changing the value of the sequence.  The macro form may side-effect 
>a variable through a setf but I don't see any real difference between
>that and altering its structure.

Well, let's start by just saying there's a difference: in one case,
a variable is given a new value; in the other the variable keeps the
same value, but the value is modified.  "Side-effects the environment"
is just another way to say "assigns to a variable".  "Environment" is
being used in a special sense here.

This difference can matter; but changing the structure is usually
considered to be more dangerous than assigning to a variable, rather
than the other way around, because other variables might point to
the same structure.

>If you advocate a functional approach then it would seem that "remove"
>should be used rather than "delete". 

Just so.

>Since delete is designed to be destructive, its only advantage seems
>to be speed since functional style would advocate "equal" checks in
>subsequent code rather than "eq".

Destructive operations aren't just a matter of efficiency.  There's
also a conceptual difference.  For example, one way to model
real-world objects that change over time is to use Lisp objects
that change (via destructive operations) over time.

>······@think.com writes:
>
>>For instance, what happens when sequence isn't a place that can be SETFed?
>
>I would think this could be checked during code generation.

True, but what if you still want to perform a delete in one of the
cases where the SETF was impossible?  The DELETE function would still
be useful in this case.  So I wouldn't want to replace that function
by the macro.

>>Or what if you didn't really need to store the result back into the
>>variable the list came from, e.g.
>
>I think a better implementation would check if a list were being
>used and the first element had been deleted.  Only in that special
>case would a "setf" occur.

But what if you don't want to store the result back in the place
the list came from?  What if you want to put it somewhere else,
for example, as in

   (setq b (delete 'this a))

>This seems a small price to pay to get a consistent delete function.

Consistency depends on how you look at it.  In Lisp, one often thinks
of data objects as independent of variables.  You get your consistency
only in cases where a list and a setf-able place are considered
together.  It still isn't a consistent operation on an object standing
alone.  For that, you'd need to use a headed list or something of that
sort.

However, there's nothing wrong with defining a macro to delete-in-a-
place.  There are already similar operations in Common Lisp, such as
PUSH and POP.

-- Jeff