(define-syntax (make-info-proc x r t) ;; like list-ref but returns #f instead of failing ;; and returns original item on non-lists if idx == 0 ;; (list-ref-maybe '(mass a b c) 3) ==> c ;; (list-ref-maybe '(mass a b c) 4) ==> #f ;; (list-ref-maybe 'mass 0) ==> mass ;; (list-ref-maybe 'mass 2) ==> #f (define (list-ref-maybe lst idx) (if (list? lst) (and (> (length lst) idx) (list-ref lst idx)) (and (= idx 0) lst))) (let* ([spec (cadr x)] [getter-prefix (caddr x)] [setter-prefix (cadddr x)]) `(lambda (body) (list ,@(map (lambda (item) (let* ([field (list-ref-maybe item 0)] [get-conv (list-ref-maybe item 1)] [set-conv (list-ref-maybe item 2)] [getter (list-ref-maybe item 3)] [setter (list-ref-maybe item 4)] [getter-proc-name (or getter (string->symbol (conc getter-prefix field)))] [getter-proc-call (list getter-proc-name 'body)]) `(list (quote ,field) ;; call getter with body as parameter ,(if get-conv `(,get-conv ,getter-proc-call) getter-proc-call)))) spec)))))