2010-05-23 7 views
8

मैं एक मैक्रो लिखने की कोशिश कर रहा हूं जो संबंधित कार्यों के साथ डेटा संरचना के एक विशेष वर्ग को परिभाषित करता है।रैकेट मैक्रोज़ का उपयोग करके मैं फ़ंक्शन कैसे परिभाषित करूं?

मुझे पता है कि यह संभव है; यह कोर भाषा में कई बार किया जाता है।

एक विशिष्ट उदाहरण के रूप में, मैं योजना में define-struct मैक्रो को कैसे परिभाषित करूंगा। इसे make-struct, struct-<<field>>, आदि कार्यों को बनाने की आवश्यकता है।

मैंने define का उपयोग करके ऐसा करने का प्रयास किया, हालांकि, यह केवल मैक्रो के लेक्सिकल स्कोप में फ़ंक्शन को परिभाषित करता है।

मैं वास्तव में मैक्रो में एक फ़ंक्शन कैसे परिभाषित कर सकता हूं?

+1

http://www.scheme.com/tspl4/ example.html #।/उदाहरण: एच 8 – grettke

उत्तर

16

उत्तर के लिए कुंजी datum->syntax है। मूल विचार यह है कि आप कुछ यादृच्छिक डेटा लेना चाहते हैं और इसे वाक्यविन्यास में बदलना चाहते हैं - इस मामले में, प्रतीक को पहचानकर्ता में बदल दें। एक पहचानकर्ता मूल रूप से कुछ व्याख्यात्मक जानकारी के साथ एक प्रतीक है जो (बहुत मोटे तौर पर) इंगित करता है कि यह कैसे बाध्य है। datum->syntax का उपयोग करके आप बिल्कुल ऐसा कर सकते हैं: यह सिंटैक्स के मौजूदा टुकड़े की अपेक्षा करता है, जहां यह बाध्यकारी प्रतिलिपि बनाता है, और एक डाटाम (यहां एक प्रतीक) जो वाक्यविन्यास रैपर में मौजूद मान है।

यहाँ एक उदाहरण है कि इस का उपयोग कर एक define-struct तरह उपकरण दर्शाता है:

#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))))) 
      ...)))])) 

और यहाँ यह का उपयोग करने का एक उदाहरण है:

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

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