[plt-scheme] Trying to reliably turn a value into a list of snips

From: Robby Findler (robby at cs.uchicago.edu)
Date: Tue May 27 22:42:33 EDT 2008

DrScheme uses the pretty-printer when printing values in order to know
what to do with snips that are embedded in other data structures. Is
that one of the pieces that you need? Specifically, it overrides hooks
to let it control how sub-expressions are printed and if it encounters
a snip there, it just inserts (a copy of) the snip into the buffer.

The drscheme:language:add-snip-value is used so that other values can
be turned into snips (or so that some snips can be rendered
differently when they appear, eg picts are bitmap-ized so that the
drawing callbacks don't ever happen on a drscheme thread).


On Tue, May 27, 2008 at 9:38 PM, Danny Yoo <dyoo at cs.wpi.edu> wrote:
> Hi everyone,
> I've been trying to write a module that takes a value and returns its
> representation as a list of snips.  It sorta works, except when it doesn't.
>  Here's the code I have so far:
> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
> (module value-snips mzscheme
>  (require (lib "framework.ss" "framework")
>           (lib "mred.ss" "mred")
>           (lib "class.ss")
>           (lib "contract.ss"))
>  (provide/contract [value-snips (any/c . -> . (listof (is-a?/c snip%)))])
>  ;; value-snips: value -> (listof snip)
>  (define (value-snips a-value)
>    (let ([es (make-eventspace)])
>      (parameterize ([current-eventspace es])
>        (let ([ch (make-channel)])
>          (thread (lambda ()
>                    (define a-text (new (text:ports-mixin text:wide-snip%)))
>                    (let ([port (send a-text get-out-port)])
>                      (write a-value port)
>                      (flush-output port)
>                      (channel-put
>                       ch
>                       (reverse (get-snips/rev a-text 0 (send a-text
> last-position)))))))
>          (let ([result (sync ch)])
>            result)))))
>  (define (get-snips/rev text start end)
>    (send text split-snip start)
>    (send text split-snip end)
>    (let loop ([snips/rev '()]
>               [a-snip
>                (send text find-snip start 'after-or-none)])
>      (cond
>        [(or (not a-snip)
>             (>= (send text get-snip-position a-snip)
>                 end))
>         snips/rev]
>        [else
>         (loop (cons (send a-snip copy) snips/rev)
>               (send a-snip next))]))))
> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
> Unfortunately, this breaks when I hit things like picts.  picts aren't
> snips.  It looks like they get converted implicitly by the REPL in DrScheme.
>  I see that picts are registered to the snip converter through
> drscheme:language:add-snip-value.
> I haven't yet found a good way of getting at that function without having to
> integrate tightly with DrScheme.  I suspect I need to use the
> render-value/format functions that work with DrScheme, but I hesitate in
> doing so: it means I can't easily test my module.  At the very least, I
> don't know of an effective way of testing a tool that depends on DrScheme.
> Any suggestions would be greatly appreciated!
> _________________________________________________
>  For list-related administrative tasks:
>  http://list.cs.brown.edu/mailman/listinfo/plt-scheme

Posted on the users mailing list.