Re: [racket-users] Splicing the result of one macro into another

2019-08-21 Thread Sorawee Porncharoenwase
>
> 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.
>>
>
I think what you are saying is, there should be more Racket Guide content,
and I think everyone agrees on that...


> you seem to have an excellent grasp of macros.
>

Well, not really. There are a lot of stuff I don't know!


> How did you acquire your knowledge of macros?
>

Mostly from reading tutorials and public code:
- https://www.greghendershott.com/fear-of-macros/
- https://www.hashcollision.org/brainfudge/
- https://docs.racket-lang.org/guide/macros.html
- https://docs.racket-lang.org/syntax/stxparse.html
- https://beautifulracket.com
- https://docs.racket-lang.org/syntax-parse-example/

I also attended Racket School in 2017, though as I understand the topic of
macro was focused less compared to later years -- if you attended Racket
school in recent years, you probably got the knowledge more than I did.

For more advanced topics, I learned a lot from Alexis's blog posts (
https://lexi-lambda.github.io). Ultimately there are papers and reports
like http://www.cs.utah.edu/plt/scope-sets/ which is a lot harder to read
but would be rewarding once you understand it.

Mailing list and Slack are very helpful to me, but the answers are very
easy to get lost (including this very thread, perhaps).

> --
> 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/0a39a0c4-bde5-4207-9abd-63b9d1ceec07%40googlegroups.com
> 
> .
>

-- 
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/CADcuegst8MGdZ7LbF1a%3DEppZ5kTaKcnwibfRXTb7Od6cKqfmRA%40mail.gmail.com.


Re: [racket-users] Splicing the result of one macro into another

2019-08-20 Thread Brian Adkins
On Tuesday, August 20, 2019 at 9:11:54 PM UTC-4, Brian Adkins wrote:
>
> On Tuesday, August 20, 2019 at 8:43:07 PM UTC-4, Sorawee Porncharoenwase 
> wrote:
>>
>>
>>1. You will need a cooperation of phone-numbers macro. There are two 
>>ways I am aware of
>>1.1 You could hard code in phone-numbers to deal with add-prefix 
>>directly.
>>1.2 A more general approach is to use 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. 
>>2. The macro 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")
>>
>>
> Thanks. 
>
> The reason the add-prefix macro is weird is because I have no idea what 
> I'm doing with respect to macros, so I'm currently grasping at straws and 
> experimenting :) 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. Racket School was great, but we jumped into the deep end 
> pretty quickly, and the techniques seem "hacky" with odd idiosyncrasies and 
> clever tricks vs. proceeding from a solid foundation and building upon that.
>
> I'm kind of wondering if it wouldn't be easier to just process the syntax 
> object directly - at 

Re: [racket-users] Splicing the result of one macro into another

2019-08-20 Thread Brian Adkins
On Tuesday, August 20, 2019 at 8:43:07 PM UTC-4, Sorawee Porncharoenwase 
wrote:
>
>
>1. You will need a cooperation of phone-numbers macro. There are two 
>ways I am aware of
>1.1 You could hard code in phone-numbers to deal with add-prefix 
>directly.
>1.2 A more general approach is to use 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. 
>2. The macro 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")
>
>
Thanks. 

The reason the add-prefix macro is weird is because I have no idea what I'm 
doing with respect to macros, so I'm currently grasping at straws and 
experimenting :) 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. Racket School was great, but we jumped into the deep end 
pretty quickly, and the techniques seem "hacky" with odd idiosyncrasies and 
clever tricks vs. proceeding from a solid foundation and building upon that.

I'm kind of wondering if it wouldn't be easier to just process the syntax 
object directly - at least then, I'd be in a realm I'm very familiar with.

I'll review the code you've provided.

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe 

Re: [racket-users] Splicing the result of one macro into another

