Next: , Previous: , Up: iklib   [Index]


6.15 Shared structures graph notation

This feature of the reader is derived from the SRFI 38 “External Representation for Data With Shared Structure”:

http://srfi.schemers.org/srfi-38/srfi-38.html

This graph notation allows the reader to build symbolic expressions with graph structure including cycles. Shared structures must always be used inside quoted datums; if we create a cycle in a symbolic expression passed as code to the expander: the result will be an infinite loop. Graph notation is available only when the textual input port is configured in #!vicare mode.

Graph notation extends the R6RS syntax with these additional cases:

<lexeme>                -> <r6rs lexeme>
                         | <defining datum>
                         | <defined datum>
<defining datum>        -> #<indexnum>=<r6rs lexeme>
<defined datum>         -> #<indexnum>#
<indexnum>              -> <digit>+

where <r6rs lexeme> is the lexeme definition in R6RS.

Parameter: print-graph
Parameter: print-graph #t
Parameter: print-graph #f

The graph notation is a way of marking and referencing parts of a data structure and, consequently, creating shared and cyclic data structures at read time instead of resorting to explicit mutation at run time. The default for this parameter is #f.

In a string generated by the Scheme objects writer: the prefix #N= marks the subsequent data structure with mark N, where N is a non–negative integer. The string #N# references the data structure marked N. Marks can be assigned and referenced in any order but each mark must be assigned to exactly once in an expression.

> (let ([x '#0=(1 2 3)])
    (eq? x '#0#))
#t
> (let ([x '#0#] [y '#0=(1 2 3)])
    (eq? x y))
#t
> (eq? (cdr '(12 . #1#)) '#1=(1 2 3))
#t
> (let ([x '#1=(#1# . #1#)])
    (and (eq? x (car x))
         (eq? x (cdr x))))
#t

The print-graph parameter controls how the writers (e.g. pretty-print and write) handle shared and cyclic data structures. In Vicare, all writers detect cyclic data structures and they all terminate on all input, cyclic or otherwise.

If the value of print-graph is set to #f, then the writers do not attempt to detect shared data structures. Any part of the input that is shared is printed as if no sharing is present. If the value of print-graph is set to #t, all sharing of data structures is marked using the #n= and #n# notation.

> (parameterize ((print-graph #f))
    (let ((x (list 1 2 3 4)))
      (pretty-print (list x x x))))
((1 2 3 4) (1 2 3 4) (1 2 3 4))

> (parameterize ((print-graph #t))
    (let ((x (list 1 2 3 4)))
      (pretty-print (list x x x))))
(#0=(1 2 3 4) #0# #0#)

> (parameterize ((print-graph #f))
    (let ((x (list 1 2)))
      (let ((y (list x x x x)))
        (set-car! (last-pair y) y)
        (pretty-print (list y y)))))
(#0=((1 2) (1 2) (1 2) #0#) #0#)

> (parameterize ((print-graph #t))
    (let ((x (list 1 2)))
      (let ((y (list x x x x)))
        (set-car! (last-pair y) y)
        (pretty-print (list y y)))))
(#0=(#1=(1 2) #1# #1# #0#) #0#)

Next: , Previous: , Up: iklib   [Index]