Am Mi., 13. Mai 2020 um 01:06 Uhr schrieb John Cowan <xxxxxx@ccil.org>: >> If the reference to literal pairs (that they are immutable may also be >> important to compilers!) is removed, we can make ipairs a completely >> disjoint type to pairs, > > > That is exactly what I want to do. As for conventional AOT ompilers, they may be able to do better inference if they keep track of which pairs are erroneous to mutate and which are not, but the pairs that exist at run time are not the same as those that exist at runtime in the sense of eqv?, but only in the sense of equal?. For interpreters it's a matter of preventing self-modifying code. AOT compilers may want to put literals in a read-only data segment of the executable binary. So this seems to be crucial for AOT compilers as well. In any case, if the ipairs are made disjoint to pairs, this would change the semantics of this SRFI quite a lot, so it would definitely need a new SRFI. However, I would advise against forcing ipairs and pair literals to be disjoint. Otherwise, implementations will be forced to deal with three types of pairs, all of which have to be implemented efficiently (important for pairs!). We should remember that the number of tag bits available are limited. > I agree that such pairs and ipairs are isomorphic: the sample implementation of SRFI 116 is a modified copy of SRFI, in fact. But that does not make them useless. > > My intended use case for ipairs is to be able to pass list-like objects between threads or futures without requiring them to be copied for safety's sake. The same is true of immutable strings. As the Racket people correctly observed, mutability of either type is rare; as they chose to ignore, RnRS (even R6RS) requires that the tail variable of a lambda-expression is bound to a mutable list. For this use case, there will also be a request for immutable vectors, etc. Wouldn't it make sense to have a general mechanism to add immutability to Scheme objects so that we don't have an explosion of interfaces? (See below.) >> Racket's approach to make all pair immutable is, if I am not mistaken, >> less motivated by what seems to be the motivation of SRFI 116, but >> motivated by the fact that "apply" and rest argument handling can be >> implemented much more efficiently when there is a guarantee that the >> rest argument is not mutated. > > > Exactly so, at the expense of conformance. Note that R6RS implementations can reliably detect at library visitation time whether pairs are necessarily immutable: if a program does not transitively import (rnrs mutable-pairs), its pairs are all immutable, which provides all the advantages of uniformly immutable pairs in almost all programs while preserving conformance. But as far as I know no implementation takes advantage of this fact; even in #lang r6rs, the pairs are Racket mpairs, which hinders interoperability with #lang racket. (Hash tables and textual ports are likewise not interoperable.) It would have probably been more helpful if R6RS had offered two libraries (rnrs mutable-pairs) and (rnrs legacy-mutable-pairs). Only if the latter library were included, the legacy semantics would be used. The way as it stands now, most programs (transitively) need mutable pairs, so it doesn't pay off for compiler writers to treat the case of solely mutable pairs particularly. (Unfortunately, this route cannot be chosen for R7RS-large because the standard library (scheme base) is already fixed.) Whatever the final shape of SRFI 116 and immutable pairs will be, it would be great if we find a solution that does not result in duplication of code (most interfaces in all R7RS-large libraries (have to) accept and yield mutable pairs) and will be adopted by the users (we are having this discussion with immutable strings as well). (At the moment, there is no motivation to use SRFI 116, except for, maybe, clarity, because it is probably a lot less effective than, say, SRFI 1. And almost not integrated into the rest of the system. SRFI 101 isn't either, but one gets immediate benefits of a nice functional data structure like fast access to list elements, etc.) If we find a convincing solution where the immutable pairs already dictated by literals form the base of ipairs, that would be the best as implementations, and users already know these and we have to cope with them in any case. "Emulating" literals could also be a route for the use case you mentioned, named inter-process communication. What I can think of is a procedure `freeze` that takes a general Scheme object and returns an immutable Scheme object that is `equal?` to it. This can be efficiently implemented by copying the data structure to a memory area that can be mprotected to be read-only.