[racket-users] Macro help

53 views
Skip to first unread message

Kevin Forchione

unread,
May 24, 2019, 12:41:20 AM5/24/19
to Racket Users
Hi guys,
I’ve been wracking my brains all day trying to come up with a macro that would convert this syntax:

;; (aux a (b (* 2 pi)) c (d pi))
;; => (define-values (a b c d) (values #f 6.28318530717958 #f 3.141592653589793)


I’m missing some part of the picture. The closest I’ve come is to create a list of the pairs:

#lang racket

(define-syntax (aux stx)
(syntax-case stx ()
[(_ (var val)) #'`((var ,val))]
[(_ var) #''((var #f))]
[(_ (var0 val0) var1 ...) #'(append `((var0 ,val0)) (aux var1 ...))]
[(_ var0 var1 ...) #'(append '((var0 #f)) (aux var1 ...))]))

(aux a (b (* 2 pi)) c (d pi)) ;=> '((a #f) (b 6.283185307179586) (c #f) (d 3.141592653589793))


Any help is greatly appreciated!

Kevin

Michael Murdock MacLeod

unread,
May 24, 2019, 12:52:18 AM5/24/19
to racket...@googlegroups.com
Does this work? It uses a helper function, `prune`, to parse the var-val
clauses.

#lang racket

(define-for-syntax (prune stx)
(syntax-case stx ()
[()
#'()]
[((var val) others ...)
(cons #'(var val)
(prune #'(others ...)))]
[(var others ...)
(cons #'(var #f)
(prune #'(others ...)))]))

(define-syntax (aux stx)
(syntax-case stx ()
[(_ terms ...)
(with-syntax ([((var val) ...) (prune #'(terms ...))])
#'(define-values (var ...) (values val ...)))]))

(aux a (b (* 2 pi)) c (d pi))
a
b
c
d

;; output shown below

#f
6.283185307179586
#f
3.141592653589793

Matthias Felleisen

unread,
May 24, 2019, 9:33:35 AM5/24/19
to Michael Murdock MacLeod, lys...@gmail.com, racket...@googlegroups.com

Let me propose the use of syntax-parse as an alternative here. I think it clarifies the purpose of the maco. — Matthias


#lang racket

(require (for-syntax syntax/parse))

#; (aux a (b (* 2 pi)) c (d pi))
;; =>
#; (define-values (a b c d) (values #f 6.28318530717958 #f 3.141592653589793))


(begin-for-syntax
  (define-syntax-class optionally-initiliazed
    (pattern (lhs:id rhs:expr))
    (pattern lhs:id #:attr rhs #'#f)))

(define-syntax (aux stx)
  (syntax-parse stx
    [(_ p:optionally-initiliazed ...) #'(define-values (p.lhs ...) (values p.rhs ...))]))

(aux a (b (* 2 pi)) c (d pi))
--
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/2893163.LJ05K77S5N%40alphtsr.
For more options, visit https://groups.google.com/d/optout.

Stephen Chang

unread,
May 24, 2019, 10:35:19 AM5/24/19
to Matthias Felleisen, Michael Murdock MacLeod, lys...@gmail.com, Racket-Users List
If `define-values` is not strictly required, here's a more
syntax-case-y recursive version:

(define-syntax (aux stx)
(syntax-case stx ()
[(_) #'(begin)]
[(_ (var val) . rst)
(identifier? #'var)
#'(begin
(define var val)
(aux . rst))]
[(_ var . rst)
(identifier? #'var)
#'(begin
(define var #f)
(aux . rst))]))
> To view this discussion on the web visit https://groups.google.com/d/msgid/racket-users/A0B65B5E-0244-4E7C-89E5-24ED2CDF69EB%40felleisen.org.

Kevin Forchione

unread,
May 24, 2019, 3:58:08 PM5/24/19
to Stephen Chang, Matthias Felleisen, Michael Murdock MacLeod, Racket-Users List
Wow! Thanks so much guys. Each of these solutions adds another brick to the wall of my macro eduction!

Kevin

yfzhe

unread,
May 25, 2019, 4:35:24 AM5/25/19
to Racket Users
Another "syntax-case-y" version generates `define-values`:

(define-syntax-rule (aux clause ...)
  (aux-helper () (clause ...)))

(define-syntax (aux-helper stx)
  (syntax-case stx ()
    [(_ ([id val] ...) ())
     #'(define-values (id ...) (values val ...))]
    [(_ (id+val ...) ([id val] more ...))
     (identifier? #'id)
     #'(aux-helper (id+val ... [id val]) (more ...))]
    [(_ (id+val ...) (id more ...))
     (identifier? #'id)
     #'(aux-helper (id+val ... [id #f]) (more ...))]))


在 2019年5月24日星期五 UTC+8下午12:41:20,lysseus写道:
Reply all
Reply to author
Forward
0 new messages