Return Styles: Pseud0ch, Terminal, Valhalla, NES, Geocities, Blue Moon. Entire thread

Macros in Racket [Scheme][newbie][help]

Name: Anonymous 2011-02-28 20:17

Hi /prog/. So I've only just picked up Racket and I want to write some macros to use with an SQL database.

I'd like:
(wrapper wrapper-id
  [query-id "SQL"]
  [query-id "SQL" f ...])

to define a procedure make-wrapper-wrapper-id, which I would then use to create some value which would contain the prepared sql statements, and lambdas to apply to the results of the queries.

Then after doing
(define some-wrapper (make-wrapper-... ...)),
I'd like to say:
(some-wrapper :: query-id param ...)
to automatically invoke the statement associated with query-id and apply the stored lambda to the result.

My implementation (prepare and execute provided by the DB module):
(define-syntax mk-f
  (syntax-rules ()
    [(mk-f) (lambda (%) %)]
    [(mk-f f ...) (lambda (%) (f ... %))]))

(define-for-syntax (mk-spec form)
  (let* ([def (syntax->list form)])
    (with-syntax ([id (car def)]
                  [sql (cadr def)]
                  [(f ...) (cddr def)])
      #'(list* 'id sql (mk-f f ...)))))

(define-for-syntax (mk-c-id id)
  (string->symbol (string-append "make-wrapper-" (symbol->string (syntax->datum id)))))

(define-syntax (wrapper stx)
  (syntax-case stx ()
    [(wrapper id defs ...)
     (with-syntax ([c-id (mk-c-id #'id)]
                   [(spec ...) (map mk-spec (syntax->list #'(defs ...)))])
       #'(define (c-id connect)
           (make-wrapper connect (list spec ...))))]))

(define (make-wrapper connect specs)
  (let* ([conn (connect)]
         [f (lambda (x) (list (car x) (cons (prepare #:connection conn (cadr x)) (cddr x))))])
    (cons conn (hash (append-map f specs)))))

(define-syntax ::
  (syntax-id-rules ()
    [(w :: id param ...)
     (exec-query w (quote id) param ...)]))

(define (exec-query wrapper id . params)
  (let ([m (hash-ref (cdr wrapper) id)])
    ((cdr m) (execute (car m) params))))

But, well, it doesn't work. I've stepped through the (wrapper ...) macro in DrRacket and it expands just right, but it's like the define does nothing; I can't reference make-wrapper-wrapper-id at all! And using the :: macro causes a bad syntax error.
It's rather late and I'd really appreciate your help, guys!

Name: Anonymous 2011-02-28 22:51

>>6
Not that unusual even for other lisps. I've had much deeper macros and functions myself. It's not a problem if you have a good editor.

Newer Posts
Don't change these.
Name: Email:
Entire Thread Thread List