[racket] at-exp: is there any way to make it turn @list{A @"string" escape} into (list "A " "string" " escape") ?

From: Eli Barzilay (eli at barzilay.org)
Date: Mon Dec 29 16:53:01 EST 2014

On Mon, Dec 29, 2014 at 3:03 AM, Alexander D. Knauth
<alexander at knauth.org> wrote:
>
> (But DrRacket colors the second one red, is that a bug?)

(It uses a different parses, so it might not parse that part right.)


> > ... this is generally a bad idea.  What do you do when you want the
> > @"..." escapes?  How do you find out which parts of the input are
> > arguments and which are part of the format string?
>
> For that, I have a helper function that looks at the first argument,
> sees how many arguments it would take as a format string, and then
> takes the next n arguments as the place-fillers for that format
> string, then recursively looks at the next format string.

Well, what I meant is that it's a bad idea conceptually, in a way that
can lead to actual bugs.  For example, if you do exacly that, then
you'll probably have an unexpected result with something like:

    @my-error['x]{blah blah
                    blah blah ~v
                    @|"something"|}

And you can probably also run into surprises when some argument
evaluates to a string that has ~s in it.


> I wanted to be able to format things that can't be converted to text and
> back properly, so for example in DrRacket this works:
> @my-printf{the plt logo: ~v@(plt-logo #:height 50)}
> But this doesn't:
> (display @string-append{the plt logo: @~v[(plt-logo #:height 50)]})
> There is a similar-ish thing with syntax-objects and mixed numbers (and
> there are probably more) in DrRacket.

You can still do that nicely:

    (define (my-print . stuff) (for-each display stuff))
    @my-print{blah @some-value blah}

that, or some variant that uses `display' for strings and `print' for
other values:

    (define (my-print . stuff)
      (for ([thing (in-list stuff)])
        ((if (string? thing) display print) thing)))

or even ignore voids

    (define (my-print . stuff)
      (for ([thing (in-list stuff)] #:unless (void? thing))
        ((if (string? thing) display print) thing)))

so you can do something like:

    @my-print{blah @some-value blah @write[another-value] blah}

The bottom line is that I'm avoiding the strange mixture of a format
string and mixed string/values ("interpolation"), which makes it easier
to use.

-- 
          ((lambda (x) (x x)) (lambda (x) (x x)))          Eli Barzilay:
                    http://barzilay.org/                   Maze is Life!

Posted on the users mailing list.