[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 21:36:28 EST 2014

On Tue, Dec 30, 2014 at 3:24 AM, Alexander D. Knauth
<alexander at knauth.org> wrote:
> My code don't actually do any format-string parsing, it does (format
> str) inside a with-handlers and if it succeeds it knows it takes 0
> arguments, and if it fails it looks at the error message.

(Well, yes, that's robust, but...)

> Oh ok, up until now I hadn't realized that error converted them to
> strings anyway.  (for the "tests" I used my-printf so that it would go
> on the the next "test") But I could probably add an extension to
> exceptions that did that.
> But you still couldn't do something like: (with your my-error)
> @my-error[name]{blah @some-value blah @write[another-value] blah}
> without my-error being a macro that wrapped everything in thunks, but
> my version of my-error could still be a function.

Yes, you need something other than a plain write, of course.  Here's a
rough sketch of what I was talking about (the procedure thing is a cheap
way to extend `output' to show values in a different way):

    #lang at-exp racket

    (require scribble/text/output)

    (define exn-extras (make-weak-hasheq))

    (struct v (value) #:property prop:procedure (λ(x) (print (v-value x))))

    (define (print-extras extras)
      (output (list (car extras) ": " (cdr extras))))

    (define (error* who . what)
      (define extras (cons who what))
      (define exn (exn:fail (with-output-to-string (λ() (print-extras extras)))
      (hash-set! exn-extras exn extras)
      (raise exn))

    (let ([old (error-display-handler)])
       (λ(msg exn) (define extras (hash-ref exn-extras exn #f))
                   (if (not extras) (old msg exn)
                       (parameterize ([current-output-port
                         (print-extras extras)
                         (old "" exn))))))

    @error*['foo]{blah blah
                    needed: @v["blah"]}

> That's part of it, but I also want to be able to have string arguments
> print as values with the ""s, and also be able to do stuff like:
> @my-format{some stuff
>            <~a,~a>@|(foo-x blah) (foo-y blah)|
>            more stuff}
> Where the place-fillers can be on the same line as the place-holders,
> even with a multi-line format string.

That's a very different problem, I only mentioned it as a side-issue.
In fact, such uses make the newline problem much more likely to happen,
since if you see the above work you're more likely to try things like:

    @my-format{some stuff
               <~a: ~a,
                    ~a>@|(foo-name blah) (foo-x blah) (foo-y blah)|
               more stuff}

But in any case, it's really best to deal with this separately.  I've
tried a few things in the past, but nothing was too appealing, at least
not more than the usual options:

    @my-format{some stuff
               @format["<~a,~a>" (foo-x blah) (foo-y blah)]
               more stuff}

    (define (xy p) (format "<~a,~a>" (foo-x p) (foo-y p)))
    @my-format{some stuff
               more stuff}

(And in your case you'd replace `format' with something that does
something similar to the above semi-trick.)

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

Posted on the users mailing list.