Previous: Reader, Up: Reader & writer


4.6.2 Writer

Scheme48's writing structure exports its writer facility. The write and display bindings from it are identical to those from the scheme structure, which are the same bindings that R5RS specifies.

— procedure: write object [port] –> unspecified

Writes object to port, which defaults to the current output port, in a machine-readable manner. Strings are written with double- quotes; characters are prefixed by #\. Any object that is unreadable — anything that does not have a written representation as an S-expression — is written based on its disclosed representation. Such unreadable objects are converted to a disclosed representation by the disclose generic procedure (see below).

— procedure: display object [port] –> unspecified

Displays object to port, which defaults to the value of the current output port, in a more human-readable manner. Strings are written without surrounding double-quotes; characters are written as themselves with no prefix.

— procedure: recurring-write object port recur –> unspecified

Writes object to port. Every time this recurs upon a new object, rather than calling itself or its own looping procedure, it calls recur. This allows customized printing routines that still take advantage of the existence of Scheme48's writer. For example, display simply calls recurring-write with a recurring procedure that prints strings and characters specially and lets recurring-write handle everything else.

— procedure: display-type-name name port –> unspecified

If name is a symbol with an alphabetic initial character, this writes name to port with the first character uppercased and the remaining character lowercased; otherwise, display-type-name simply writes name to port with display.

          (display-type-name 'foo)
              -| Foo
          
          (display-type-name (string->symbol "42foo"))
              -| 42foo
          
          (display-type-name (cons "foo" "bar"))
              -| (foo . bar)
          
          (display-type-name (string->symbol "fOo-BaR"))
              -| Foo-bar

This is used when printing disclosed representations (see below).

4.6.2.1 Object disclosure

The methods structure exports the generic procedure disclose and its method table &disclose. When recurring-write encounters an object it is unable to write in a rereadable manner, it applies disclose to the unreadable object to acquire a disclosed representation. (If disclose returns #f, i.e. the object has no disclosed representation, the writer will write #{Random object}.) After converting a value to its disclosed representation, e.g. a list consisting of the symbol foo, the symbol bar, a byte vector, and a pair (1 . 2), the writer will write #{Foo #{Byte-vector} bar (1 . 2)}. That is: contents of the list are surrounded by #{ and }, the first element of the list (the `type name') is written with display-type-name, and then the remaining elements of the list are recursively printed out with the recur argument.

Typically, when a programmer creates an abstract data type by using Scheme48's record facility, he will not add methods to &disclose but instead define the record type's discloser with the define-record-discloser procedure; see Records.

Example:

     (define-record-type pare rtd/pare
       (kons a d)
       pare?
       (a kar set-kar!)
       (d kdr set-kdr!))
     
     (define-record-discloser rtd/pare
       (lambda (pare)
         `(pare ,(kar pare) *dot* ,(kdr pare))))
     
     (write (kons (kons 5 3) (kons 'a 'b)))
         -| #{Pare #{Pare 5 *dot* 3} *dot* #{Pare a *dot* b}}