Subject: bug#33998: 27.0.50; cl-delete does not delete the first list element

From: Drew Adams <[email-masked]>
Date: Tue, 8 Jan 2019 17:30:10 -0800 (PST)

> > It's not about implementation of `cl-delete'. It's
> > not about the type of sequence you pass it.  It's
> > about a variable being something different from its
> > value.
> 
> Drew, it is you who are missing something basic here:
> 
>   (defun mistery (thing seq)
>     (let ((head (elt seq 0)))
>       (cl-delete thing seq)
>       (eq head (elt seq 0))))
> 
> Today, in Emacs this always returns t, for every THING and sequence SEQ
> you can think of (in fact, for vectors, cl-delete delegates to cl-remove).
> This is perfectly CL-compliant.  But a future, different, also perfectly
> CL-compliant, implementation of cl-delete, might very well make this
> function return nil.  In fact, if you port this code to SBCL or Allegro
> CL by changing 'cl-delete' to 'cl:delete'
> 
>   (mistery 1 (list 1 2 3 4)) ;; => t
>   (mistery 1 (vector 1 2 3 4)) ;; => nil

Your example has no bearing on our discussion,
AFAICT.

What is passed to your function are two values -
no variables.  Again, `cl-delete' sees only a
sequence value, not any _variable_ that might
have that sequence as its variable.  And yes,
that's by design.  `cl-delete' can change the
elements of a sequence (a value), but it cannot
change the value of a variable.  That's not its
job.

> So again, for the nth time, it's a bad idea to rely on SEQ after calling
> 'cl-delete'.

Again, you are confusing `SEQ' the variable with
its value.  There is no such general rule with
"always" as part of it.  Not in Lisp, there ain't.

If that were not the case then you would be in
effect claiming (and perhaps you are explicitly
claiming) that CL's definition of `delete' is a
bad one, misguided, since it applies only to a
sequence and not to any variable that might have
that sequence as its value.

Contrast Lisp functions such as `delete' and
`nconc' to a Lisp function such as `add-to-list'
or to a special form (or macro) such as `push'.
The latter act on a _variable_ (possibly a
generalized variable - a place).  `delete',
`nconc' etc. do NOT act on a variable.

If you really believe "always" to apply then you
had better toss all of the functions that possibly
modify values, replacing them with only macros or
special forms that (like `push') set a variable
(place) to its modified value or to functions that
(like `add-to-list') accept a variable (symbol)
as argument and set it to its modified value.

Such things are available in Lisp, and you can
define more such.  But Lisp doesn't _limit_ itself
to such things - IOW, Lisp does NOT say "always".
Why?  For the reasons I gave - sometimes you don't
want to update a variable.  IOW, "always" is not
always the case - it just isn't.

I already said I'd stop.  I hope that's the case
now, at least.  Perhaps we can agree to disagree:
you say "always"; I say "often".

You (apparently) think there's no reason for a
function such as `cl-delete', and that it would be
better for Lisp itself to enforce your "always"
rule, using either a macro or a function that
takes a symbol argument rather than just a value.
Any programmer can certainly do that.  Lisp offers
both possibilities.