2013-10-16 6 views
5

मुझे लगता है कि एक लिस्प फ़ंक्शन में पारित मान पैरामीटर के नाम से मेल खाने वाले उद्धरण को असाइन किए जाते हैं। हालांकि, मुझे आश्चर्य हुआ कि यह:लिस्प में संग्रहीत फ़ंक्शन पैरामीटर कैसे हैं?

(defun test (x) (print (eval 'x))) 
(test 5) 

काम नहीं करता है (चर एक्स एक्सबाउंड है)। तो यदि पैरामीटर फ़ंक्शन में प्रतीकों के रूप में संग्रहीत नहीं होते हैं, तो इस उदाहरण में एक्स वास्तव में क्या है? पैरामीटर नाम से मेल खाने वाले प्रतीक से पैरामीटर तक पहुंचने का कोई तरीका है?

अधिक संदर्भ:

defun slice (r1 c1 r2 c2 board) 
    (dolist (param '(r1 c1 r2 c2)) ;adjust for negative indices 
    (if (< (eval param) 0) 
     (set param (+ (length board) (eval param))))) 
     ;Body of function 

असल में, मैं उनके मूल्यों में से किसी को पहले चार मापदंडों के माध्यम से पुनरावृति और अगर वे < हैं एक समायोजन बनाना चाहते: मैं करना चाहते हैं क्या कुछ इस तरह है 0. बेशक, मैं एक पैरा कर सकता हूं और प्रत्येक पैरामीटर के लिए एक व्यक्तिगत रेखा रख सकता हूं, लेकिन विचार कर रहा हूं कि मैं चार पैरामीटर में से प्रत्येक के लिए एक ही चीज़ कर रहा हूं, यह क्लीनर लग रहा था। हालांकि, मुझे त्रुटि मिलती है कि परिवर्तनीय आर 1 अनबाउंड है।

+0

यह विशिष्ट दिया गया है:

एक तरह से दोहरा खुद एक मैक्रो होगा बचने के लिए। [एसबीसीएल] (http://www.sbcl.org/manual/index.html) विदेशी फंक्शन इंटरफेस अध्याय आदि में कुछ जानकारी दें। –

उत्तर

4

क्या पैरामीटर नाम से मेल खाने वाले प्रतीक से पैरामीटर तक पहुंचने का कोई तरीका है?

शब्दावली बाध्यकारी के लिए नहीं। सामान्य लिस्प एक समान नामित प्रतीक से एक व्याख्यात्मक चर का उपयोग करने का कोई तरीका नहीं देता है। आपको परिवर्तनीय विशेष घोषित करने की आवश्यकता होगी।

तो यदि पैरामीटर फ़ंक्शन में प्रतीकों के रूप में संग्रहीत नहीं होते हैं, तो इस उदाहरण में एक्स वास्तव में क्या है?

एक प्रोसेसर रजिस्टर? एक ढेर फ्रेम का एक हिस्सा?

गतिशील बंधन के साथ

:

CL-USER 40 > (defun foo (a b) 
       (declare (special a b)) 
       (dolist (v '(a b)) 
       (if (zerop (symbol-value v)) 
        (set v 10))) 
       (values a b)) 
FOO 

CL-USER 41 > (foo 1 0) 
1 
10 
+0

धन्यवाद, इसने मुझे घोषित करने के लिए केवल एक अतिरिक्त पंक्ति के साथ एक ही कोड का उपयोग करने की अनुमति दी विशेष – rcorre

+2

@murphyslaw के रूप में पैरामीटर सुनिश्चित करें कि आप एक परिवर्तनीय विशेष घोषित करने के अन्य संभावित परिणामों को समझते हैं। परिवर्तनीय गतिशील दायरे से बंधे होंगे जिसका अर्थ है, उदाहरण के लिए, '(चलो ((x 3)) (घोषित करें (विशेष एक्स)) (funcall (चलो ((x 4)) (घोषित करें (विशेष एक्स)) (लैम्ब्डा () x)))) ''3',' 4' नहीं लौटाएगा, भले ही' lambda' फ़ंक्शन बनाया गया हो 'x' '4' तक बाध्य है। –

+0

@ जोशुआ टेलर - सिर के लिए धन्यवाद, मुझे स्पष्ट रूप से इस पर कुछ और पढ़ने की ज़रूरत है। बस यह सुनिश्चित करने के लिए, पैरामीटर को विशेष रूप से घोषित करने के लिए फ़ंक्शन ब्लॉक के बाहर उस प्रतीक के लिए कोई प्रभाव नहीं होगा, सही? – rcorre

2

के रूप में रेनर बताया गया है, आप इसके नाम से शाब्दिक बहस मूल्य तक नहीं पहुँच सकता।

क्या आप के बजाय कर सकते हैं destructuring-bind के साथ एक साथ &rest तर्क का उपयोग करता है, तो आप चर भी चाहते हैं:

(defun slice (board &rest params) 
    (destructuring-bind (r1 c1 r2 c2) 
     (mapcar (lambda (param) ;adjust for negative indices 
       (if (minusp param) 
        (+ (length board) param) 
        param)) 
       params) 
    ... operate on r1 c1 r2 c2 ...)) 
5

मूल रूप से कैसे शाब्दिक बाध्यकारी काम करता है यही कारण है कि: चर नाम एक सीधा साथ शाब्दिक दायरे के भीतर बदल दिया जाता है संदर्भ जहां वैरिएबल का मान संग्रहीत किया जाता है। परिवर्तनीय नाम के बाध्यकारी symbol-value केवल गतिशील चर के लिए किया जाता है जिसे आप special के साथ घोषित कर सकते हैं।

(defmacro with-adjusting ((&rest vars) adjust-value &body body) 
    `(let ,(loop for var in vars 
       collect `(,var (if (minusp ,var) 
           (+ ,var ,adjust-value) 
           ,var))) 
    ,@body)) 

(defun slice (r1 c1 r2 c2 board) 
    (with-adjusting (r1 c1 r2 c2) (length board) 
    ;; function body 
+1

यह एक अच्छा जवाब है। एक मैक्रो यहाँ काफी उपयोगी है। छोटी कमी: संकलित कोड बड़ा हो जाता है। –

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