Subject: Re: bug#16362: compiler disrespects referential integrity

From: Mark H Weaver <[email-masked]>
Date: Wed, 15 Jan 2014 17:15:14 -0500

Zefram <[email-masked]> writes:

> Mark H Weaver wrote:
>>I'm sorry that you've written code that assumes that this is allowed,
>>but in Scheme all literals are immutable.
>
> It's not a literal: the object was not constructed by the action of
> the reader.  It was constructed by non-literal means, and merely *passed
> through* the reader.

In Scheme terminology, an expression of the form (quote <datum>) is a
literal.  Where that <datum> came from is not relevant to the definition
of "literal".

> That's not to say your not-a-bug opinion is wrong, though.  Scheme as
> defined by RnRS certainly doesn't support this kind of thing.  It treats
> the print form of an expression as primary, and so doesn't like having
> anything unprintable in the object form.
>
>>It worked by accident in Guile 1.8,
>
> This is the bit that's really news to me.  *Scheme* doesn't support
> it, but *Guile* is more than just Scheme, and I presumed that it was
> intentional that it took a more enlightened view of what constitutes
> an expression.  If that was just an accident, then what you actually
> support ought to be documented.

Where does it say in the documentation that this is allowed?

To my mind, Guile documents itself as Scheme plus extensions, but you
cannot determine what extensions you can depend on by experiment.  If a
given extension is not documented, then you cannot depend on it.

> In principle it would also be a good idea to enforce this restriction
> in the interpreter, to avoid having this incompatibility between
> interpreter and compiler of the `same' implementation.

Perhaps, but there are always going to be discernable differences
between multiple implementations of the same language.

>>                                    but there's simply no way to support
>>this robustly in an ahead-of-time compiler, which must serialize all
>>literals to an object file.
>
> Sure there is.  The object in question is eminently serialisable: it
> contains only references to other serialisable data.

Yes, but the identity of the objects cannot in general be preserved by
serialization where multiple object files and multiple Guile sessions
are involved.

Consider this: you serialize an object to one file, and then the same
object to a second file.  Now you load them both in from a different
Guile session.  How can the Guile loader know whether these two objects
should have the same identity or be distinct?

> All that needs to change is to distinguish between actual literal
> pairs (that can be merged) and non-literals whose distinct identity
> needs to be preserved.

That information is not preserved by the reader.

> This might well be painful to add to your existing code, given the
> way you represent pairs.  But that's a difficulty with the specific
> implementation, not an inherent limitation of compilation.

There are inherent limitations to serialization.  In the general case,
the identity of mutable objects cannot be reliably preserved.

For example, how do you correctly serialize a procedure produced by
make-counter?

  (define (make-counter)
    (let ((n 0))
      (lambda ()
        (set! n (+ n 1)) n)))

      Mark