2010-05-23 12 views
8

Ich versuche, ein Makro zu schreiben, das eine spezielle Klasse von Datenstruktur mit zugeordneten Funktionen definiert.Wie definiere ich Funktionen mit Racket-Makros?

Ich weiß, das ist möglich; Es wird mehrmals in der Kernsprache selbst gemacht.

Als ein spezifisches Beispiel, wie würde ich das define-struct Makro in Scheme selbst definieren. Es muss make-struct, struct-<<field>> usw. Funktionen erstellen.

Ich habe versucht, dies mit zu tun, dies definiert jedoch nur die Funktion in den lexikalischen Bereich des Makros.

Wie kann ich tatsächlich eine Funktion in einem Makro definieren?

+1

http://www.scheme.com/tspl4/: es verwendet

#lang scheme ;; implements a defstruct-like macro that uses association lists (define-syntax (defstruct-lite stx) (syntax-case stx() [(defstruct-lite name field ...) (let ([make-id (lambda (template . ids) (let ([str (apply format template (map syntax->datum ids))]) (datum->syntax stx (string->symbol str))))]) (with-syntax ([make-name (make-id "make-~a" #'name)] [name? (make-id "~a?" #'name)] [(arg ...) (generate-temporaries #'(field ...))] [(name-field ...) (map (lambda (f) (make-id "~a-~a" #'name f)) (syntax->list #'(field ...)))]) #'(begin (define (make-name arg ...) (list 'name (cons 'field arg) ...)) (define (name? x) (and (pair? x) (eq? 'name (car x)))) (define (name-field x) (and (name? x) (cdr (assq 'field (cdr x))))) ...)))])) 

Und hier ist ein Beispiel examples.html #./Beispiele: h8 – grettke

Antwort

16

Der Schlüssel für eine Antwort ist datum->syntax. Die Grundidee ist, dass Sie einige zufällige Daten nehmen und in eine Syntax umwandeln möchten - in diesem Fall verwandeln Sie ein Symbol in einen Bezeichner. Ein Bezeichner ist im Grunde ein Symbol mit einigen lexikalischen Informationen, die (sehr grob) angeben, wie es gebunden ist. Mit datum->syntax können Sie genau das tun: Es erwartet eine vorhandene Syntax, aus der die Bindung kopiert wird, und ein Datum (ein Symbol hier), das den Wert enthält, der im Syntax-Wrapper enthalten ist.

Hier ist ein Beispiel, das ein define-struct -ähnliche Tool mit dieser zeigt:

(defstruct-lite point x y) 
(point-y (make-point 1 2)) 
+0

http://www.scheme.com/tspl4/examples.html#./examples:h8 – grettke