2012-06-26 26 views
18

मैं, कैसे defun मैक्रो काम करता है के बारे में उलझन में हूँ क्योंकिक्यों defun समान नहीं है (setq <name><lambda>)?

(defun x() "hello") 

समारोह एक्स निर्माण करेंगे, लेकिन प्रतीक अभी भी x अनबाउंड हो जाएगा।

अगर मैं एक्स के लिए कुछ लैम्ब्डा बाध्य होगी और फिर एक्स एक मूल्य होगा, लेकिन यह इस तरह के रूप में समारोह के रूप में दुभाषिया द्वारा नहीं माना जाएगा:

(x) 

मुझे लगता है कि यह से संबंधित है तथ्य यह है कि डिफ्यून को वैश्विक पर्यावरण में कार्य को परिभाषित करना चाहिए, लेकिन मुझे यकीन नहीं है कि इसका क्या अर्थ है। मैं इसे वर्तमान माहौल में क्यों छाया नहीं कर सकता?

क्या कुछ लैम्ब्डा इसके लिए बाध्य था तो दुभाषिया उपचार प्रतीक को कार्य के रूप में बल देने का कोई तरीका है? उदाहरण के लिए:

(setq y (lambda() "I want to be a named function")) 
(y) 

पीएस .: मैं एसबीसीएल का उपयोग कर रहा हूं।

उत्तर

20

कॉमन लिस्प कार्यों और मूल्यों के लिए विभिन्न नामस्थान है।

आप DEFUN, FLET, LABELS और 0 अन्य के साथ फ़ंक्शन नेमस्पेस में फ़ंक्शंस को परिभाषित करते हैं।

यदि आप किसी फ़ंक्शन ऑब्जेक्ट को मान के रूप में प्राप्त करना चाहते हैं, तो आप FUNCTION का उपयोग करें।

(defun foo (x) (1+ x)) 

(function foo) -> #<the function foo> 

या कम:

#'foo -> #<the function foo> 

आप एक समारोह कॉल करना चाहते हैं, तो आप (foo 100) लिखें।

तो आप उपयोग करने की आवश्यकता आप एक मूल्य के रूप में समारोह कॉल करने के लिए चाहते हैं FUNCALL या APPLY:

(funcall #'foo 1) 

आप कार्यों के आसपास भेज देंगे और उनसे फोन कर सकते हैं:

(defun bar (f arg) 
    (funcall f arg arg)) 

(bar #'+ 2) -> 4 

के मामले में DEFUN:

यह (setf (symbol-value 'FOO) (lambda ...)) नहीं है।

यह (setf (symbol-function 'foo) (lambda ...)) जैसा है।

ध्यान दें कि दो नामस्थान लिखने के लिए सक्षम:

(defun foo (list) 
    (list list)) 

(foo '(1 2 3)) -> ((1 2 3)) 

वहाँ में निर्मित समारोह LIST और चर LIST के बीच कोई विवाद नहीं है। चूंकि हमारे पास दो अलग-अलग नामस्थान हैं, इसलिए हम दो अलग-अलग उद्देश्यों के लिए एक ही नाम का उपयोग कर सकते हैं।

ध्यान दें कि स्थानीय कार्यों के मामले में प्रतीक शामिल नहीं है। नेमस्पेस जरूरी नहीं है कि प्रतीकों से बंधे हों। इस प्रकार स्थानीय चर के लिए एक प्रतीक नाम के माध्यम से एक फ़ंक्शन लुकअप संभव नहीं है।

5

आम लिस्प में प्रत्येक प्रतीक के लिए एकाधिक स्लॉट हैं, जिसमें मूल्य-स्लॉट और फ़ंक्शन-स्लॉट शामिल है। जब आप सिंटैक्स (x) का उपयोग करते हैं, तो सामान्य lisp x के फ़ंक्शन-स्लॉट-बाइंडिंग की तलाश करता है। यदि आप मान-बाध्यकारी कॉल करना चाहते हैं, तो funcall या apply का उपयोग करें।

देखें http://cl-cookbook.sourceforge.net/functions.html