Skip to content

Instantly share code, notes, and snippets.

@danking
Created May 19, 2012 01:30
Show Gist options
  • Select an option

  • Save danking/2728497 to your computer and use it in GitHub Desktop.

Select an option

Save danking/2728497 to your computer and use it in GitHub Desktop.
A hack to get multiple auto-values
#lang racket
(require (for-syntax racket racket/syntax))
(provide (all-defined-out))
(define-syntax (struct* stx)
(syntax-case stx ()
((_ name (args ...) others ...)
(with-syntax (((arg-list ...) (build-arg-list #'(args ...) (get-autos #'(others ...))))
((others ...) (remove-autos #'(others ...)))
(real-constructor (format-id #'name "make-~a" #'name)))
#'(begin (struct name (args ...) #:constructor-name constructor others ...)
(define (real-constructor arg-list ...)
(constructor args ...)))))))
(begin-for-syntax
(define (get-autos ls)
(define (collect-autos ls)
(match ls
('() '())
(`(#:auto-value ,var ,val . ,others)
(cons (list var val)
(collect-autos others)))
((cons something others) (collect-autos others))))
(for/hash ((pair (collect-autos (syntax->datum ls))))
(values (first pair) (second pair))))
(define (remove-autos ls)
(define (remove-autos ls)
(match ls
('() '())
(`(#:auto-value ,var ,val . ,others)
(remove-autos others))
((cons something others) (cons something (remove-autos others)))))
(datum->syntax ls (remove-autos (syntax->datum ls))))
(define (build-arg-list args avs)
(datum->syntax args
(for/list ((arg (syntax->list args)))
(if (hash-has-key? avs (syntax-e arg))
(list arg (hash-ref avs (syntax-e arg)))
arg)))))
(struct* posn (x y z) #:transparent #:auto-value y 2 #:auto-value z 4)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment