[plt-scheme] Newbie macro problem
how about this:
(define (flex-format str . rest)
(apply format str (sublist rest 0 (count-format-arguments str))))
No macros required.
Robby
At Fri, 1 Nov 2002 17:57:53 +0100, Erich Rast wrote:
> For list-related administrative tasks:
> http://list.cs.brown.edu/mailman/listinfo/plt-scheme
>
> Hi,
>
> I need a replacement for format that behaves exactly like format except
> that it takes an arbitrary number of arguments and simply ignores any
> more arguments than the format string requires:
>
> (flex-format "hello ~a" 'world) ==> "hello world"
> (flex-format "hello ~a" 'world 'folks 'good-day) ==> "hello world"
>
> Looks simple, and I've defined a function count-format-arguments that
> returns the number of format-tags that require an argument. If I have a
> function defined as (flex-format str . rest)
>
> (sublist rest 0 (count-format-arguments str))
>
> yields a list of the arguments that are really required by str,
> ommiting any further arguments.
>
> However, I simply can't figure out how to actually define flex-format.
> I'v tried various functions and macros for hours and never got the
> right result. Using apply and quasi-quotes, I either got errors about a
> missing syntax-transformer, or I didn't get the quasi-quotation right.
>
> Could someone show me how to define flex-format or explain a similar
> example to me?
>
> Best regards,
>
> Erich
>
> ======
> (define (count-format-arguments str)
> (let loop ((li (string->list str))
> (elem #f)
> (c 0))
> (cond ((null? li) c)
> ((not elem) (loop (cdr li) (car li) c))
> ((equal? elem #\~) (case (car li)
> ((#\a #\A #\v #\V #\s #\S #\e #\E #\c
> #\C #\b #\B #\o #\O #\x #\X)
> (loop (cdr li) (car li) (+ c 1)))
> (else (loop (cdr li) (car li) c))))
> (else (loop (cdr li) (car li) c)))))
>
> ; grabbed from the Net:
> (define sublist
> (lambda (ls m n)
> (define (sublist-internal result ls m n)
> (cond ((or (= m n) (= n 0)) ; limit cases
> result)
> ((null? ls)
> ;; either complain or return a useful default
> result)
> ((= m 0)
> (sublist-internal (cons (car ls) result) (cdr ls) 0 (- n
> 1)))
> (else (sublist-internal result (cdr ls) (- m 1) (- n
> 1)))))
> (reverse! (sublist-internal '() ls m n))))