Skip to content

Instantly share code, notes, and snippets.

@greghendershott
Created November 8, 2012 14:28
Show Gist options
  • Save greghendershott/4039102 to your computer and use it in GitHub Desktop.
Save greghendershott/4039102 to your computer and use it in GitHub Desktop.
Using make-keyword-procedure in a macro
#lang racket
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; Scenario 1: Plain function
;;
(define (def-proc ks)
;; Proc that takes a dict?
(define (f/dict d)
(displayln d))
;; Wrap f/dict in a proc that takes keyword arguments, instead.
(define symbol->keyword (compose1 string->keyword symbol->string))
(define keyword->symbol (compose1 string->symbol keyword->string))
(define (keyword<=? a b) (string<=? (keyword->string a) (keyword->string b)))
(define f/kw (make-keyword-procedure
(lambda (kws vs . rest)
(f/dict (map cons
(map keyword->symbol kws)
vs)))))
f/kw)
(define foo (def-proc '(a b c)))
(foo #:a 1 #:b 2 #:c 3)
;; =>
;; ((a . 1) (b . 2) (c . 3))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; Scenario 2: Using a macro
;;
(begin-for-syntax
(define (def-proc ks) ;; This is EXACTLY the same as above
;; Proc that takes a dict?
(define (f/dict d)
(displayln d))
;; Wrap f/dict in a proc that takes keyword arguments
(define symbol->keyword (compose1 string->keyword symbol->string))
(define keyword->symbol (compose1 string->symbol keyword->string))
(define (keyword<=? a b) (string<=? (keyword->string a) (keyword->string b)))
(define f/kw (make-keyword-procedure
(lambda (kws vs . rest)
(f/dict (map cons
(map keyword->symbol kws)
vs)))))
f/kw))
(define-syntax (def stx)
(syntax-case stx ()
[(_ name keys)
(let ([ks (syntax->list #'keys)])
#`(begin
(define name #,(def-proc ks))))]))
(def foo2 '(a b c))
(foo2 #:a 1 #:b 2 #:c 3)
;; =>
;; application: procedure does not accept keyword arguments
;; procedure: ...t/private/kw.rkt:191:14
;; given arguments:
;; #:a 1
;; #:b 2
;; #:c 3
;; Huh ????
@greghendershott
Copy link
Author

@samth what I ended up with is here: https://github.com/greghendershott/gapi/blob/c5e3e844c441623030c9af4307e3a03fa4321328/macro.rkt#L49

It works, but creating the syntax for a struct literal seems much more complicated than I expected. I have the feeling I went down the wrong fork in the road.

(BTW the background for this is that I had a lot of nearly-duplicated code in GAPI lib for using it in a dynamic/runtime way vs. a compiled/macro way. I wanted to refactor it.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment