Skip to content

Instantly share code, notes, and snippets.

@bdionne
Created June 27, 2013 18:10
Show Gist options
  • Save bdionne/5878859 to your computer and use it in GitHub Desktop.
Save bdionne/5878859 to your computer and use it in GitHub Desktop.
(define-macro (define-record/keywords name-form . slots)
(let* ((name (if (pair? name-form) (car name-form) name-form))
(printer (and (pair? name-form) (cadr name-form)))
(slot-names (map (lambda (slot) (if (pair? slot) (car slot) slot))
slots))
(stem (trim-brackets name)))
`(begin
(define ,name (make-record-type ,(symbol->string name) ',slot-names
,@(if printer (list printer) '())))
(define ,(symbol-append 'make- stem)
(let ((slots (list ,@(map (lambda (slot)
(if (pair? slot)
`(cons ',(car slot) ,(cadr slot))
`',slot))
slots)))
(constructor (record-constructor ,name)))
(lambda args
(apply constructor (%compute-initargs args slots)))))
(define ,(symbol-append stem '?) (record-predicate ,name))
,@(map (lambda (sname)
`(define ,(symbol-append stem '- sname)
(make-procedure-with-setter
(record-accessor ,name ',sname)
(record-modifier ,name ',sname))))
slot-names))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment