[racket] Is there anything like the cl format?

From: Jakub Piotr Cłapa (jpc-ml at zenburn.net)
Date: Fri Dec 17 19:09:19 EST 2010


I wanted to hijack the thread to ask about one idea I implemented. I am 
pretty sure this is "evil" but I do not now how to improve things.

I did a match-like macro for sync (of the event? kind). I wanted to have 
short names for the clauses but I didn't really want them to "pollute" 
the namespace of the using module so I did something like this (full 
code is on bitbucket [1]):

   [(#:after 1000) (printf "1000ms passed\n")]
   [(#:recv v #:on chn) (printf "~s received from channel ~s\n" v chn)])

The important part of the implementation is:

(define-for-syntax (keyword-stx->helper stx)
   (format-id stx #:source stx "receive-#:~a" (syntax-e stx)))

It takes a keyword and makes a (scoped) identifier from it by appending 

This allows the #:after and #:recv (and #:handle and #:at) clauses to be 
implemented (and possibly exported from unrelated modules) like this:

(define-syntax-rule (receive-#:handle (evt-expr result) e0 e1 ...)
   (handle-evt (or evt-expr never-evt)
               (λ (result) (rewind!) e0 e1 ...)))

(define-syntax-rule (receive-#:at (time) e0 e1 ...)
   (receive-#:handle ((let ([t time]) (and t (alarm-evt t))) _) e0 e1 ...))

(define-syntax-rule (receive-#:after (interval) e0 e1 ...)
   (receive-#:at ((now+ interval)) e0 e1 ...))

(define-syntax-rule (receive-#:recv (id #:on chn) e0 e1 ...)
   (receive-#:handle (chn id) e0 e1 ...))

I do not feel like this is a clean way to do this. But OTOH it kind of 
respects lexical scope and module provides. Also it tries not to suprise 
the developer.

The question:

Does the module system provide a way to create a completely seperate 
namespace for things like this (I read the Typed Scheme macrology papers 
but I failed to find a good solution to this). It should be seperate but 
preferably controllable with something like provide and require.

The reason I hijacked this thread:

It would be quite nice to make a printf alternative which takes a C like 
input string but converts it to a series of function/macro calls with 
the names of the functions based on the letters in the original string. 
Something like:

(printf "Value: %.5f from sender: % 20s\n" 5/6 robot-name)


(display "Value: ") (display (printf::f ".5" 5/6))
(display " from sender: ") (display (printf::s " 20" robot-name))
(display "\n")

Of course this could also be done with Scribble syntax instead of string 
parsing but the main selling point are the short identifiers together 
with "aftermarket" extensibility. In this case it is even more critical 
not to pollute the environment with bindings for symbols like 'f, 'd or 's.

Sorry for the long post and thanks for all input on this matter.

[1]: http://bb.loee.pl/rkt-util/src/9c60a54ee7df/receive.ss

Jakub Piotr Cłapa

Posted on the users mailing list.