[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
cases.

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
Scheme-reports@x
http://lists.scheme-reports.org/cgi-bin/mailman/listinfo/scheme-reports