Re: either-guard reference implementation John Cowan (29 Jul 2020 23:18 UTC)
Re: either-guard reference implementation Marc Nieper-Wißkirchen (31 Jul 2020 08:36 UTC)
Re: either-guard reference implementation John Cowan (05 Aug 2020 06:07 UTC)
Re: either-guard reference implementation Marc Nieper-Wißkirchen (05 Aug 2020 06:22 UTC)
Re: either-guard reference implementation John Cowan (05 Aug 2020 06:28 UTC)
Re: either-guard reference implementation Marc Nieper-Wißkirchen (05 Aug 2020 06:48 UTC)
Re: either-guard reference implementation John Cowan (07 Aug 2020 22:08 UTC)
Re: either-guard reference implementation Marc Nieper-Wißkirchen (09 Aug 2020 11:14 UTC)
Re: either-guard reference implementation John Cowan (09 Aug 2020 13:10 UTC)
Re: either-guard reference implementation Marc Nieper-Wißkirchen (11 Aug 2020 08:14 UTC)
Re: either-guard reference implementation John Cowan (11 Aug 2020 16:48 UTC)
Re: either-guard reference implementation Marc Nieper-Wißkirchen (15 Aug 2020 12:11 UTC)
Re: either-guard reference implementation John Cowan (15 Aug 2020 13:57 UTC)

Re: either-guard reference implementation Marc Nieper-Wißkirchen 15 Aug 2020 12:11 UTC

Please excuse the belated reply.

Am Di., 11. Aug. 2020 um 18:48 Uhr schrieb John Cowan <xxxxxx@ccil.org>:

>> Standard pair procedures already accept immutable pairs in the form of
>> datum literals.
>
>
> Literal pairs, as I will call them (as distinct from ordinary pairs and ipairs), are immutable only in the sense that it is an error to mutate them.  However, implementations *may* allow their routine mutation: Cyclone, Chibi, Sagittarius, Kawa, STklos, Scheme48, Loko, T prevent mutation, MIT, Gambit, Chicken, Guile, IronScheme, Bigloo, Loko, Gauche, Chez, Mosh, Larceny, Vicare, Picrin, Schemik, TinyScheme permit it.  Furthermore, it is impossible to create one at run time or detect one.

Indeed, the idea would be to allow the creation of such "literal
pairs" at runtime easily. (NB: It's not true that they cannot be
created by any means at runtime; through a trivial use of 'eval' it is
possible.)

That "it is an error" to mutate them should be enough. This helps
adoption and Schemes can start to add modes, in which such mutations
are detected.

> That means that they do not serve  the purposes of ipairs, that of guaranteeing (modulo frame-breaking implementation extensions) that they cannot be mutated by buggy code. Ipairs are, I claim, easier to reason about and easier to use in many situations, particularly extreme ones, than either ordinary pairs or literal pairs.

No existing code uses ipairs. And I guess the amount of code that has
been written since SRFI 116 and uses ipairs is neglecable. Moreover,
unless implementations special-case ipairs natively, ordinary pairs
and literal pairs are most likely more performant. In other words,
implementations have to catch up anyway, but then it makes more sense
to invest this energy into making literal pairs truly immutable.

> If all systems signaled an error on an attempt to mutate a literal pair, then indeed an `icons` analogue that returned a literal pair would suffice.  But they don't and it's my belief that they won't.  So if you want the advantages of immutability, you have to pay the cost of incompatible behavior.

"Signaling an error" is the wrong phrase here. It has to be
implementation-dependent how the mutation is detected and reported.

> I will, however, request another PFN for 116 that strikes out the claim that ordinary-pair operations should not support ipairs, and addis a recommendation for them to do so (nothing stronger is portable).  This is not a matter of subtyping but of ad hoc polymorphism, as in SRFI 135 procedures that accept textuals.

That sounds like a good idea for sure. In any case, "ipair?" has to be
allowed to return #t when applied to a literal pair.

>> Just drop "ipair?" from SRFI 116 and the route to
>> adoption is easy.
>
>
> That is as much as to say "Drop SRFI 116 altogether", since it will no longer serve any purpose to write icar rather than car.

Not at all; "icar" would return an immutable pair, which is relevant
for implementations that check whether they are mutated.

>> From a risk-mitigation viewpoint, you won't choose an implementation
>> that is silent on "(car 0)" either. We can expect that most quality
>> implementations will detect the error once they have found time to
>> adopt immutable strings, vectors and pairs.
>
>
> We cannot expect them to do the latter: see above.

If implementers see the value of true immutability, they will improve
their implementations in this regard. I think it is comparable to the
situation of SRFI 124.

>
>>
>> The good thing with this
>> approach is that all existing code will still work.
>
>
> I don't understand this claim.  Mutable pairs are not going away (except in Racket), so of course existing code will still work.

I mean the you if you have legacy code operating on pairs and that
this legacy claims not to mutate the pairs, you can easily feed it
with the immutable pairs of my proposal (which doesn't seem to be much
different  to your idea of a new PFN).

Marc

PS Somewhere on the SRFI 116 mailing list, I think I have proposed
procedures like the following:

(immutable OBJ)

and

(immutable! OBJ)

The first procedure creates an immutable copy of OBJ (whether a pair,
a string, vector, record, ...). It may reuse OBJ if it is already
immutable. The second procedure is a linear-update variant of the
former.

These procedures could be implemented either by extension of the
tagging system or by copying the data to heap areas that are
mprotected against writing and relying on SIGSEGV.