Subject: Re: bug#42296: 27.0.91; Correct manual entry for 'concat' w.r.t. allocation [PATCH]

From: Mattias Engdegård <[email-masked]>
Date: Fri, 10 Jul 2020 19:04:48 +0200

9 juli 2020 kl. 21.24 skrev Eli Zaretskii <[email-masked]>:

>  This function frequently, but not always, constructs a new string
>  that is not @code{eq} to any existing string.  Lisp programs should
>  not rely on the result being a new string nor on it being @code{eq}
>  to an existing string.
> 
>  When this function returns a string @code{eq] to another, changing
>  the result will also change that other string; to avoid that, use
>  @code{copy-sequence} on the result.

Thank you! First a minor detail: the word 'frequently' doesn't convey any useful information since the user isn't supposed to take any chances -- either the returned value is always new and unaliased, or there is no such guarantee. The frequency isn't relevant, and we shouldn't encourage the user to act as if it were by talking about it.

> To my mind, immutability (or, rather, the adverse effects of modifying
> the result of 'concat') is the result of the identity.  So it is
> conceptually wrong to talk about mutability _instead_ of the identity.
> Identity is the basic reason, immutability is the side effect.  Which
> is what I tried to say in the text I suggested.

I understand what you mean, but do not necessarily agree in every respect. A string may be unsuitable for modification for several (overlapping) reasons:

* It is a string literal that occurs in the program.
* It is a string produced by macro-expansion.
* It is a string resulting from other compile-time evaluation (eg, constant folding).
* It is a string residing in read-only storage of some kind (via dumping).
* It aliases another string in the program.
* It is an actual read-only string value (which we don't really have today, but we should not preclude its introduction in the future).

Thus mutability and identity are related concepts but neither clearly dominates the other; stating both is probably useful, for clarity if nothing else. Saying that mutating the return value merely entails changing some other string is understating and misleading: the consequences are not well-defined, and may include mutating programs and the raising of errors. (It will never reach C levels of undefined behaviour if we can help it, however.)

There is also the question whether the function can return one of its arguments. If so, the caller not only needs to abstain from mutating the returned value, but also the argument, even though it may be safely created by the caller. Currently, (concat x) never returns a string argument, unless it's a compile-time constant that cannot be mutated anyway. It's unclear whether we can guarantee this behaviour.

But let's be constructive: Taking your proposed text and performing some light surgery, we might end up with:

 This function does not always allocate a new string.  Callers should
 not rely on the result being a new string nor on it being @code{eq}
 to an existing string.

 In particular, the returned value should not be altered. To obtain
 a string that can be mutated, use @code{copy-sequence} on the result.