[racket] at-exp: is there any way to make it turn @list{A @"string" escape} into (list "A " "string" " escape") ?
On Dec 28, 2014, at 5:42 PM, Eli Barzilay <eli at barzilay.org> wrote:
> On Sat, Dec 27, 2014 at 6:21 PM, Alexander D. Knauth
> <alexander at knauth.org> wrote:
>> Is there any way to make the at-exp reader turn @list{A @"string" escape}
>> into (list "A " "string" " escape.),
>> instead of into (list .A string escape.) ?
>
> The idea behind this is that @|...| can be used to include not only any
> Racket subexpression, but any number of them, so @|x| is just an
> identifier as is often used, and if you need two of them, you can use
> @|x y| which is more convenient than @|x|@|y|
Thanks, this is actually almost perfect, so that way I can do something like
@my-printf{given: ~v and ~v@|x y|}
(But DrRacket colors the second one red, is that a bug?)
> -- and @|| is therefore
> the degenerate case. This means that you can get what you want with
>
> @list{A @|"string"| escape}.
>
> (Long explanation, but the bottom line would look magical without it...)
>
>
> But...
>
>> The reason is that I wanted to make my own versions of format, printf,
>> fprintf, error, etc. that would work with the at-exp reader and
>> convert something like this:
>> @my-error['f]{message
>> given: ~v@"something"
>> other-arguments: ~v@"something-else"
>> ~v@"another-something-else"}
>> into something like this:
>> (error 'f "message\n given: ~v\n other-arguments: ~v ~v"
>> "something" "something-else" "another-something-else")
>
> ... 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.
;; parse-format-args : (Listof Any) -> (Cons String (Listof Any))
(define (parse-format-args args)
(match args
[(list) (list "")]
[(cons (? string? s (app format-string->num-of-args n)) rst)
(unless (<= n (length rst))
(error 'parse-format-args "format string requires ~v arguments, given ~v" n (length rst)))
(define-values (rst.vs rst.rst) (split-at rst n))
(match-define (cons rst.rst.s rst.rst.vs) (parse-format-args rst.rst))
(cons (string-append s rst.rst.s) (append rst.vs rst.rst.vs))]))
> But most of all, IMO it sounds like a bad idea since it tries to fight
> the natural mixed-text-and-expressions and bend it into a
> format-string-like thing. I'd go with something that avoids that and
> uses @-expressions more naturally, as in:
>
> @my-error['f]{message
> given: @~v[stuff]
> other-arguments: @~v[other-stuff]}
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.
>
> and have `my-error' be something like:
>
> (define (my-error what . text) (error what "~a" (string-appeng* text)))
>
>
> --
> ((lambda (x) (x x)) (lambda (x) (x x))) Eli Barzilay:
> http://barzilay.org/ Maze is Life!
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.racket-lang.org/users/archive/attachments/20141228/4141eb09/attachment.html>