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
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 ***
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
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