Hi!

I am trying to write a macro, which checks the name of an argument for 
presence a substring. This is not the main purpose of the macro, but I want 
to do different things depending on the substring being contained or not 
contained.

Here is what I've got so far:

~~~~~
;; A macro to get the identifier name as string, shamelessly copied from 
StackOverflow and renamed:

(define-syntax identifier-name->string
  (lambda (stx)
    (syntax-case stx ()
      ((_ id)
       (identifier? #'id)
       (datum->syntax #'id (symbol->string (syntax->datum #'id)))))))

;; And the actual macro I want to write:

(define-syntax define-api-route
  (lambda (stx)
    (syntax-case stx (GET HEAD POST PUT DELETE CONNECT OPTIONS TRACE PATH)
      [(_ route GET my-content-type)
       (string-contains? (identifier-name->string (syntax route)) "abc")
       (println "abc is in the identifier name")])))
~~~~~

With this, Racket will complain, that I am referencing an identifier before 
its definition:

~~~~~
> (define-syntax identifier-name->string
    (lambda (stx)
      (syntax-case stx ()
        ((_ id)
         (identifier? #'id)
         (datum->syntax #'id (symbol->string (syntax->datum #'id)))))))
> 
  (define-syntax define-api-route
    (lambda (stx)
      (syntax-case stx (GET HEAD POST PUT DELETE CONNECT OPTIONS TRACE PATH)
        [(_ route GET my-content-type)
         (string-contains? (identifier-name->string (syntax route)) "abc")
         (println "abc is in the identifier name")])))
> (define-api-route abc/abc/abc GET 
application/json)                                                               
  
; string-contains?: undefined;
;  cannot reference an identifier before its definition
;   in module: top-level
;   internal name: string-contains?
; [,bt for context]
~~~~~

If I take away the (syntax ...) in the guard expression however, it will 
also not work, as template variables may only occur in syntax:

~~~~~
> (define-syntax 
define-api-route                                                                
                         
(lambda 
(stx)                                                                           
                                
(syntax-case stx (GET HEAD POST PUT DELETE CONNECT OPTIONS TRACE 
PATH)                                                  [(_ route GET 
my-content-type)                                                                
                         
(string-contains? (identifier-name->string route) 
"abc")                                                              
(println "abc is in the identifier name")])))
; readline-input:19:52: route: pattern variable cannot be used outside of a
;   template
;   in: route
; [,bt for context]
~~~~~

I have also tried loads of other stuff, but I cannot find a way to:

1. get the identifier name of route, whatever the user has as route (not a 
string yet!)
2. check inside the guard expression, whether the identifier name contains 
a certain substring
3. based on that substring call other macros to do the actual job of 
defining an API route

Can you help me writing this macro?
It would also be great, if the macro was portable, meaning that it is 
usable from any Scheme.

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/8b706c81-2587-4dc8-aaaa-a900813571f1%40googlegroups.com.

Reply via email to