On Sat, Jan 23, 2010 at 7:34 PM, Eduardo Cavazos <[email protected]>wrote:
> Hello, > > I've been messing about with a 'named-arguments' macro: > > http://gist.github.com/284714 I am not convinced this is the right approach, since you are treading a bona fide first class function for a macro. What one would need is the ability to attach compile time attributes to a function, in particular attributes containing the needed information about the function signature. Then you could write a single macro "call" such that (call function-id (arg1 value1) ...) would expand to the right thing. Of course this is not obvious since you should make it to work across modules and with separate compilation. Anyway, I have looked at your code and notice that you do not check that the passed arguments are the expected one. For instance (create-point (x 10) (y 20) (z 30)) would silently ignore the "z" argument. Since I had nothing better to do this Sunday morning I have translated you code to use my sweet-macros library (the one described in my Adventures): (import (rnrs) (sweet-macros) (aps lang) (aps compat)) (def-syntax (named-arguments name ((parameter value) ...) name*) (with-syntax ((name-helper (identifier-append #'name "-helper"))) #'(begin (def-syntax name-helper (syntax-match () (sub (name-helper tbl) (with-syntax (((val (... ...)) (map (lambda (x) (datum->syntax #'name-helper (cdr (assq x (syntax->datum #'tbl))))) (syntax->datum #'(parameter ...))))) #'(name* val (... ...)))) (sub (name-helper tbl (k v) rest (... ...)) (with-syntax ((new-tbl (datum->syntax #'name-helper (cons (cons (syntax->datum #'k) (syntax->datum #'v)) (syntax->datum #'tbl))))) #'(name-helper new-tbl rest (... ...)))) )) (def-syntax (name (k v) (... ...)) (let ((expected-params (list 'parameter ...))) (for-each ;; check the passed parameters (lambda (param) (unless (memq param expected-params) (error 'name "unexpected parameter" param))) (syntax->datum #'(k (... ...)))) #'(name-helper ((parameter . value) ...) (k v) (... ...))))))) ;; example (named-arguments create-point ((x 0) (y 0)) list) (pretty-print (syntax-expand (named-arguments create-point ((x 0) (y 0)) list))) (create-point) (create-point (x 1)) ;(create-point (x 1) (y 2) (z 3)) (display (syntax-expand (create-point (x 1) (y 2))))
