[racket] Is there anything like the cl format?
Hi,
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]):
(receive
[(#: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
receive-.
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
--
regards,
Jakub Piotr Cłapa