Subject: bug#76313: New function `replace-region`

From: Stefan Kangas <[email-masked]>
Date: Sat, 29 Mar 2025 06:57:48 -0700

Eli Zaretskii <[email-masked]> writes:

>> From: Stefan Kangas <[email-masked]>
>> Date: Sat, 29 Mar 2025 05:46:51 -0700
>> Cc: [email-masked], [email-masked], [email-masked]
>>
>> Eli Zaretskii <[email-masked]> writes:
>>
>> >> From: Stefan Monnier <[email-masked]>
>> >> Cc: Stefan Kangas <[email-masked]>,  [email-masked],
>> >>   [email-masked],  [email-masked]
>> >> Date: Fri, 28 Mar 2025 11:38:19 -0400
>> >>
>> >> Any chance we could consider a  breaking change and force a non-nil value of
>> >> one of MAX-SECS or MAX-COSTS before the function is allowed to use the
>> >> costly algorithm?
>> >
>> > I'd prefer a completely backward-compatible change of passing a
>> > special value of MAX-SECS to indicate that the potentially costly
>> > algorithm is to be bypassed.
>>
>> We can keep trying to shoe-horn `replace-region-contents` into something
>> that looks like a function intended for general use, and document it as
>> such.  If we go that route, I think it would make sense to make the
>> change Stefan M proposes.
>
> Can you explain why it does NOT make sense to do what I proposed?  It
> gives us what Stefan wanted, but avoids the backward incompatibility
> (unless I'm missing something).

My understanding is that your proposal means that the potentially costly
algorithm is used by default, and that users should explicitly say so if
they don't want it.

That would be the best way to do it, if the normal case is that you want
the costly algorithm.  But my understanding so far is that, in the
overwhelming majority of cases, you do not want this.

>> Alternatively, we let it live on as a proper citizen of subr-x.el and
>> consequently remove it from the manual.  We've managed without
>> `replace-region` for decades already, so there's no urgent need to
>> elevate a design that has more than a few rough edges.
>
> ??? I'm confused: Stefan made replace-region-contents our preferred
> API, and demoted replace-buffer.  Are you suggesting to do the
> opposite now?

I agree that it's a step forward to demote `replace-buffer-contents`.

I submit that it's worth considering that we might better off with just
a function in subr-x.el, for when you need it, than officially blessing
a problematic or suboptimal function for general use.

Personally, I would feel reluctant to use this function.  For example, I
don't know how to specify a meaningful value for MAX-COSTS.  It is
documented as specifying "the quality of the difference computation",
which does not help much.  I think our users will feel this even more.

No other buffer editing primitives have anything resembling the MAX-SECS
and MAX-COSTS arguments.  I find the design choice to expose those
arguments a bit unusual in a specialized function, and inappropriate in
a function intended for general use.

That said, I understand that they are occasionally useful, or they
wouldn't exist.  I would make them internal to the function, with
sensible defaults that users could override with some variable when they
need to.  That change could be done in a backwards-compatible way with
advertised-calling-convention', and I would suggest we do that.

With that change, and the one proposed by Stefan Monnier above, I can
see that keeping `replace-region-contents` is okay.  I would also
suggest adding the alias `replace-region` for improved ergonomics and
consistency (e.g., with `delete-region`), but that is less important.
We can live with a long name.