2015-04-15 5 views
5

में विधि विकल्प का उपयोग करें, मुझे लगता है कि, केन की पुस्तक पढ़ने पर, defgeneric में :method विकल्प है, जो ऐसा लगता है कि यह आपको सामान्य परिभाषा में एक विधि निर्दिष्ट करने की अनुमति देता है। मैंने जो अधिकांश दस्तावेज देखा है, उनमें अलग-अलग defmethod एस में परिभाषित सभी लागू विधियां हैं। hyperspec, इसकी सामान्य स्पष्टता के साथ, :method को defgeneric के विकल्प के रूप में सूचीबद्ध करता है, लेकिन यह नहीं कहता कि इसका क्या अर्थ है।का उपयोग: डिफेंजेनिक

क्या :method विकल्प डिफ़ॉल्ट है, या कम से कम, दस्तावेज जो आप अपेक्षा करते हैं कि सबसे सामान्य उपयोग केस क्या होगा, या इसमें अतिरिक्त अर्थशास्त्र है? एक स्टाइल प्वाइंट के रूप में, यदि आप केवल एक विधि को परिभाषित करने की अपेक्षा करते हैं, तो क्या इसे defgeneric रूप में परिभाषित करने के लिए और अधिक समझदारी होती है (यदि आप वास्तव में ऐसा कर सकते हैं), या defmethod में अलग से? या इस मामले में एक सामान्य कार्य करने के लिए यह समझ में नहीं आता है, और इसके बजाय नियमित defun का उपयोग करें?

उत्तर

6

hyperspec अपने सामान्य स्पष्टता, सूचियों के साथ: defgeneric के लिए एक विकल्प के रूप में विधि है, लेकिन कहना नहीं है कि इसका क्या मतलब।

वास्तव में, HyperSpec entry for defgeneric अपने सामान्य स्पष्टता के साथ, कहते हैं कि यह वास्तव में क्या मतलब है। यह कहता है कि defgeneric के लिए वाक्यविन्यास है:

defgeneric function-name gf-lambda-list [[विकल्प | {विधि-विवरण} *]]

और उसके बाद का कहना है कि विधि-विवरण के लिए वाक्य रचना है:

विधि-विवरण :: = (: विधि विधि-क्वालीफायर * विशेष-लैम्ब्डा-सूची [[घोषणा * | प्रलेखन]] प्रपत्र *)

और फिर यह विधि-संयोजन वर्णन करता है:

प्रत्येक विधि-वर्णन जेनेरिक फ़ंक्शन पर एक विधि को परिभाषित करता है। प्रत्येक विधि की लैम्ब्डा सूची gf-lambda-list विकल्प द्वारा निर्दिष्ट लैम्ब्डा सूची के अनुरूप होना चाहिए। यदि कोई विधि विवरण निर्दिष्ट नहीं है और उसी नाम का एक सामान्य कार्य पहले से ही मौजूद नहीं है, तो कोई सामान्य कार्य नहीं किया गया है।

तो: विधि रूपों सामान्य समारोह पर तरीकों को परिभाषित करने के लिए, बस तरह के लिए कर रहे हैं रूपों defmethod।

(मैं अनुदान देगा कि यह वास्तव में के बारे में तुम क्यों defgeneric प्लस पसंद करते हैं कुछ भी नहीं कहना है: विधि के रूप में करने का विरोध किया defmethod याद रखें कॉमन लिस्प में आम मतलब यह है कि उस भाषा को एकजुट करने का प्रयास है। मौजूदा लिस्प कार्यान्वयन के बहुत सारे। शायद कुछ समर्थित: विधि और अन्य ने defmethod का समर्थन किया, और यह एक एकीकृत इंटरफ़ेस प्रदान करने का सबसे आसान तरीका था।

(defgeneric to-list (object)) 

(defmethod to-list ((object t)) 
    (list object)) 

(defmethod to-list ((object list)) 
    object) 

(defgeneric to-list (object) 
    (:method ((object t)) 
    (list object)) 
    (:method ((object list)) 
    object)) 

कभी कभी यह defgeneric पत्र के साथ तरीकों के कुछ परिभाषित करने के लिए सुविधाजनक हो सकता है:)

है, निम्नलिखित एक ही प्रभाव होता है। यह शैली की बात है, और यह आपके प्रश्न के अन्य हिस्सों में आता है। विधि विकल्प एक डिफ़ॉल्ट प्रस्तुत करते हैं, या कम से कम, दस्तावेज़ क्या आप उम्मीद का सबसे आम उपयोग किया जाएगा, या यह अतिरिक्त अर्थ विज्ञान है:

करता है?

यह डिफ़ॉल्ट का एक तरह होगा यदि आप प्रकार विनिर्देशक के बिना एक विधि निर्धारित करें, या प्रकार विनिर्देशक है कि हर वस्तु पर लागू होने वाले कर सकते हैं (उदाहरण के लिए, टी)।

