phone-numbers macro. There are two ways I am aware ofphone-numbers to deal with add-prefix directly.local-expand in phone-numbers to partially expand macros in the body of phone-numbers. In this case, this is to partially expand add-prefix to something that phone-numbers can recognize and deal with.add-prefix is weird. It doesn’t expand to the compile-time macro number. Instead, it expands to a runtime function application (to construct a list of lists) and perform the string-append at runtime. This means it would be really hard for phone-numbers to process the partially expanded syntax if you were to use approach 1.2. Are you sure that this behavior of add-prefix is what you want?Here’s my attempt to solve this problem, while trying to maintain the external behavior you described.
#lang racket
(require (for-syntax syntax/parse))
;; number macro is needed so that "bare" add-prefix works correctly
(define-syntax (number stx)
(syntax-parse stx
[(_ x:string) #'(list 'number x)]))
(number "123") ; ==> '(number "123")
;; - if the immediate macro is `number`, don't partially expand it, because
;; `phone-numbers` know how to deal with it already. Note that
;; the result attribute should be of ellipsis depth 1, so we need to do
;; some normalization here.
;;
;; - otherwise, partially expand the immediate macro. The protocol is that
;; the immediate macro should expand to (list (number xxx) ...).
;; We then extract the result from it.
(begin-for-syntax
(define-syntax-class do-expand
#:attributes ([result 1])
(pattern ({~literal number} _)
#:with (result ...) (list this-syntax))
(pattern _
#:with ({~literal list} result ...)
(local-expand this-syntax 'expression #f))))
(define-syntax (phone-numbers stx)
(syntax-parse stx
[(_ :do-expand ...)
(syntax-parse #'((~@ result ...) ...)
[(((~literal number) phone) ...)
#'(list phone ...)])]))
(phone-numbers
(number "1212")
(number "2121")) ; ==> '("1212" "2121")
;; add-prefix computes at compile-time. It abides the protocol described above.
(define-syntax (add-prefix stx)
(syntax-parse stx
[(_ prefix ((~literal number) str) ...)
#:with (prefixed ...) (map (λ (s)
(datum->syntax
this-syntax
(string-append (syntax-e #'prefix)
(syntax-e s))))
(attribute str))
#'(list (number prefixed) ...)]))
(add-prefix "555"
(number "1212")
(number "2121")) ; ==> '((number "5551212") (number "5552121"))
;; add-suffix computes at compile-time. It abides the protocol described above.
(define-syntax (add-suffix stx)
(syntax-parse stx
[(_ prefix ((~literal number) str) ...)
#:with (suffixed ...) (map (λ (s)
(datum->syntax
this-syntax
(string-append (syntax-e s)
(syntax-e #'prefix))))
(attribute str))
#'(list (number suffixed) ...)]))
(add-suffix "555"
(number "1212")
(number "2121")) ; ==> '((number "1212555") (number "2121555"))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(phone-numbers
(add-prefix "555"
(number "1212")
(number "2121"))
(number "1234"))
;; similar to typing
(phone-numbers
(list (number "5551212") (number "5552121"))
(number "1234"))
;; ==> '("5551212" "5552121" "1234")
--
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...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/racket-users/e6e5a407-7547-44f1-b8c2-bbe7906ed6f5%40googlegroups.com.
I appreciate all of the Racket documentation, but I think there is a need for a much better presentation of the material in a graduated way.
you seem to have an excellent grasp of macros.
How did you acquire your knowledge of macros?
--
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...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/racket-users/0a39a0c4-bde5-4207-9abd-63b9d1ceec07%40googlegroups.com.