[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Scheme-reports] Write procedure is not backwards compatible

Marc Feeley <feeley@x> wrote:

> That's not what I understood.

I think it is clear then, that we should revisit and deal with this,
as it appears that you and I are not the only ones who think about
these differently.

> By the way, I'd like to see how this is implemented.  I tried the
> latest Chibi Scheme, which is meant to be more or less a reference
> implementation for R7RS, and it gives an infinite loop on:

>    (write (let ((x (cons 1 2))) (set-cdr! x x) x))

That is clearly a bug in Chibi when it comes to implementing this. 
It is not necessarily a new thing to implement though. There are 
algorithms like tortoise and hare that I understand are used by 
implementations to detect these cycles. However, I delved a bit
further into things to address below.

> The semantics you suggest, while it would be compatible with R5RS
> and would avoid infinite loops, would not provide structure sharing
> information that datum labels are meant to give (and which are
> necessary to reconstruct the same graph structure when it is read
> back).  It would be sad to cripple the implentation like this.

Indeed, I see your point here, and I think that you have exposed an
unfortunate weakness in the way that we have specified these two
procedures. Indeed, I think that this needs to be changed. There are
ways of doing this that I think will satisfy everyone.  I will take an
example from Chez Scheme here because I am most familiar with it, and
it actually supports the semantics that I think make sense in these

Chez Scheme does not have a WRITE-SIMPLE, and while I can understand 
why someone might want WRITE-SIMPLE, I personally feel that having 
any such procedure that is so unstable in the face of unknown or 
uncontrolled inputs in the standard itself is a mistake. 

Chez Scheme does have WRITE that handles cycles. Specifically, there
is a parameter PRINT-GRAPH that controls whether or not WRITE will
print the shared structure of the datum or not. It defaults to #f, and
WRITE will not normally print the shared structures unless there is a
cycle, in which case it enables PRINT-GRAPH and proceeds with printing
the shared structure, since it cannot reliably do otherwise. However,
if you set PRINT-GRAPH to #t before calling WRITE, then all shared
structures, regardless of whether they contribute to a cycle, or even
whether any cycle exists in the system at all, will be printed.

	(parameterize ([print-graph #t]) 
	  (write (let ([x (list 5)]) (list x x))))
(#0=(5) #0#)

        (parameterize ([print-graph #f]) 
	  (write (let ([x (list 5)]) (list x x))))
((5) (5))

        (parameterize ([print-graph #f]) 
          (write (let ([x (list 5)]) (set-cdr! x x) x)))
Warning in write: cycle detected; proceeding with (print-graph #t)
#0=(5 . #0#)

I think that something like this serves us better and does not cripple
the system, while still preserving by default the expectations that we
have in being able to WRITE programs.

Aaron W. Hsu | arcfide@x | http://www.sacrideo.us
Programming is just another word for the lost art of thinking.

Scheme-reports mailing list