[racket] print/pretty-print weirdness
Sorry for the long delay! And thanks for the smaller example, which is
helpful.
The problem is that the `write-proc` is called multiple times for a
single print, and the printer tries to keep track of quoting modes
across calls based on `eq?` identity.
If you change your example to have
(define a-printable2-list (list {test-printable2}))
and use that for the recursive print in `write-proc` of
`test-printable`, then the output is as you expect.
The printer's dependency on `eq?` identity is not properly documented,
and my current thought is that the printer should be fixed, instead of
the documentation. For now, I hope knowing that `eq?` identity is
relevant will help you find a workaround.
Meanwhile, the explanation for
> (print 'hello (current-output-port) 1)
'hello
in DrRacket is that something is broken, because the right behavior is
> (print 'hello (current-output-port) 1)
hello
I'll look into that, too.
At Mon, 11 Nov 2013 12:29:36 -0700, Christopher wrote:
> Greetings again.
>
> I'm still hoping for some help from you friendly bunch of geniuses!
>
> Lest you think that the printing weirdness I described in my previous email is
> relegated to that world of Racket OOP classes and objects, please look at this
> example which uses only struct values:
>
> #lang racket
>
> (struct test-printable []
> #:property prop:custom-print-quotable 'never
> #:methods gen:custom-write
> [(define [write-proc strct port mode]
> (when {eqv? mode 1}
> {error "test-printable printed with depth of 1"} )
> {fprintf port "(test-printable ~v)" {list {test-printable2}}} )])
>
> (struct test-printable2 []
> #:property prop:custom-print-quotable 'never
> #:methods gen:custom-write
> [(define [write-proc strct port mode]
> (when {eqv? mode 1}
> {error "test-printable2 printed with depth of 1"} )
> {display "(test-printable2)" port} )])
>
> Here is an interactions session:
>
> > {test-printable2}
> (test-printable2)
>
> > {list {test-printable2}}
> (list (test-printable2))
>
> > {test-printable} ; produces error
> . . test-printable2 printed with depth of 1
>
>
> What I want is for the third expression line to print the below:
>
> (test-printable (list (test-printable2)))
>
> But as you can see, that is not what happens. I don't understand why it does
> what it's doing. Furthermore, is there a solution can I use to get print to
> write stuff out without forcing it to be quoted when it isn't supposed to be?
>
> By the way, if I change the above code so that print is explicitly at quote
> depth of 0, print ignores it and calls the write-proc handler with quote depth
> of 1 anyway, thus giving the same error:
>
> (struct test-printable []
> #:property prop:custom-print-quotable 'never
> #:methods gen:custom-write
> [(define [write-proc strct port mode]
> (when {eqv? mode 1}
> {error "test-printable printed with depth of 1"} )
> {display "(test-printable " port}
> {print {list {test-printable2}} port 0} ; explicitly at quote
> depth of 0 but is IGNORED!
> {display ")" port} )])
>
> > {test-printable} ; still produces error
> . . test-printable2 printed with depth of 1
>
> I would love you hear back from someone in the know. Many thanks!
>
> --Christopher
>
>
>
> On Nov 5, 2013, at 12:09 PM, Christopher <ultimatemacfanatic at gmail.com> wrote:
>
> > I'm experiencing some weirdness with print and pretty-print.
> >
> > First of all, can someone please explain why these print the same thing:
> >
> > > (print 'hello (current-output-port) 0)
> > 'hello
> > > (print 'hello (current-output-port) 1)
> > 'hello
> >
> > But these do not:
> >
> > > (pretty-print 'hello (current-output-port) 0)
> > 'hello
> > > (pretty-print 'hello (current-output-port) 1)
> > hello
> >
> > (notice the bottom line has no quote in front of the symbol)
> >
> > It seems to me that (print 'hello (current-output-port) 1) should not print
> with a single-quote in front of the symbol, but it does, as you can see above.
> >
> >
> > Consider this:
> >
> > #lang racket
> >
> > (define allow-quoted #t)
> >
> > (define printable-unquoted<%>
> > (interface* []
> > [[prop:custom-print-quotable 'never]
> > [prop:custom-write
> > (lambda (obj port mode)
> > (cond
> > [{eq? mode #t} (send obj custom-write port)]
> > [{eq? mode #f} (send obj custom-display port)]
> > [(or {= mode 0} allow-quoted) (send obj custom-print port)]
> > [{= mode 1} {error {string-append "printable-unquoted<%> object "
> > "called with depth of 1" }}]))]]
> > custom-write custom-display custom-print ))
> >
> > (define test-printable%
> > (class* object% [printable-unquoted<%>]
> > (super-make-object)
> >
> > (define/public [custom-print port]
> > {display "(make-object test-printable%)" port} )
> >
> > (define/public [custom-write port]
> > {display "|;-)" port} )
> >
> > (define/public [custom-display port]
> > {custom-write port} )))
> >
> > (struct test-printable []
> > #:property prop:custom-print-quotable 'never
> > #:methods gen:custom-write
> > [(define [write-proc strct port arg]
> > {fprintf port "(test-printable ~v)" {vector (new test-printable%)}} )])
> >
> >
> > {print {test-printable}}
> >
> > If I run it with (define allow-quoted #t) then the result is:
> >
> > (test-printable '#((make-object test-printable%)))
> >
> > Notice that the declared unquotable object is printed in the middle of a
> quoted vector!!
> >
> > If I set allow-quoted to #f then we confirm the obvious:
> >
> > (test-printable '#(. . printable-unquoted<%> object called with depth of 1
> >
> > Can anyone tell me why my prop:custom-print-quotable 'never is not being
> respected on my class instance?
> >
> > Thanks,
> >
> > Christopher
>
>
> ____________________
> Racket Users list:
> http://lists.racket-lang.org/users