Skip to content

Instantly share code, notes, and snippets.

@danking
Created May 17, 2012 22:45
Show Gist options
  • Select an option

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

Select an option

Save danking/2722107 to your computer and use it in GitHub Desktop.
(define-syntax (singleton-struct stx)
(syntax-case stx ()
((_ name others ...)
(let-syntax ((name? (syntax-append #'name #'?)))
#'(define-values
(name name?)
(let ()
(struct name () others ...)
(values (name) name?)))))))
(define-for-syntax (syntax-append s1 s2)
(quasisyntax
(unsyntax
(string->symbol
(string-append (symbol->string (syntax-e s1))
(symbol->string (syntax-e s2)))))))
@dvanhorn
Copy link

That occurrence of syntax-append is at phase 2: it's +1 for being on the rhs of a define-syntax and another +1 for being on the rhs of let-syntax. But define-for-syntax defines something at +1 of where it's located.

@dvanhorn
Copy link

This is probably closer to what you want, but you're still not going to correctly capture the predicate name:

(define-syntax (singleton-struct stx)
  (syntax-case stx ()
    ((_ name others ...)
     (with-syntax ((name? (syntax-append #'name #'?)))
       #'(define-values
           (name name?)
           (let ()
             (struct name () others ...)
             (values (name) name?)))))))

@danking
Copy link
Author

danking commented May 18, 2012

Thanks, I get burned by let-syntax every time.

I ended up using format-id.

(define-syntax (singleton-struct stx)
  (syntax-case stx ()
    ((_ name others ...)
     (with-syntax ((name? (format-id #'name "~a?" (syntax-e #'name))))
       #'(define-values
           (name name?)
           (let ()
             (struct name () others ...)
             (values (name) name?)))))))

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment