Email list hosting service & mailing list manager

Re: SRFI 13 redux: a proposed compromise between SRFI 140 and SRFI 152 Per Bothner (29 Mar 2019 22:31 UTC)

Re: SRFI 13 redux: a proposed compromise between SRFI 140 and SRFI 152 Per Bothner 29 Mar 2019 22:31 UTC

On 3/29/19 2:16 PM, John Cowan wrote:
> Here's the general outline for yet another string library SRFI that is meant to serve as a compromise between SRFI 140 and SRFI 152, while remaining fully compatible with R7RS-small.  I'm proposing this in order to try to break the deadlock between SRFI 152 and SRFI 140 advocates.

Much appreciated.

> 1) The SRFI 140 distinction between mutable and immutable strings is accepted.  However, although it is an error to attempt to mutate an immutable string. implementations are allowed not to support the distinction between mutable and immutable strings.  In such implementations, all strings are mutable,and there is no guarantee of O(1) behavior.  This is pretty much the SRFI 13 position.
> 2) The SRFI 140 istring? predicate is replaced with an mstring? predicate.  This returns #t on any string that is in fact mutable; on systems without a distinction it returns #t on all strings.

Ok - I don't feel strongly about this.  Is this any different from allowing systems without a distinction to have istring? return #f on all strings?

> 3) Except as noted, all procedures accept either mutable or immutable strings and return immutable strings.  However, make-string and string-copy return mutable strings, and string-set!/fill!-copy! accept only mutable strings.

> 4) The SRFI 140 procedures string-upcase, string-downcase, string-foldcase, and substring are renamed to istring-upcase, istring-downcase, istring-foldcase, and isubstring respectively.  In that way they do not collide with the R7RS versions, which return mutable strings.  In implementations without a distinction, these procedures are of course the same.

Note these are not the only R7RS strings which SRFI 140 specifies to return immutable strings.
There is also (at least) string-append and list->string.

I have mixed feelings about this issue.  Backward compatibility is always desirable, but there are
costs.  Having to change existing programs to use istring-upcase/.../isubstring is also a compatibility
issue: Old programs that continue to use string-upcase/.../substring may continue to produce the same
result, but may be much slower than expected.  And that is a bug that is harder to catch that having
to add string-copy in the (few?) places where someone tries to mutate the results of using these procedures.

That, plus simplicity, is why I think on the whole the SRFI 140 compatibility-breaking is the
better option.  A compromise may be to use libraries: If you import (srfi xxx) or (r7rs-large) you
would have string-upcase/.../substring return immutable strings; if you import (scheme base) or
(scheme char) you get the r7rs semantics.

> 5) A new make-istring procedure is added to create immutable strings that consist of the same character repeated: the fill argument is required rather than optional.

This is redundant with SRFI 140's string-repeat, which allows the first argument to be *either* a character
or a string.  I'd rather than string-repeat.

> 6) The SRFI 118/140 procedures string-append! and string-replace! are made into linear-update procedures: that is, they always return a mutable string, which may or may not be the same (in the sense of eqv?) to the argument string.

I'm skeptical of linear-update procedures, especially when their names don't make it
clear what is going on: It is too easy to forget to add the set! - programs developed on
platforms that update in-place (which is probably most of them) will fail on platforms
that don't update in-place.  Most programmers are not familiar with linear-update procedures
or the motivations for having them (primarily implementation flexibility - which the typical
programmers have no interest or conception of).

Linear-update procedures might be more usable if compilers can warn about unused result
from a linear-update procedure.

I'm particularly opposed to re-purposing the names string-append! and string-replace! as that
breaks Kawa programs that use them.  I have no problems with the names string-append-linear! and

Another possibility is that the old names be macros:

    (string-append! mstring value ...)

would be a macro for:

   (set! mstring (string-append-linear! mstring value ...))

This could still break some SRFI 118-using programs, but fewer,
especially on platforms like Kawa that have generalized set! (SRFI 17).
That is mitigated by allowing the string-append! macro to expand to
(something like) %string-append-inplace on platforms that do the update in-place.
	--Per Bothner