defstruct
( define-macro defstruct (lambda (x . ff) ( (let ( (i -1) (j -1) (struct-name (symbol->string x)) (keys (map (lambda (x) (if (pair? x) (car x) (x))) ff))) ( `( (define ,(string->symbol (string-append 'mark-' struct-name)) (lambda (,@keys) ( (cons (vector 'struct' ,struct-name) (vector ,@keys))))) (define ,(string->symbol (string-append 'verify-struct-' struct-name)) (lambda (o) ( (if (not (and (eqv? 'struct' (vector-ref (car o) 0)) (eqv? ,struct-name (vector-ref (car o) 1)) )) (error ,(string-append 'not-struct ' struct-name)))))) ,@(map (lambda (n) ( (set! i (+ i 1)) ( `(define ,(string->symbol (string-append struct-name '.' (symbol->string n))) (lambda (o) ( (,(string->symbol (string-append 'verify-struct-' struct-name)) o) (vector-ref (cdr o) ,i) ))) ) )) keys) ,@(map (lambda (n) ( (set! j (+ j 1)) ( `(define ,(string->symbol (string-append struct-name '.' (symbol->string n) '-set!')) (lambda (o v) ( (,(string->symbol (string-append 'verify-struct-' struct-name)) o) (vector-set! (cdr o) ,j v) ))) ) )) keys) ))))))
应用
( (defstruct box (name width height size)) (define x (mark-box 'name' 2 3 5)) (display (box.width x)) (newline) (box.width-set! x 15) (display (box.width x)))=> 2=> 15
目前还暂不反对初始化操作 如这种模式:
(defstruct box (name width height(size 5)))