2009-02-23 5 views
18

मैं हाल ही में कुछ लिस्प (सामान्य लिस्प) सीखने की कोशिश कर रहा हूं, और मुझे आश्चर्य है कि निरंतर संख्याओं को नाम देने के लिए कोई तरीका है जैसे कि आप सी के माध्यम से सी में कर सकते हैं।सी लिम्स के समतुल्य सामान्य लिस्प

मुझे enums की पूर्ण विशेषता की आवश्यकता नहीं है। अंत में मैं बस और पठनीय कोड रखना चाहता हूं।

मैंने ग्लोबल्स और छोटे कार्यों की कोशिश की है, लेकिन यह हमेशा प्रदर्शन में एक डिग्री के साथ आया था। कोड में संख्याओं को बस प्लग करना हमेशा तेज था।

उत्तर

22

लिस्प में enumerations करने के लिए सामान्य तरीके प्रतीकों का उपयोग करने के लिए है । प्रतीकों को प्रशिक्षित किया जाता है (संकेतक तालिका में उनकी प्रविष्टियों के लिए पॉइंटर्स के साथ प्रतिस्थापित किया जाता है) ताकि वे पूर्णांक के रूप में तेज़ी से और अन्य भाषाओं में गणित स्थिरांक के रूप में पठनीय हो सकें।

तो जहां सी में आप लिख सकते हैं:

 
enum { 
    apple, 
    orange, 
    banana, 
}; 

लिस्प में आप बस सीधे 'apple, 'orange और 'banana उपयोग कर सकते हैं।

(deftype fruit() '(member apple orange banana))

और फिर आप इतने पर declare, typep, typecase में टाइप fruit उपयोग कर सकते हैं, और आप कर सकते हैं:

आप एक प्रगणित प्रकार की जरूरत है, तो आप एक deftype साथ परिभाषित कर सकते हैं जेनेरिक फ़ंक्शन लिखें जो उस प्रकार पर विशेषज्ञ हैं।

+4

हां, लेकिन बेहतर कीवर्ड का उपयोग करें। – kmkaplan

+0

यह एक अच्छा मुद्दा है: कीवर्ड का उपयोग करके आप इस बारे में चिंता करने से बचें कि आपके प्रतीक किस पैकेज में हैं। –

+0

असल में, सामान्य कार्य केवल कक्षाओं पर विशेषज्ञ हो सकते हैं, मनमाना प्रकार नहीं। –

6

Enums लिस्प, कारण यह है कि सभी प्रतीकों उनकी खुद की पहचान कर रहे हैं के लिए बेमानी हैं, ताकि आप केवल उन्हीं का उपयोग कर सकते हैं, उदाहरण के लिए:

[[email protected]:~]$ clisp -q 
[1]> (setf x 'some) ;' 
SOME 
[2]> (eq x 'some) ;' 
T 
[3]> 
15

उदाहरण के लिए आप फ़ॉन्ट आकार नामकरण करना चाहते हैं:

(defconstant +large+ 3) 
(defconstant +medium+ 2) 
(defconstant +small+ 1) 

आपको लगता है कि कम करने के लिए एक मैक्रो लिख सकते हैं।

ऊपर की परिभाषाओं को ऊपर आमतौर पर लिखा जाता है जब इन नंबरों को कुछ बाहरी गैर-लिस्प कोड में पारित करने की आवश्यकता होती है।

अन्यथा कोई केवल कीवर्ड प्रतीकों का उपयोग करेगा:: बड़ा,: मध्यम और: छोटा।

आप उन्हें ईक्यू और समानता के लिए कुछ परीक्षणों का उपयोग करने वाले सभी परीक्षणों का परीक्षण कर सकते हैं।

(let ((size :medium)) 
    (ecase size 
    (:small ...) 
    (:medium ...) 
    (:large ...))) 

आप भी इसे करने के लिए तरीके लिख सकते हैं: जैसा कि बताया जा आप एक सेट के प्रकार को परिभाषित कर सकता है

(defmethod draw-string (message x y (size (eql :large))) ...) 

:

(deftype size() '(member :small :medium :large)) 

तो फिर तुम देख सकते हैं कि कुछ उन दोनों में से किसी है:

(let ((my-size :medium)) 
    (check-type my-size size)) 

ऊपर अगर मेरा आकार एक में से एक नहीं है तो एक त्रुटि सिग्नल करें: छोटा,: मध्यम या: बड़ा।

तुम भी एक defclass रूप में प्रकार का उपयोग कर सकते हैं:

(defclass vehicle() 
    ((width :type size :initarg :width))) 

अब तुम यहाँ की तरह वस्तुओं को बनाने होगा: जब आप कुछ करने के लिए स्लॉट सेट

(make-instance 'vehicle :width :large) 

कुछ कॉमन लिस्प कार्यान्वयन की जाँच करेगा अवैध मूल्य

यदि अब आप कक्षा वाहन की वस्तुएं बनाते हैं, तो स्लॉट इनमें से एक होगा: बड़ा, मध्यम या छोटा। यदि आप किसी डिबगर, इंस्पेक्टर या किसी अन्य टूल में ऑब्जेक्ट देखते हैं तो आपको प्रतीकात्मक नाम दिखाई देंगे, न कि 1, 2 या 3 (या जो भी मान आप सामान्य रूप से उपयोग करेंगे)।

यह लिस्प शैली का हिस्सा है: जब संभव हो तो प्रतीकात्मक नामों का उपयोग करें। इंटरफ़ेस कोड में केवल विदेशी कार्यों में संख्या मानों के साथ प्रतीकों का उपयोग करें (जैसे बाहरी सी कोड को कॉल करना जो enums का उपयोग करता है)।

+1

संख्यात्मक स्थिरांक (कीवर्ड के विपरीत) भी उपयोगी हो सकता है यदि आप रखना चाहते हैं चीजों का बड़ा हिस्सा, जैसे गेम या सिमुलेशन के लिए एक विश्व मॉडल में। तब आपका "अधिभोग मानचित्र", दीवारों और राक्षसों और खजाने जैसी विभिन्न प्रकार की चीजों को संकलित और कुशलता से ट्रैक कर सकता है। स्थिरांक के अंतराल का उपयोग इकाइयों को वर्गीकृत करने के लिए किया जा सकता है, जैसे कि 'राक्षस-पी (एक्स) (और (> = x + कम-राक्षस-संख्या +) (<= x + सबसे बड़ा-राक्षस-संख्या +)() = –

+0

दिया गया ऊपर दिए गए 'defconstant' कॉल, कीवर्ड का उपयोग करने के बाद उदाहरणों के साथ मिश्रित, यह मुझे मारता है कि कोई इन दोनों को मिश्रण कर सकता है, जब कोई गैर-लिस्प कोड पर जा रहा है, तो फ़ंक्शन के रूप में निम्न की तरह कुछ है: '(आकार आकार को हटाएं (थीसिस) (चेक-टाइप आकार आकार) (केस (: छोटा + छोटा +) (: मध्यम + मध्यम +) (: बड़ा + बड़ा +))) '। या हो सकता है कि कोई 'चेक-टाइप' छोड़ देता है और 'केस' के बजाय 'ecase' का उपयोग करता है। एक पारस्परिक 'संख्या-से-आकार' समान रूप से लिखा जा सकता है। – lindes

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