[plt-scheme] Newbie macro problem

From: Robert Bruce Findler (robby at cs.uchicago.edu)
Date: Fri Nov 1 12:23:54 EST 2002

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))))



Posted on the users mailing list.