> On Dec 29, 2017, at 3:31 PM, Robert Girault <rfrancoisgira...@gmail.com 
> <mailto:rfrancoisgira...@gmail.com>> wrote:
> 
> (define-macro (prelude/connect-to HOST PORT)
>   #'(begin
>       (require racket/tcp)
>       (require racket/port)
>       (define-values (input-port output-port)
>         (tcp-connect HOST PORT))))
> 
> This doesn't work because I get the error message
> 
>   www.google.com <http://www.google.com/>: unbound identifier in module in: 
> www.google.com <http://www.google.com/>
> 
> This must be because www.google.com <http://www.google.com/> is not a string. 
>  I don't know how to turn into a string and this must mean I'm very confused. 
>  What should my macro do so I'd get the desired expansion?

The issue is that when `read-syntax` encounters

www.google.com

in your source, it treats it as an identifier, not a literal string. (This 
identifier hasn't been defined, hence the "unbound identifier" error.) 

But you want it to behave as a string, so you can pass it to `tcp-connect`. So 
you have two choices. 

1) You can fix the problem in your source, by instead writing 

"www.google.com"

which will cause `read-syntax` to treat it as a literal string, rather than an 
identifier.

2) You can fix the problem in your macro, by converting the would-be identifier 
to a string in the output of the macro:

(define-macro (prelude/connect-to HOST PORT)
  #'(begin
      (require racket/tcp)
      (require racket/port)
      (define-values (input-port output-port)
        (tcp-connect (symbol->string 'HOST) PORT))))


The notation 'HOST rather than HOST makes the identifier into a symbol, and 
then `symbol->string` finishes the job. 

If you like to be lenient with input, you could also do this, which will work 
with either www.google.com or "www.google.com":

(define-macro (prelude/connect-to HOST PORT)
  #'(begin
      (require racket/tcp)
      (require racket/port)
      (define-values (input-port output-port)
        (tcp-connect (format "~a" 'HOST) PORT))))



> On Dec 29, 2017, at 7:31 AM, Matthias Felleisen <matth...@ccs.neu.edu> wrote:
> 
> I prefer to teach syntax transformers using define-syntax and syntax-parse so 
> that you can say 
> 
>  (define-syntax (prelude/connect-to stx)
>     (syntax-parse stx 
>       [(_ HOST:str PORT:nat) #’(  . . HOST . . PORT ..)])) 
> 
> That way misuses of a ‘macro’ are caught immediately and you get sensible 
> error messages. 
> 
> [I just went thru this with freshmen in the spare weeks after Thanksgiving 
> and it worked like a charm.
> I don’t understand the appeal of define-macro.]


The `define-macro` used in the `br/quicklang` language is not the same as the 
one in Racket's "legacy macro" library. [1] Rather, it's a simplified version 
of `syntax-parse`. [2] 


[1] 
https://docs.racket-lang.org/compatibility/defmacro.html?q=define-macro#%28form._%28%28lib._compatibility%2Fdefmacro..rkt%29._define-macro%29%29
 
<https://docs.racket-lang.org/compatibility/defmacro.html?q=define-macro#(form._((lib._compatibility/defmacro..rkt)._define-macro))>

[2] 
https://beautifulracket.com/appendix/from-br-to-racket-base.html#macro-definitions
 
<https://beautifulracket.com/appendix/from-br-to-racket-base.html#macro-definitions>


-- 
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.
For more options, visit https://groups.google.com/d/optout.

Reply via email to