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

From: Deus Max <[email-masked]>
Date: Mon, 07 Jan 2019 22:20:55 +0200

Thank you both for your replies.

On Mon, Jan 07 2019, João Távora wrote:

> There is no bug.
>
> You should always read "destructive" as "potentially
> destructive".
>

I believe the manual is precise and not up to interpretation. When it
says that it is "destructive", it is always "destructive". The cl-delete
function is always destructive. The variable you pass is modified.

> 'cl-delete', being a function, cannot know that the value
> you passed it is pointed to by the symbol 'tst'.  Or, in lisp
> speak, that that value is the variable binding of 'tst'.
>
> Because it doesn't know this, it cannot affect the variable
> binding of 'tst', to be '(cdr tst)', which would be the only
> way to do what you want (remove the first element).
>
> If 'cl-delete' were a macro, like 'pop' is, it could do that
> (but that would have other disadvantages).
>
> So, cumbersome as it is, you should always use:
>
> (setq seq (cl-delete thing seq ))
>
> The docstring of 'delq' has this explanation more or less:
>
> delq is a built-in function in `C source code'.
>
> (delq ELT LIST)
>
> Delete members of LIST which are `eq' to ELT, and return the result.
> More precisely, this function skips any members `eq' to ELT at the
> front of LIST, then removes members `eq' to ELT from the remaining
> sublist by modifying its list structure, then returns the resulting
> list.
>
> Write `(setq foo (delq element foo))' to be sure of correctly changing
> the value of a list `foo'. See also `remq', which does not modify the
> argument.
>
> João
>

The elisp functions `delq' and delete "destructive" as per manual remove
elements from a list and return the resulting list. It goes on to
recommend to always use the `(setq foo (delq elm foo))' construct.

OK, I agree, no argument here.
But my point is about function `cl-delete', which is part of the
cl-extension. So, the manual descriptions of `delq', `delete' do not
apply.

In cl:
  - to keep the original sequence intact, use `cl-remove'.
  - to modify the original sequence, use `cl-delete'.

The manual states for `cl-delete':
     This deletes all elements of seq that match item. It is a
     destructive operation. (period, no optional)

It goes on to remark, on the analogy between `cl-remove' and `cl-delete':
     Compare append and nconc, which are analogous non-destructive and
     destructive list operations in Emacs Lisp.

I still thing it is a bug.

It (`cl-delete') should delete *all* elements of seq, that match item, not only in the
returning value, but in the sequence itself.
Anyway, that is how it behaves in all other cases, except for the case
of a match on the *first* element. I don't see why the first element
should be different. The manual makes no mention of this as a special
(and peculiar) case.

>
>
>
>
> On Sun, Jan 6, 2019 at 5:48 PM Deus Max <[email-masked]> wrote:
>>
>>
>> Function cl-delete refuses to delete the first element of a list.
>> I tried with all sorts of list elements, same results each time.
>> Here is a simple example:
>>
>> (setq tst  '(5 8 9 5 10 14 5 23))
>>
>> (cl-delete 10 tst)  -> returns (5 8 9 5 14 5 23)
>> and
>> tst  -> (5 8 9 5 14 5 23)
>>
>> (cl-delete 5 tst)  -> returns (8 9 14 23)
>> but
>> tst -> (5 8 9 14 23)

*** Wrong ! should be the same to the returned value.
>>
>> The CL-manual says nothing about the first element being special. *ALL*
>> should mean all, right ? Am I missing something here ?
>>
>> CL-manual says:
>> — Function: cl-delete item seq &key :test :test-not :key :count :start :end
> :from-end
>>
>>       This deletes all elements of seq that match item. It is a
>>       destructive operation. Since Emacs Lisp does not support
>> stretchable strings or vectors, this is the same as cl-remove for
>> those sequence types. On lists, cl-remove will copy the list if
>> necessary to preserve the original list, whereas cl-delete will
>> splice out parts of the argument list. Compare append and nconc,
>>       which are analogous non-destructive and destructive list
>>       operations in Emacs Lisp.
>>

DeusMax