Hi Hamish, I find this confusing too.
It seems that the pretty printer calls the different handlers in order to detect cycles. If one turns of the pretty printer I get two calls instead of one. I am not exactly sure, why the pretty printer needs to this. The code in question: https://github.com/plt/racket/blob/0eb29a4dcf7c63e9e3881469deee2d655f2dd786/racket/collects/racket/pretty.rkt#L460 /Jens Axel 2014-05-17 20:44 GMT+02:00 Hamish Ivey-Law <hamish.ivey....@gmail.com>: > Dear Racket-users > > I am trying to understand the behaviour of the `gen:custom-write` > method. What I find confusing is that the `write-proc` function is > called twice for explicit calls to `write`, `display` or `print` and > three times when display happens in the (x)repl. For example: > > -> (struct thing (n) > #:methods gen:custom-write > [(define (write-proc tg port mode) > (printf "In thing write-proc (port = ~a, mode = ~a)~%" port > mode) > (fprintf port "Thing is ~a~%" (thing-n tg)))]) > -> (define tg (thing 7)) > -> tg > In thing write-proc (port = #<output-port:null>, mode = #f) > In thing write-proc (port = #<output-port:null>, mode = #f) > In thing write-proc (port = #<printing-port>, mode = 0) > Thing is 7 > > If the printing mode is specified explicitly by using `write`, > `display` or `print`, then `write-proc` is still called twice: > > -> (write tg) > In thing write-proc (port = #<output-port:null>, mode = #t) > In thing write-proc (port = #<output-port:redirect>, mode = #t) > Thing is 7 > -> (display tg) > In thing write-proc (port = #<output-port:null>, mode = #f) > In thing write-proc (port = #<output-port:redirect>, mode = #f) > Thing is 7 > -> (print tg) > In thing write-proc (port = #<output-port:null>, mode = #t) > In thing write-proc (port = #<output-port:redirect>, mode = 0) > Thing is 7 > > Is there an example of an implementation of `write-proc` which shows > how one should handle the combinations of values of `port` and `mode` > (and whatever else) in such a way that, for example, we can avoid > potentially expensive conversions to strings which are later > discarded? Or are we simply expected to cache anything that we don't > want to recompute ourselves? What is the rationale behind calling > `write-proc` several times? Where is this behaviour documented (other > than in the Racket source, obviously)? > > (In my particular application, the analogue of `n` is gigantic *and* > must undergo a costly conversion to a string via FFI before being > printed to a file. Not something I can afford to do twice!) > > I am very new to Racket. Please keep that in mind when responding! > Thanks very much in advance! > > Kind regards, > Hamish. > ____________________ > Racket Users list: > http://lists.racket-lang.org/users -- -- Jens Axel Søgaard ____________________ Racket Users list: http://lists.racket-lang.org/users