guile-user
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Write a macro which defines a procedure


From: zelphirkaltstahl
Subject: Write a macro which defines a procedure
Date: Sat, 20 Jul 2019 00:51:58 +0200
User-agent: Posteo Webmail

Hi Guile Users,

I want to write a macro, which creates a procedure of given name, where the given name is a not yet defined identifier.
Here is what I have so far:

--------8<--------begin-------->8--------
(use-modules (web uri)
             (web client)
             (json)
             (ice-9 iconv))

(define-syntax define-api-route
  (syntax-rules ()
    [(define-api-route route http-method my-content-type)
     (module-define! (current-module)
                     ;; `route` should be `/container/json` for example.
                     route
                     (lambda* (docker-socket #:key (data #f))
                       (call-with-values
                           (lambda ()
;; Here the route needs to be given as a string to `http-get`.
                             (http-get (variable-name->string route)
                                       #:port docker-socket
                                       #:version '(1 . 1)
                                       #:keep-alive? #f
;; Why is my quasiquote not working as expected? #:headers `((host . ("localhost" . #f)) (content-type . (,my-content-type (charset . "utf-8"))))
                                       #:body (scm->json-string data)
                                       #:decode-body? #t
                                       #:streaming? #f))
                         (lambda (response response-text)
(let ([resp-text-as-string (bytevector->string response-text "utf-8")])
                             (cons response resp-text-as-string))))))]))

;; from: https://stackoverflow.com/a/21177216/1829329
(define-syntax variable-name->string
  (lambda (stx)
    (syntax-case stx ()
      ((_ id)
       (identifier? #'id)
       (datum->syntax #'id (symbol->string (syntax->datum #'id)))))))
--------8<--------end-------->8--------

However, when I call this macro as follows:


--------8<--------begin-------->8--------
(define-api-route /container/json 'POST application/x-www-form-urlencoded)
--------8<--------end-------->8--------

I get the following error:

--------8<--------begin-------->8--------
;;; <stdin>:33:0: warning: possibly unbound variable `/container/json'
;;; <stdin>:33:0: warning: possibly unbound variable `application/x-www-form-urlencoded' <unnamed port>:33:0: In procedure module-lookup: Unbound variable: /container/json
--------8<--------end-------->8--------

So I see that there are at least 2 problems with my macro:

1. `/container/json` is not defined. I thought it would be defined, as I tried to make the macro define it in the current module. 2. `application/x-www-form-urlencoded` is evaluated, although I have it in a quasiquoted expression.

There are other things, which I would like to implement once I get the above working:

* I would like the macro to complain, if there is other stuff with the same identifier already defined inside the module, as a little safety measure. However, this might be difficult, I guess, because the macro might be done before those other definitions of same identifier are even executed.

Anyway, can you help me out writing the macro, fixing at least the 2 issues or direct me to a tutorial, which covers how to write a macro which gives basically a new define form?

Regards,
Zelphir



reply via email to

[Prev in Thread] Current Thread [Next in Thread]