From: Scott McLoughlin
Subject: *print-circle*
Date: 
Message-ID: <F3kguc1w165w@sytex.com>
Howdy,
        Another implementation question. How to implement
(*print-circle* t) semantics?  I'm specifically interested
in getting the darn thing to work accross structure
print methods.
        Without burning too many brain cells, I can
imagine an implementation that used a "special" stream
type, but that seems cludgy.  

p.s. Thanks to all who responded to my q's regarding
structure inheritance and multiple-value imp's.

=============================================
Scott McLoughlin
Conscious Computing
=============================================

From: Barry Margolin
Subject: Re: *print-circle*
Date: 
Message-ID: <386hp4$1lj@tools.near.net>
In article <············@sytex.com> ····@sytex.com (Scott McLoughlin) writes:
>        Another implementation question. How to implement
>(*print-circle* t) semantics?  I'm specifically interested
>in getting the darn thing to work accross structure
>print methods.
>        Without burning too many brain cells, I can
>imagine an implementation that used a "special" stream
>type, but that seems cludgy.  

The top-level PRINT/WRITE has to make two passes through the object.  The
first time, it has to use a stream type that simply discards all the
output.  Every object that is encountered is entered into a hash table.  If
an object is encountered that is already in the hash table, its hash table
entry gets a number as a value and the recursive call to PRINT returns
immediately.

Then a second pass is made, outputting to the original stream.  Before each
object is printed, though, it is looked up in the hash table.  If there's a
numeric value and this is the first time it has been encountered during the
second pass, the #<number>= prefix is printed and the object itself is
printed.  If it's a subsequent encounter the #<number># notation is printed
and that recursive call to PRINT returns.
-- 

Barry Margolin
BBN Internet Services Corp.
······@near.net
From: Scott McLoughlin
Subject: Re: *print-circle*
Date: 
Message-ID: <Zsmiuc1w165w@sytex.com>
······@nic.near.net (Barry Margolin) writes:

> In article <············@sytex.com> ····@sytex.com (Scott McLoughlin) writes:
> >        Another implementation question. How to implement
> >(*print-circle* t) semantics?  I'm specifically interested
> 
> The top-level PRINT/WRITE has to make two passes through the object.  The

Howdy,
        OK. Cool. Clarification: this means that calling structure
:print-function's twice per logical "WRITE" is OK? (Don's see why not
but want to make sure.)
        Clarification: We similarly "run" a format spec twice?
        Thanks.

=============================================
Scott McLoughlin
Conscious Computing
=============================================
From: Barry Margolin
Subject: Re: *print-circle*
Date: 
Message-ID: <389c97$2n1@tools.near.net>
In article <············@sytex.com> ····@sytex.com (Scott McLoughlin) writes:
>        OK. Cool. Clarification: this means that calling structure
>:print-function's twice per logical "WRITE" is OK? (Don's see why not
>but want to make sure.)

I thought we explicitly specified that you can't depend on :print-function
or PRINT-OBJECT methods being called only once, but I can't find it in the
dpANS now.

Someone else posted the suggestion that the fake stream record the
positions in the output where all the objects start, so that #n= can be
inserted after one pass.  That same post also suggested not entering
objects into the hash table until they've been encountered a second time.
You can't have it both ways -- if you need to record the starting
positions, you need to do that upon first encounter.

Also, I don't think this technique will work well if you're
pretty-printing.  The insertion of the #n= may cause lines to break
differently, which can drastically affect the layout.
-- 

Barry Margolin
BBN Internet Services Corp.
······@near.net
From: Simon Brooke
Subject: Port of CMU Common LISP to Linux: Volunteers wanted
Date: 
Message-ID: <Cy9t3K.6tr@rheged.dircon.co.uk>
This is a second posting seeking interest and volunteers for porting
Carnegie Mellon University's Common LISP to Linux. CMU Common LISP is
widely regarded as one of the best non-commercial implementations of
the language currently available.

The porting effort, if it is to proceed, needs more volunteers and, in
particular, seeks volunteers with experience of compiler back-ends for
Intel 32 bit architectures.

TO RESPOND

*PLEASE* do not followup this article. It is massively cross-posted
and will annoy people. If you have already responded to my previous
posting, please do not respond to this one.

If you would like to volunteer, and believe you have relevent skills,
mail to me (·····@rheged.dircon.co.uk) with the subject line 

'CMU CL: volunteer'

If you would not like to volunteer, but would like to be kept informed
of the porting effort, please mail to me (·····@rheged.dircon.co.uk)
with the subject line

'CMU CL: interest'

-- 
··············@rheged.dircon.co.uk
From: Bruno Haible
Subject: Re: *print-circle*
Date: 
Message-ID: <3888u1$iao@nz12.rz.uni-karlsruhe.de>
Barry Margolin <······@nic.near.net> described the basic idea of an
average *PRINT-CIRCLE* implementation:

> The top-level PRINT/WRITE has to make two passes through the object.  The
> first time, it has to use a stream type that simply discards all the
> output.  Every object that is encountered is entered into a hash table.  If
> an object is encountered that is already in the hash table, its hash table
> entry gets a number as a value and the recursive call to PRINT returns
> immediately.
>
> Then a second pass is made, outputting to the original stream.  Before each
> object is printed, though, it is looked up in the hash table.  If there's a
> numeric value and this is the first time it has been encountered during the
> second pass, the #<number>= prefix is printed and the object itself is
> printed.  If it's a subsequent encounter the #<number># notation is printed
> and that recursive call to PRINT returns.

Two modifications of this are possible:

1. Only put those objects into the hash table that are encountered more
   than once while recursively walking the object. (You can use an
   algorithm similar to the garbage collector marking subroutine for this.)
   This will greatly reduce the consing overhead needed by PRINT.

2. You need not execute every FORMAT etc. twice. (There may also be
   PRINT-OBJECT methods whose output depends on (RANDOM)...)
   Instead, output the objects and their printed representation to a special
   kind of stream which stores the point where to insert #n= for each object.
   A final pass then actually inserts the #n= and outputs the printed
   representation to the original stream.


                    Bruno Haible
                    ······@ma2s2.mathematik.uni-karlsruhe.de
From: Rob MacLachlan
Subject: Re: *print-circle*
Date: 
Message-ID: <388svn$r99@cantaloupe.srv.cs.cmu.edu>
Contrary to Barmar's suggestion, I believe that implementing the complete CL
print-circle does require a special stream type.  This stream is needed to
contain the hashtable, since output to different underlying streams is
considered to be distinct for circularity purposes.  This somewhat esoteric
distinction only arises in single-threaded CL if print-functions are printing
to two different streams at the same time (which can reasonably happen if the
debugger is invoked during printing.)

In CMU CL, this is overloaded on the prettyprinting support, which also
requires seperate state "per print invocation."

  Rob