2011-10-12 20 views
8

मैं एमआईटी योजना में इस तुच्छ (कॉमन लिस्प में) मैक्रो के बराबर बनाने के लिए कोशिश कर रहा द्वारा विस्मित कर रहा हूँ:लैम्बडा फॉर्म लौटने के लिए आप एमआईटी स्कीम मैक्रो कैसे लिखते हैं?

(defmacro funcify (exp) 
    `(lambda (x) ,exp)) 

यह एक सरल व्यक्तिगत परियोजना के लिए, एक संख्यात्मक समीकरण solver में बनाया कार्यों के आधार पर दूसरा एसआईसीपी व्याख्यान। मुझे परवाह नहीं है कि यह मैक्रो "सुरक्षित" या "स्वच्छ" नहीं है या यदि एक्स एक्स के अलावा किसी भी प्रतीक का संदर्भ देता है तो एक चर को कैप्चर करेगा। मैं

(solv '(* 60 x) '(* 90 (- x 1))) 

लिखने में सक्षम होना चाहते हैं जहां solv है:

(define (solv lh-exp rh-exp) 
    (solve (funcify lh-exp) (funcify rh-exp))) 
बजाय टाइप करने के लिए

(solve (lambda (x) (* 60 x)) (lambda (x) (* 90 (- x 1)))) 

होने लेकिन यह कैसे का उपयोग कर ऐसा करने के लिए को समझ नहीं सकता की

एमआईटी योजना वाक्यविन्यास-नियम।

मैं इस की कोशिश की है, लेकिन यह काम नहीं करता है:

(define-syntax funcify 
    (syntax-rules() 
    ((funcify y) (lambda (x) y)))) 
;Value: funcify 

(funcify x) 
;Value 17: #[compound-procedure 17] 

((funcify x) 10) 
;Unbound variable: x 

मैं शायद eval शामिल लेकिन कोई लाभ नहीं हुआ उल्लेख के लायक नहीं अन्य बातों की कोशिश की है।

इसके अलावा, योजना के मैक्रो सिस्टम पर अच्छे ट्यूटोरियल (संदर्भ नहीं) के संदर्भ जो छोटे सरल उदाहरणों के साथ शुरू होते हैं और पर्याप्त टिप्पणी के साथ निर्माण करते हैं, और विशेष रूप से बैकक्वोट-कॉमा शैली LISP मैक्रोज़ को परिवर्तित करने के तरीके को दिखाते हैं (जो मेरे लिए है बेहद सहज) योजना के सिंटैक्स मैक्रो सिस्टम के लिए बहुत अच्छा होगा।

उत्तर

4

आप explicit-renaming macros का उपयोग करके defmacro साथ के रूप में एक ही बात मूल रूप से कर सकते हैं । एकमात्र महत्वपूर्ण अंतर यह है कि आपको इनपुट फॉर्म को स्वयं को नष्ट करना होगा:

(define-syntax funcify 
    (er-macro-transformer 
    (lambda (form rename cmp) 
     (let ((exp (cadr form))) 
     `(,(rename 'lambda) (x) ,exp))))) 
+0

ईआर कार्यान्वयन के लिए +1 (जो एमआईटी योजना का समर्थन करता है)। :-) –

+1

@ क्रिसजेस्टर-यंग बग फिक्स के लिए धन्यवाद। :) –

+0

+1। बहुत बहुत धन्यवाद। परिभाषित-वाक्यविन्यास पूरी तरह से परेशान है लेकिन मुझे संदेह है कि यह बहुत शक्तिशाली है, मैं इसे बेहतर सीखना चाहता हूं, इस पर गति देने के लिए कोई संदर्भ? मैं आपका जवाब स्वीकार कर रहा हूं क्योंकि यह एमआईटी योजना में काम करता है कि एक मज़ेदारता देता है, मेरी इच्छा है कि मैं क्रिस के जवाब को भी स्वीकार कर सकता हूं क्योंकि यह भी बताता है कि सोलव एक सिंटैक्स-नियम मैक्रो भी होना चाहिए। – Bogatyr

7

यह syntax-rules में नहीं किया जा सकता है। कहानी का अंत।

आउटपुट अभिव्यक्ति में एक मनमानी पहचानकर्ता (x, आपके मामले में) इंजेक्शन करने के लिए स्वच्छता को तोड़ने की आवश्यकता होती है, और syntax-rules स्वच्छता तोड़ने का कोई साधन नहीं प्रदान करता है। ऐसा करने के लिए आपको निम्न-स्तरीय मैक्रो सिस्टम का उपयोग करने की आवश्यकता होगी। एमआईटी योजना स्पष्ट नाम (मथायस Benkard के जवाब देखें) का उपयोग करता है, लेकिन अन्य योजना कार्यान्वयन कि syntax-case का उपयोग के लिए, आप इसे इस प्रकार कर सकते हैं:

(define-syntax funcify 
    (lambda (stx) 
    (syntax-case stx() 
     ((_ body) 
     (with-syntax ((x (datum->syntax stx 'x))) 
     #'(lambda (x) 
      body)))))) 

कुंजी (datum->syntax stx 'x) सा है, जो प्रतीक x इंजेक्शन के रूप में अगर यह थे funcify आमंत्रण के वाक्य रचनात्मक संदर्भ में।

वैसे, अपने solv को भी मैक्रो, नहीं एक प्रक्रिया होना चाहिए, लेकिन कम से कम यह हो सकता है एक syntax-rules मैक्रो:

(define-syntax solv 
    (syntax-rules() 
    ((_ lhs rhs) (solve (funcify lhs) (funcify rhs))))) 
+0

+1 आपके उत्तर के लिए बहुत बहुत धन्यवाद, और यह इंगित करने के लिए कि सॉल्व भी एक मैक्रो होना चाहिए। मैक्रोज़ शुरू करने के लिए मुश्किल हैं, लेकिन स्कीम सिंटैक्स- * मैक्रोज़ शायद सबसे कठिन चीज है जिसे मैंने अब तक एक भाषा में देखा है, और मैं प्रोग्रामिंग कर रहा हूं (ज्यादातर ब्लब्स, लेकिन मैंने सीएल में एमएस थीसिस किया था) 30+ वर्षों। – Bogatyr

+0

@ बोगेटिर: जब तक आप निरंतरता तक न आएं तब तक प्रतीक्षा करें। ;-) (गंभीरता से, हालांकि, योजना एक बहुत बड़ी भाषा है, अवधारणात्मक रूप से, इसके बावजूद कि R5RS spec "50 पृष्ठों" के भीतर फिट बैठता है।) –

संबंधित मुद्दे