From: Peter Seibel
Subject: Correct way to signal print-not-readable?
Date: 
Message-ID: <m3n0jhhki4.fsf@localhost.localdomain>
Suppose I'm writing a print-object method for a user-defined class. My
first attempt was something like:

  (defmethod print-object ((object my-class) stream)
    (when *print-readably*
      (signal (make-condition 'print-not-readable :object object)))
    (format stream "~a" (non-readable-string object)))

However, at least in ACL 6.2,

  (write object :stream *standard-output* :readably t)

at the REPL happily printed the non-readable form. If I change the
SIGNAL to ERROR it stops.

Perhaps the problem is I'm expecting the REPL to care that I signaled
print-not-readable?

Anyway, what's the correct way to write such a print-object method?

-Peter


-- 
Peter Seibel                                      ·····@javamonkey.com

  The intellectual level needed   for  system design is  in  general
  grossly  underestimated. I am  convinced  more than ever that this
  type of work is very difficult and that every effort to do it with
  other than the best people is doomed to either failure or moderate
  success at enormous expense. --Edsger Dijkstra

From: Simon Katz
Subject: Re: Correct way to signal print-not-readable?
Date: 
Message-ID: <b5t987$2c9v3u$1@ID-131024.news.dfncis.de>
"Peter Seibel" <·····@javamonkey.com> wrote:
>
> Suppose I'm writing a print-object method for a user-defined class.
> My first attempt was something like:
>
>   (defmethod print-object ((object my-class) stream)
>     (when *print-readably*
>       (signal (make-condition 'print-not-readable :object object)))
>     (format stream "~a" (non-readable-string object)))
>
> However, at least in ACL 6.2,
>
>   (write object :stream *standard-output* :readably t)
>
> at the REPL happily printed the non-readable form. If I change the
> SIGNAL to ERROR it stops.
>
> Perhaps the problem is I'm expecting the REPL to care that I
> signaled print-not-readable?

With SIGNAL, if nothing handles the condition, SIGNAL returns NIL and
execution continues. With ERROR, if nothing handles the condition, the
debugger is entered. See the spec entries for SIGNAL and ERROR.


> Anyway, what's the correct way to write such a print-object method?

This is the easiest way. Play with the :TYPE and :IDENTITY arguments
to get the behaviour you want.

(defmethod print-object ((object my-class) stream)
  (print-unreadable-object (object stream
                                   :type t
                                   :identity t)
    (format stream "~a" (non-readable-string object))))
From: Peter Seibel
Subject: Re: Correct way to signal print-not-readable?
Date: 
Message-ID: <m31y0thhbq.fsf@localhost.localdomain>
"Simon Katz" <·····@nomistech.com> writes:

> "Peter Seibel" <·····@javamonkey.com> wrote:
> >
> > Suppose I'm writing a print-object method for a user-defined class.
> > My first attempt was something like:
> >
> >   (defmethod print-object ((object my-class) stream)
> >     (when *print-readably*
> >       (signal (make-condition 'print-not-readable :object object)))
> >     (format stream "~a" (non-readable-string object)))
> >
> > However, at least in ACL 6.2,
> >
> >   (write object :stream *standard-output* :readably t)
> >
> > at the REPL happily printed the non-readable form. If I change the
> > SIGNAL to ERROR it stops.
> >
> > Perhaps the problem is I'm expecting the REPL to care that I
> > signaled print-not-readable?
> 
> With SIGNAL, if nothing handles the condition, SIGNAL returns NIL and
> execution continues. With ERROR, if nothing handles the condition, the
> debugger is entered. See the spec entries for SIGNAL and ERROR.

Yup. I understand that bit. So maybe my problem was I was expecting
the REPL to be unhappy (i.e. drop me into the debugger or something)
when I tried to write my object with :readable t. But I guess the REPL
doesn't care about the print-not-readable condition. So who does? I
assume that there are some conditions where there *is* a handler bound
to the print-not-readable error that will complain? Or do I assume too
much?

> > Anyway, what's the correct way to write such a print-object method?
> 
> This is the easiest way. Play with the :TYPE and :IDENTITY arguments
> to get the behaviour you want.
> 
> (defmethod print-object ((object my-class) stream)
>   (print-unreadable-object (object stream
>                                    :type t
>                                    :identity t)
>     (format stream "~a" (non-readable-string object))))

Ah, perfect. Thanks. I knew I had seen such a thing in my travels
through the HyperSpec but somehow couldn't find it this time around.
Duh.

-Peter

-- 
Peter Seibel                                      ·····@javamonkey.com

  The intellectual level needed   for  system design is  in  general
  grossly  underestimated. I am  convinced  more than ever that this
  type of work is very difficult and that every effort to do it with
  other than the best people is doomed to either failure or moderate
  success at enormous expense. --Edsger Dijkstra
From: Simon Katz
Subject: Re: Correct way to signal print-not-readable?
Date: 
Message-ID: <b5tg8m$2c0s2l$1@ID-131024.news.dfncis.de>
"Peter Seibel" <·····@javamonkey.com> wrote in message
···················@localhost.localdomain...
> "Simon Katz" <·····@nomistech.com> writes:
>
> > "Peter Seibel" <·····@javamonkey.com> wrote:
> > >
> > > Suppose I'm writing a print-object method for a user-defined
> > > class.
> > > My first attempt was something like:
> > >
> > >   (defmethod print-object ((object my-class) stream)
> > >     (when *print-readably*
> > >       (signal (make-condition 'print-not-readable
> > >                               :object object)))
> > >     (format stream "~a" (non-readable-string object)))
> > >
> > > However, at least in ACL 6.2,
> > >
> > >   (write object :stream *standard-output* :readably t)
> > >
> > > at the REPL happily printed the non-readable form. If I change
> > > the SIGNAL to ERROR it stops.
> > >
> > > Perhaps the problem is I'm expecting the REPL to care that I
> > > signaled print-not-readable?
> >
> > With SIGNAL, if nothing handles the condition, SIGNAL returns NIL
> > and execution continues. With ERROR, if nothing handles the
> > condition, the debugger is entered. See the spec entries for
> > SIGNAL and ERROR.
>
> Yup. I understand that bit. So maybe my problem was I was expecting
> the REPL to be unhappy (i.e. drop me into the debugger or something)
> when I tried to write my object with :readable t. But I guess the
> REPL doesn't care about the print-not-readable condition. So who
> does?

No one. If you want someone to care, you have to do it yourself;
either write your own handler, or use ERROR rather than SIGNAL, or use
PRINT-UNREADABLE-OBJECT, which signals an error when *PRINT-READABLY*
is true.

BTW, I think I know that "to signal an error" means "to effectively
call ERROR", rather than the possible alternative interpretation "to
signal a condition of type ERROR". But I can't find the place in the
spec that says so. Can someone help me?
From: Peter Seibel
Subject: Re: Correct way to signal print-not-readable?
Date: 
Message-ID: <m3of3xfvr4.fsf@localhost.localdomain>
"Simon Katz" <·····@nomistech.com> writes:

> BTW, I think I know that "to signal an error" means "to effectively
> call ERROR", rather than the possible alternative interpretation "to
> signal a condition of type ERROR". But I can't find the place in the
> spec that says so. Can someone help me?

Yeah, I'd like to see where that is clarified too. I was re-reading
the dictionary entry for *print-readably* and interpreted this:

   If printing an object readably is not possible, an error of type
   print-not-readable is signaled

to mean one would SIGNAL a condition of type print-not-readable. I.e.
not that you would use ERROR. Which you're saying is the wrong
interpretation.

-Peter

-- 
Peter Seibel                                      ·····@javamonkey.com

  The intellectual level needed   for  system design is  in  general
  grossly  underestimated. I am  convinced  more than ever that this
  type of work is very difficult and that every effort to do it with
  other than the best people is doomed to either failure or moderate
  success at enormous expense. --Edsger Dijkstra
From: Barry Margolin
Subject: Re: Correct way to signal print-not-readable?
Date: 
Message-ID: <aHsga.26$Hv4.734@paloalto-snr1.gtei.net>
In article <··············@localhost.localdomain>,
Peter Seibel  <·····@javamonkey.com> wrote:
>"Simon Katz" <·····@nomistech.com> writes:
>
>> BTW, I think I know that "to signal an error" means "to effectively
>> call ERROR", rather than the possible alternative interpretation "to
>> signal a condition of type ERROR". But I can't find the place in the
>> spec that says so. Can someone help me?
>
>Yeah, I'd like to see where that is clarified too. I was re-reading
>the dictionary entry for *print-readably* and interpreted this:
>
>   If printing an object readably is not possible, an error of type
>   print-not-readable is signaled
>
>to mean one would SIGNAL a condition of type print-not-readable. I.e.
>not that you would use ERROR. Which you're saying is the wrong
>interpretation.

I'm not sure if it's ever said explicitly, but I believe it says "signal a
condition" when it means to use SIGNAL, and "signal an error" when it means
to use ERROR.

-- 
Barry Margolin, ··············@level3.com
Genuity Managed Services, Woburn, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.
From: Barry Margolin
Subject: Re: Correct way to signal print-not-readable?
Date: 
Message-ID: <1Lsga.27$Hv4.924@paloalto-snr1.gtei.net>
In article <··············@localhost.localdomain>,
Peter Seibel  <·····@javamonkey.com> wrote:
>Yup. I understand that bit. So maybe my problem was I was expecting
>the REPL to be unhappy (i.e. drop me into the debugger or something)
>when I tried to write my object with :readable t. But I guess the REPL
>doesn't care about the print-not-readable condition. So who does? I
>assume that there are some conditions where there *is* a handler bound
>to the print-not-readable error that will complain? Or do I assume too
>much?

I wouldn't expect the REPL to have handlers for *any* conditions.  If it
did, it would render the rule that SIGNAL returns NIL if no handlers were
found useless for those conditions.  That's the only significant difference
between using SIGNAL and ERROR to signal a condition, and those conditions
would then behave the same in both cases.  We generally want to give the
programmer control by letting him choose whether to use SIGNAL or ERROR,
and establishing a global handler would usurp that control.

-- 
Barry Margolin, ··············@level3.com
Genuity Managed Services, Woburn, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.
From: Peter Seibel
Subject: Re: Correct way to signal print-not-readable?
Date: 
Message-ID: <m3brzxfspf.fsf@localhost.localdomain>
Barry Margolin <··············@level3.com> writes:

> In article <··············@localhost.localdomain>,
> Peter Seibel  <·····@javamonkey.com> wrote:
> >Yup. I understand that bit. So maybe my problem was I was expecting
> >the REPL to be unhappy (i.e. drop me into the debugger or something)
> >when I tried to write my object with :readable t. But I guess the REPL
> >doesn't care about the print-not-readable condition. So who does? I
> >assume that there are some conditions where there *is* a handler bound
> >to the print-not-readable error that will complain? Or do I assume too
> >much?
> 
> I wouldn't expect the REPL to have handlers for *any* conditions.  If it
> did, it would render the rule that SIGNAL returns NIL if no handlers were
> found useless for those conditions.  That's the only significant difference
> between using SIGNAL and ERROR to signal a condition, and those conditions
> would then behave the same in both cases.  We generally want to give the
> programmer control by letting him choose whether to use SIGNAL or ERROR,
> and establishing a global handler would usurp that control.

Yes, that makes good sense. I think maybe I got wrapped around the
axle because of my misinterpretation of the "signal an error" verbiage
in the *print-readably* docs. I figured (correctly it seems) that if
you try to WRITE an object with :readably t whose PRINT-OBJECT signals
an error when *print-readably* is true, that something bad should
happen unless you explicitly handle it (e.g. with handler-bind or its
kin). But if you signal with SIGNAL (as I originally assumed) the only
way that would happen would be if the REPL had bound a handler. But if
you signal with ERROR, it explodes the way I expected because ERROR
explodes if the error is *not* handled.

-Peter

-- 
Peter Seibel                                      ·····@javamonkey.com

  The intellectual level needed   for  system design is  in  general
  grossly  underestimated. I am  convinced  more than ever that this
  type of work is very difficult and that every effort to do it with
  other than the best people is doomed to either failure or moderate
  success at enormous expense. --Edsger Dijkstra
From: Kent M Pitman
Subject: Re: Correct way to signal print-not-readable?
Date: 
Message-ID: <sfwptodqz49.fsf@shell01.TheWorld.com>
Peter Seibel <·····@javamonkey.com> writes:

> [...]
> Yes, that makes good sense. I think maybe I got wrapped around the
> axle because of my misinterpretation of the "signal an error" verbiage
> in the *print-readably* docs. I figured (correctly it seems) that if
> you try to WRITE an object with :readably t whose PRINT-OBJECT signals
> an error when *print-readably* is true, that something bad should
> happen unless you explicitly handle it (e.g. with handler-bind or its
> kin). But if you signal with SIGNAL (as I originally assumed) the only
> way that would happen would be if the REPL had bound a handler. But if
> you signal with ERROR, it explodes the way I expected because ERROR
> explodes if the error is *not* handled.

Note that error is just signaling; the only difference between ERROR and
SIGNAL is what happens in the fallthrough case.  It's not like there's a
different process.

And, btw, let me just spin things slightly for you and say that "explode"
strikes me as a funny verb in this context because the debugger (i.e., the
interactive error handler) is just offering to allow you to intervene as
if there had been one additional handler:
 (handler-bind ((error ()
                  (let ((r (compute-restarts)))
                    (ask-user-to-choose-one-restart r))))
   ...)
I know what you mean by explode, but really in a sense it is doing just
the opposite--keeping something from exploding.  At the point the error
handler is entered, no ill action has been taken to the program and all
restarts are still available. I think the verb explode might be better 
reserved for the Macintosh bomb box or the Unix 'core dumped' situation,
which are WAY different even though I suppose there is the superficial
and not really other than superficial similarity of the condition having
the arguably-ill manners to make itself visible in any way.
From: Lars Brinkhoff
Subject: Re: Correct way to signal print-not-readable?
Date: 
Message-ID: <85of3xtf8u.fsf@junk.nocrew.org>
Kent M Pitman <······@world.std.com> writes:
> And, btw, let me just spin things slightly for you and say that "explode"
> strikes me as a funny verb in this context because the debugger (i.e., the
> interactive error handler) is just offering to allow you to intervene as
> if there had been one additional handler:
>  (handler-bind ((error ()
>                   (let ((r (compute-restarts)))
>                     (ask-user-to-choose-one-restart r))))
>    ...)

Maybe this is useless nit-picking, but lest anyone be confused,
I believe you mean something more like:

 (handler-bind ((error (lambda ()
                  (let ((r (compute-restarts)))
                    (ask-user-to-choose-one-restart r)))))
   ...)
From: Kent M Pitman
Subject: Re: Correct way to signal print-not-readable?
Date: 
Message-ID: <sfw8yv16nav.fsf@shell01.TheWorld.com>
Lars Brinkhoff <·········@nocrew.org> writes:

> Kent M Pitman <······@world.std.com> writes:
> > And, btw, let me just spin things slightly for you and say that "explode"
> > strikes me as a funny verb in this context because the debugger (i.e., the
> > interactive error handler) is just offering to allow you to intervene as
> > if there had been one additional handler:
> >  (handler-bind ((error ()
> >                   (let ((r (compute-restarts)))
> >                     (ask-user-to-choose-one-restart r))))
> >    ...)
> 
> Maybe this is useless nit-picking, but lest anyone be confused,
> I believe you mean something more like:
> 
>  (handler-bind ((error (lambda ()
>                   (let ((r (compute-restarts)))
>                     (ask-user-to-choose-one-restart r)))))
>    ...)

Heh.  Yeah...  Thanks.
From: james anderson
Subject: Re: Correct way to signal print-not-readable?
Date: 
Message-ID: <3E82E48E.66B37826@setf.de>
to raise the question, whether there are any angels on nits:

Lars Brinkhoff wrote:
> 
> Kent M Pitman <······@world.std.com> writes:
> > And, btw, let me just spin things slightly for you and say that "explode"
> > strikes me as a funny verb in this context because the debugger (i.e., the
> > interactive error handler) is just offering to allow you to intervene as
> > if there had been one additional handler:
> >  (handler-bind ((error ()
> >                   (let ((r (compute-restarts)))
> >                     (ask-user-to-choose-one-restart r))))
> >    ...)
> 
> Maybe this is useless nit-picking, but lest anyone be confused,
> I believe you mean something more like:
> 
>  (handler-bind ((error (lambda ()
>                   (let ((r (compute-restarts)))
>                     (ask-user-to-choose-one-restart r)))))
>    ...)

what is the difference between the latter and

  (handler-bind ((error #'(lambda ()
                   (let ((r (compute-restarts)))
                     (ask-user-to-choose-one-restart r)))))
    ...)

is one stylistically preferable?
does each permit a runtime to make different assumptions about the behaviour? 

?
From: Kent M Pitman
Subject: Re: Correct way to signal print-not-readable?
Date: 
Message-ID: <sfw4r5p6mw2.fsf@shell01.TheWorld.com>
james anderson <··············@setf.de> writes:

> what is the difference between [ (lambda ...) ] and [ #'(lambda ...) ]

Style.

> is one stylistically preferable?

No.  It's a personal preference matter, bordering on political preference.

It tends to be the case that people who are comfortable with CL's 
dual-namespace mechanisms don't mind #' while those who prefer Scheme's
single-namespace notation prefer just (lambda ...), but that's just
a generalization and there are some exceptions.

Some people don't like the #' because they find it ugly.

I personally like seeing #' because it alerts me to the use of a function
and I find that handy.  The mere use of lambda is not as visible to me.

> does each permit a runtime to make different assumptions about 
> the behaviour? 

There is no functional difference.  It's purely a notational difference.

LAMBDA is a macro in CL.

 (dolist (form '( (lambda (x) x)
                  #'(lambda (x) x) ))
   (format t "~2&~S ~30T== ~S~%" x (macroexpand-1 x)))

 (LAMBDA (X) X)                == (FUNCTION (LAMBDA (X) X))

 (FUNCTION (LAMBDA (X) X))     == (FUNCTION (LAMBDA (X) X))
From: Lars Brinkhoff
Subject: Re: Correct way to signal print-not-readable?
Date: 
Message-ID: <8565q5t46j.fsf@junk.nocrew.org>
james anderson <··············@setf.de> writes:
> >  (handler-bind ((error (lambda ()
> >                   (let ((r (compute-restarts)))
> >                     (ask-user-to-choose-one-restart r)))))
> what is the difference between the latter and
>   (handler-bind ((error #'(lambda ()
>                    (let ((r (compute-restarts)))
>                      (ask-user-to-choose-one-restart r)))))

(lambda ...) is a macro call which expands to #'(lambda ...), see

  http://www.lisp.org/HyperSpec/Body/mac_lambda.html
From: Coby Beck
Subject: Re: Correct way to signal print-not-readable?
Date: 
Message-ID: <b68o79$a05$1@otis.netspace.net.au>
"Peter Seibel" <·····@javamonkey.com> wrote in message
···················@localhost.localdomain...
>
> Suppose I'm writing a print-object method for a user-defined class. My
> first attempt was something like:
>
>   (defmethod print-object ((object my-class) stream)
>     (when *print-readably*
>       (signal (make-condition 'print-not-readable :object object)))
>     (format stream "~a" (non-readable-string object)))
>

I know I am chiming in late but I didn't see anyone else mention that
print-object is supposed to return the object as well as try to print it.

I experienced quite a number of "what the...?!?!" experiences working with
some code that had a whole bunch of specialized print-object methods that
did not return the object before I finally realized what was going wrong.
(mostly at the REPL using the * variable....)

So how about:

(defmethod print-object ((object my-class) stream)
  (when *print-readably*
    (signal (make-condition 'print-not-readable :object object)))
  (format stream "~a" (non-readable-string object))
  object)

--
Coby Beck
(remove #\Space "coby 101 @ bigpond . com")
From: Nils Goesche
Subject: Re: Correct way to signal print-not-readable?
Date: 
Message-ID: <lyadfb23ex.fsf@cartan.de>
"Coby Beck" <·····@mercury.bc.ca> writes:

> "Peter Seibel" <·····@javamonkey.com> wrote in message
> ···················@localhost.localdomain...
> >
> > Suppose I'm writing a print-object method for a user-defined
> > class. My first attempt was something like:
> >
> >   (defmethod print-object ((object my-class) stream)
> >     (when *print-readably*
> >       (signal (make-condition 'print-not-readable :object object)))
> >     (format stream "~a" (non-readable-string object)))
> >
> 
> I know I am chiming in late but I didn't see anyone else mention
> that print-object is supposed to return the object as well as try to
> print it.
> 
> So how about:
> 
> (defmethod print-object ((object my-class) stream)
>   (when *print-readably*
>     (signal (make-condition 'print-not-readable :object object)))
>   (format stream "~a" (non-readable-string object))
>   object)

Also, consider using PRINT-UNREADABLE-OBJECT instead.

Regards,
-- 
Nils G�sche
"Don't ask for whom the <CTRL-G> tolls."

PGP key ID 0x0655CFA0