From: Richard M Kreuter
Subject: Right way to use the Printer
Date: 
Message-ID: <8764m3yzre.fsf@progn.net>
Howdy,

In the current application, there are a dozen or so classes whose
instances are supposed to be printed differently at various places in
the system (e.g., according to different XML schemas, or the same
schema with different levels of detail), but I can't figure out which
aspects/uses of the printer are right for the job.

The available tactics seem to be these:

(0) make some methods that specialize only on the data classes, and
    use pretty printer dispatch tables to collect
    context-to-printed-representation relationships in the program;

(1) assuming Gray streams, use subclasses of FUNDAMENTAL-OUTPUT-STREAM
    to represent contexts, and then have methods specialize on both
    the data classes and the stream classes;

(2) as a degenerate case of (1), have those methods be methods of
    PRINT-OBJECT, and bind *PRINT-PRETTY* to false;

(3) punt the task of understanding the printer, but employ it
    according to ad-hoc conventions.

Options (0) and (1) seem to entail writing approximately the same
methods, but (1) uses generic function dispatch rather than pretty
printer dispatch.  I can't see a clear winner between (0) and (1),
except incidentally that pprint dispatch is standardized (but Gray
streams are ubiquitous).  

Is there something I'm overlooking?  Any other suggestions on getting
the hang of the printer would be welcome, too.

Thanks,
RmK

From: Barry Margolin
Subject: Re: Right way to use the Printer
Date: 
Message-ID: <barmar-49EF14.00422825032006@comcast.dca.giganews.com>
In article <··············@progn.net>,
 Richard M Kreuter <·······@progn.net> wrote:

> Howdy,
> 
> In the current application, there are a dozen or so classes whose
> instances are supposed to be printed differently at various places in
> the system (e.g., according to different XML schemas, or the same
> schema with different levels of detail), but I can't figure out which
> aspects/uses of the printer are right for the job.
> 
> The available tactics seem to be these:
> 
> (0) make some methods that specialize only on the data classes, and
>     use pretty printer dispatch tables to collect
>     context-to-printed-representation relationships in the program;
> 
> (1) assuming Gray streams, use subclasses of FUNDAMENTAL-OUTPUT-STREAM
>     to represent contexts, and then have methods specialize on both
>     the data classes and the stream classes;
> 
> (2) as a degenerate case of (1), have those methods be methods of
>     PRINT-OBJECT, and bind *PRINT-PRETTY* to false;
> 
> (3) punt the task of understanding the printer, but employ it
>     according to ad-hoc conventions.
> 
> Options (0) and (1) seem to entail writing approximately the same
> methods, but (1) uses generic function dispatch rather than pretty
> printer dispatch.  I can't see a clear winner between (0) and (1),
> except incidentally that pprint dispatch is standardized (but Gray
> streams are ubiquitous).  
> 
> Is there something I'm overlooking?  Any other suggestions on getting
> the hang of the printer would be welcome, too.
> 
> Thanks,
> RmK

The Lisp printer is intended for ad hoc display to the user, usually of 
objects that can then be read back in by the reader.  For 
application-specific I/O, I suggest you use your own methods rather than 
the printer.  The only justification I can think of for customizing the 
printer rather than using your own methods is if you'll be printing 
standard Lisp objects that contain your objects (e.g. lists containing 
your instances) and want these embedded objects to be printed in your 
customized fashion, and don't want to reproduce all the standard Lisp 
printing machinery.

-- 
Barry Margolin, ······@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***
*** PLEASE don't copy me on replies, I'll read them in the group ***
From: Ken Tilton
Subject: Re: Right way to use the Printer
Date: 
Message-ID: <IO4Vf.127$D75.52@fe08.lga>
Richard M Kreuter wrote:
> Howdy,
> 
> In the current application, there are a dozen or so classes whose
> instances are supposed to be printed differently at various places in
> the system (e.g., according to different XML schemas, or the same
> schema with different levels of detail), but I can't figure out which
> aspects/uses of the printer are right for the job.
> 
> The available tactics seem to be these:
> 
> (0) make some methods that specialize only on the data classes, and
>     use pretty printer dispatch tables to collect
>     context-to-printed-representation relationships in the program;
> 
> (1) assuming Gray streams, use subclasses of FUNDAMENTAL-OUTPUT-STREAM
>     to represent contexts, and then have methods specialize on both
>     the data classes and the stream classes;
> 
> (2) as a degenerate case of (1), have those methods be methods of
>     PRINT-OBJECT, and bind *PRINT-PRETTY* to false;
> 
> (3) punt the task of understanding the printer, but employ it
>     according to ad-hoc conventions.

I like #4 Why fixate at all on the printer? Just create a 'render' GF 
that takes the instance to be rendered and an arbitrary 'context' second 
variable that you can define any way you like (types and state), then 
dispatch off those two. When you finally need to produce output, use 
print or format to get the output, but not as the more abstract 
'render'ing engine that calls print/format.

> Is there something I'm overlooking?  Any other suggestions on getting
> the hang of the printer would be welcome, too.

My 2c is a guess that you do not really want to get the hang of the 
printer, you want to produce certain output. (And it sounds like you 
have reached the same conclusion by the time you listed option 4.)

kt

-- 
Cells: http://common-lisp.net/project/cells/

"And I will know my song well before I start singing."  - Bob Dylan
From: Marco Baringer
Subject: Re: Right way to use the Printer
Date: 
Message-ID: <m2lkuypnio.fsf@bese.it>
Ken Tilton <·········@gmail.com> writes:

> I like #4 Why fixate at all on the printer? Just create a 'render' GF
> that takes the instance to be rendered and an arbitrary 'context'
> second variable that you can define any way you like (types and
> state), then dispatch off those two. When you finally need to produce
> output, use print or format to get the output, but not as the more
> abstract 'render'ing engine that calls print/format.

if you decide te define a generic render function you'd also do well
to look into ContextL[1] which makes enabling/disabling parts of the
render methods much clearer than having to pass around different
context objects.

[1] - http://common-lisp.net/project/closer/contextl.html

-- 
-Marco
Ring the bells that still can ring.
Forget the perfect offering.
There is a crack in everything.
That's how the light gets in.
	-Leonard Cohen
From: Paolo Amoroso
Subject: Re: Right way to use the Printer
Date: 
Message-ID: <877j6isuvt.fsf@plato.moon.paoloamoroso.it>
Richard M Kreuter <·······@progn.net> writes:

> In the current application, there are a dozen or so classes whose
> instances are supposed to be printed differently at various places in
> the system (e.g., according to different XML schemas, or the same
> schema with different levels of detail), but I can't figure out which
[...]
> Is there something I'm overlooking?  Any other suggestions on getting
> the hang of the printer would be welcome, too.

CLIM presentations and views may provide useful ideas:

  23 Presentation Types
  http://bauhh.dyndns.org:8000/clim-spec/23.html

  23.6 Views
  http://bauhh.dyndns.org:8000/clim-spec/23-6.html#_1208

  Common Lisp Interface Manager - CLIM II Specification
  http://bauhh.dyndns.org:8000/clim-spec/index.html


Paolo
-- 
Why Lisp? http://wiki.alu.org/RtL%20Highlight%20Film
The Common Lisp Directory: http://www.cl-user.net