एक शैली बिंदु के रूप में, यदि आप केवल एक विधि को परिभाषित करने, इसे और अधिक समझ defgeneric रूप में परिभाषित करने के लिए पड़ता है उम्मीद एक defmethod में (, वास्तव में यदि आप कर सकते हैं, कि करते हैं), या अलग से ? या यह इस मामले में सामान्य कार्य करने के लिए समझ में नहीं आता है, और इसके बजाय नियमित रूप से का उपयोग करें?

मुझे लगता है कि यह इस बात पर निर्भर करता है कि आप केवल एक विधि को परिभाषित करने की अपेक्षा क्यों करते हैं। यदि ऐसा इसलिए है क्योंकि आप केवल डिफ़ॉल्ट को परिभाषित कर रहे हैं, लेकिन अन्य उपयोगकर्ताओं को इसके तरीकों को लागू करने की उम्मीद है, तो किसी को भी स्रोत ढूंढने की आवश्यकता होने पर विधियों को डीफएम विधि के साथ रखना सुविधाजनक हो सकता है। यदि आप उम्मीद करते हैं कि केवल एक चीज है, तो एक सामान्य कार्य अधिक समझ में आ सकता है। मुझे लगता है कि ये निर्णय सिर्फ स्टाइल विकल्पों में आते हैं।

यह भी ध्यान देने योग्य है कि ऐसे अन्य रूप भी हैं जो सामान्य कार्य (और अन्य रूप जो सामान्य कार्यों का उत्पादन कर सकते हैं) पर विधियों को परिभाषित कर सकते हैं। हाइपरस्पेक में, उच्च वर्गों पर जाने के लिए ऊपर तीरों का उपयोग करने से आम तौर पर आपको अधिक गद्य में लाया जाएगा। इस मामले में, 7.6.1 Introduction to Generic Functions उपयोगी है:

कुछ ऑपरेटर सामान्य कार्य के लिए विधियों को परिभाषित करते हैं। इन ऑपरेटरों को विधि-परिभाषित ऑपरेटरों के रूप में जाना जाएगा; उनके संबंधित रूपों को विधि-परिभाषित रूप कहा जाता है। मानकीकृत विधि-परिभाषित ऑपरेटरों को अगले आंकड़े में सूचीबद्ध किया गया है।

defgeneric  defmethod defclass 
define-condition defstruct 
+0

सीएलओएस ज्यादातर फ्लेवर्स/न्यू फ्लेवर्स और लूप/कॉमनलूप पर आधारित था। कई विधियां लंबी हो सकती हैं और आम तौर पर उनमें से कई को एक लंबे रूप में रखने के लिए पसंद नहीं किया जाता है। इसके अलावा एक विधि अकेले आसान/तेज तरह से परिभाषित करता है ... –

+0

धन्यवाद। शायद हाइपरस्पेक मेरे लिए बेहतर आंखों वाले लोगों के लिए है। (मुझे विश्वास नहीं है कि जब मैं इसका "मतलब" हूं तो वहां "यह" है।) – amp108

+0

@ amp108 वास्तव में कुछ अन्य रूप हैं जो सामान्य कार्यों पर विधियों को पेश करते हैं (और कुछ मामलों में जेनेरिक फ़ंक्शंस भी पेश करते हैं)। हाइपरस्पेक के कुछ गद्य भागों ने इस पर चर्चा की; मैंने अंत में एक अनुच्छेद के साथ अपना जवाब अपडेट कर दिया है। –

2

यह व्यक्तिगत पसंद और क्या कैसे प्रणाली स्रोत में आयोजित किया जाएगा पर निर्भर है।या तो

  • सरल सामान्य समारोह: DEFMETHODS

  • जटिल सामान्य समारोह का एक समूह: एक DEFGENERIC और DEFMETHODS

  • सामान्य समारोह का एक समूह:

  • अंदर तरीकों में से एक DEFGENERIC और एक गुच्छा

सीएलओएस से पहले अधिकांश लिस्प ओओ-सिस्टम सिंगल का इस्तेमाल करते थे ई विधि परिभाषा फार्म। कोड एक रूप में बहुत लंबा हो सकता है अन्यथा, जेनेरिक फ़ंक्शन अधिकतर मौजूद नहीं थे, ...

कक्षा-उन्मुख एकल-प्रेषण प्रणाली के साथ यह कक्षा परिभाषा में विधियों को व्यवस्थित करने के लिए समझ में आया हो सकता था। जेनेरिक फ़ंक्शंस और एकाधिक प्रेषण के परिचय के साथ इसे सामान्य कार्य परिभाषा के तहत व्यवस्थित करने के लिए समझ में आया।

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