2019-08-20 Thread Ben Greenman
On 8/20/19, Brian Adkins  wrote:
> Consider the following two macros:
>
> (require (for-syntax syntax/parse))
>
> (define-syntax (phone-numbers stx)
>   (syntax-parse stx
> [(_ ((~literal number) phone) ...)
>  #'(list phone ...)]))
>
> (define x (phone-numbers
>(number "1212")
>(number "2121"))) ; ==> '("1212" "2121")
>
> (define-syntax (add-prefix stx)
>   (syntax-parse stx
> [(_ prefix ((~literal number) str) ...)
>  #'(list (list 'number (string-append prefix str)) ...)]))
>
> (define y (add-prefix "555"
>   (number "1212")
>   (number "2121"))) ; ==> '((number "5551212") (number
> "5552121"))
>
> I would like to be able to do the following:
>
> (phone-numbers
>  (add-prefix "555"
>  (number "1212")
>  (number "2121"))
>  (number "1234")) ; ==> '("5551212" "5552121" "1234")
>
> I was hoping it would be possible to do this without modifying the
> phone-numbers macro. In other words, to have the result of expanding
> add-prefix macro call be:
>
> (number "5551212") (number "5552121")
>
> So that it would appear to the phone-numbers macro as if the user had
> actually typed:
>
> (phone-numbers
>   (number "5551212")
>   (number "5552121")
>   (number "1234"))
>
> Is it possible to do this w/o the explicit cooperation of the phone-numbers
>
> macro?

If you have a list at expansion time, you can splice it into a syntax
object. It's not straightforward to get a list from `add-prefix` but
here is one way:

(define-syntax (do-it stx)
  #`(phone-numbers
  #,@(eval
   (local-expand
 #'(add-prefix "555"
 (number "1212")
 (number "2121")) 'expression '())
   (make-base-namespace))
  (number "1234")))

(do-it)
; ==> '("5551212" "5552121" "1234")

I hope this helps you find something better.

-- 
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/CAFUu9R56P4-c7GczN%2B-9Q9YeGxyuTskwtViZude35EhLe4XkBA%40mail.gmail.com.


Re: [racket-users] Splicing the result of one macro into another

2019-08-20 Thread Sorawee Porncharoenwase
   1. You will need a cooperation of phone-numbers macro. There are two
   ways I am aware of
   1.1 You could hard code in phone-numbers to deal with add-prefix
   directly.
   1.2 A more general approach is to use 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.
   2. The macro 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")



On Tue, Aug 20, 2019 at 3:13 PM Brian Adkins  wrote:

> Consider the following two macros:
>
> (require (for-syntax syntax/parse))
>
> (define-syntax (phone-numbers stx)
>   (syntax-parse stx
> [(_ ((~literal number) phone) ...)
>  #'(list phone ...)]))
>
> (define x (phone-numbers
>(number "1212")
>(number "2121"))) ; ==> '("1212" "2121")
>
> (define-syntax (add-prefix stx)
>   (syntax-parse stx
> [(_ prefix ((~literal number) str) ...)
>  #'(list (list 'number (string-append prefix str)) ...)]))
>
> (define y (add-prefix "555"
>   (number "1212")
>   (number "2121"))) ; ==> '((number "5551212") (number
> "5552121"))
>
> I would like to be able to do the following:
>
> (phone-numbers
>  (add-prefix "555"
>  (number "1212")
>  (number "2121"))
>  (number "1234")) ; ==> '("5551212" "5552121" "1234")
>
> I was hoping it would be possible to do this without modifying the
> phone-numbers macro. In other words, to have the result of expanding
> add-prefix macro call be:
>
> (number "5551212") (number "5552121")
>
> So that it would 

[racket-users] Splicing the result of one macro into another

2019-08-20 Thread Brian Adkins
Consider the following two macros:

(require (for-syntax syntax/parse))

(define-syntax (phone-numbers stx)
  (syntax-parse stx
[(_ ((~literal number) phone) ...)
 #'(list phone ...)]))

(define x (phone-numbers
   (number "1212")
   (number "2121"))) ; ==> '("1212" "2121")

(define-syntax (add-prefix stx)
  (syntax-parse stx
[(_ prefix ((~literal number) str) ...)
 #'(list (list 'number (string-append prefix str)) ...)]))

(define y (add-prefix "555"
  (number "1212")
  (number "2121"))) ; ==> '((number "5551212") (number 
"5552121"))

I would like to be able to do the following:

(phone-numbers
 (add-prefix "555"
 (number "1212")
 (number "2121"))
 (number "1234")) ; ==> '("5551212" "5552121" "1234")

I was hoping it would be possible to do this without modifying the 
phone-numbers macro. In other words, to have the result of expanding 
add-prefix macro call be:

(number "5551212") (number "5552121")

So that it would appear to the phone-numbers macro as if the user had 
actually typed:

(phone-numbers
  (number "5551212")
  (number "5552121")
  (number "1234"))

Is it possible to do this w/o the explicit cooperation of the phone-numbers 
macro?

Brian Adkins

-- 
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/e6e5a407-7547-44f1-b8c2-bbe7906ed6f5%40googlegroups.com.