2012-02-11 15 views
6

जावा पृष्ठभूमि से आ रहा है, मैं स्थिर प्रकार की सुरक्षा का बहुत शौकिया हूं और आश्चर्यचकित हूं कि कैसे क्लोजर प्रोग्रामर डेटा प्रारूप परिभाषाओं की समस्या से निपटते हैं (शायद न केवल प्रकार बल्कि सामान्य आविष्कार, क्योंकि प्रकार केवल एक हैं इसका विशेष मामला।)क्लोजर में डेटा प्रारूप सुरक्षा

यह मौजूदा प्रश्न "क्लोजर में टाइप सुरक्षा" के समान है, लेकिन यह संकलन समय पर प्रकारों की जांच करने के तरीके के बारे में अधिक ध्यान केंद्रित करता है, जबकि मुझे इस बात पर अधिक रुचि है कि कैसे समस्या व्यावहारिक रूप से संबोधित है।

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

मुझे जिस मूल समस्या में दिलचस्पी है वह यह है कि संपादकों और पढ़ने/लिखने के कार्यों को एक सामान्य डेटा प्रारूप पर सहमत होना है। जावा में, मैं दस्तावेज़ के डेटा को ऑब्जेक्ट ग्राफ़ के रूप में मॉडल करता हूं, उदा। प्रत्येक वर्ग विविधता के लिए एक वर्ग और एक वर्ग का प्रतिनिधित्व करने वाली एक कक्षा के साथ। इस तरह, मुझे एक संकलन-समय गारंटी मिलती है कि मेरे डेटा की संरचना किस तरह दिखती है, और यह कि ग्राफिक्स तत्व का क्षेत्र "चौड़ाई" एक पूर्णांक है और फ्लोट नहीं है। यह गारंटी नहीं देता है कि चौड़ाई सकारात्मक है - लेकिन गेटर/सेटर इंटरफ़ेस का उपयोग करने से संबंधित वर्ग को इस तरह की परिवर्तनीय गारंटी जोड़ने की अनुमति मिल जाएगी।

इस पर भरोसा करने में सक्षम होने से कोड इस डेटा से निपटने में आसान बनाता है, और प्रारूप उल्लंघन संकलन-समय या रनटाइम पर जल्दी पकड़ा जा सकता है (जहां कुछ कोड डेटा को संशोधित करने का प्रयास करते हैं जो इनवर्सेंट का उल्लंघन करेगा)।

क्लोजर में आप एक समान "डेटा प्रारूप विश्वसनीयता" कैसे प्राप्त कर सकते हैं? जहां तक ​​मुझे पता है, फ़ंक्शन इंटरफ़ेस के पीछे संकलन-समय की जांच और छुपा डोमेन डेटा करने का कोई तरीका नहीं है, गैर-मूर्खतापूर्ण (या शायद मुझे गलत समझा जा सकता है) के रूप में निराश किया जा सकता है, तो क्लोजर डेवलपर्स क्या सुरक्षित महसूस करते हैं डेटा के स्वरूप उनके कार्यों में सौंप दिया? आप जितनी जल्दी हो सके त्रुटि के लिए अपना कोड कैसे प्राप्त करते हैं, और उपयोगकर्ता के 20 मिनट के लिए संपादित करने के बाद और डिस्क पर सहेजने का प्रयास नहीं करते हैं, जब सहेजने का कार्य नोटिस करता है कि फोंट की सूची में ग्राफिक्स तत्व है संपादक बग?

कृपया ध्यान दें कि मुझे क्लोजर और सीखने में दिलचस्पी है, लेकिन इसके साथ कोई वास्तविक सॉफ्टवेयर नहीं लिखा है, इसलिए यह संभव है कि मैं उलझन में हूं और उत्तर बहुत आसान है - यदि हां, तो बर्बाद करने के लिए खेद है तुम्हारा समय :)।

उत्तर

8

मुझे आपके डेटा को बनाने और उसका उपयोग करने के लिए एक वैध API का उपयोग करने के बारे में कुछ भी गलत या unidiomatic नहीं दिख रहा है।

(defn text-box [text height width] 
    {:pre [(string? text) (integer? height) (integer? width)]} 
    {:type 'text-box :text text :height height :width width}) 

(defn colorize [thing color] 
    {:pre [(valid-color? color)]} 
    (assoc thing :color color)) 

... (colorize (text-box "Hi!" 20 30) :green) ... 

इसके अलावा, संदर्भ (वार्स, refs, परमाणुओं, एजेंटों) एक संबद्ध validator function कि हर समय एक मान्य राज्य सुनिश्चित करने के लिए इस्तेमाल किया जा सकता हो सकता है।

+0

अभी तक उत्तर के लिए धन्यवाद। चूंकि यह एक नहीं बल्कि ओपन एंडेड सवाल है, मैं हालांकि स्वीकार करने से पहले थोड़ा और इंतजार करेंगे। सत्यापनकर्ता समारोह एक दिलचस्प समाधान की तरह लगता है, हालांकि (उदाहरण के साथ रह) अगर आप अपने राज्य के रूप में एक बड़ी दस्तावेज़ है, यह पूरी तरह से हर बार एक छोटा सा परिवर्तन किया जाता है अक्षम हो रहा है मान्य - इस तरह के एक मॉडल में, मैं मान्य का उपयोग कर लगता है हेरफेर कार्यों preferrable होगा। – Medo42

5

अच्छा सवाल - मुझे यह भी पता चलता है कि एक स्थैतिक टाइप की गई भाषा से गतिशील व्यक्ति में जाने के लिए प्रकार की सुरक्षा के बारे में थोड़ी अधिक देखभाल की आवश्यकता होती है। सौभाग्य से टीडीडी तकनीकें यहां बड़ी मात्रा में मदद करती हैं।

मैं आमतौर पर एक "मान्य" फ़ंक्शन लिखता हूं जो डेटा संरचना के बारे में आपकी सभी मान्यताओं को जांचता है। मैं अक्सर जावा में इनवेरिएंट धारणाओं के लिए भी ऐसा करता हूं, लेकिन क्लोजर में यह अधिक महत्वपूर्ण है क्योंकि आपको प्रकारों जैसे विचारों की जांच करने की आवश्यकता है।

फिर आप कई मायनों में सत्यापित करें फ़ंक्शन का उपयोग कर सकते हैं:

  • आरईपीएल पर एक त्वरित जांच के रूप में: (validate foo)
  • इकाई परीक्षण में: (is (validate (new-foo-from-template a b c)))
  • महत्वपूर्ण कार्य के लिए एक रन-टाइम की जांच के रूप में उदाहरण के लिए यह जांच करना कि (read-foo some-foo-input-stream) मान्य है

आप एक जटिल डेटा संरचना है जो कई अलग अलग प्रकार के घटक एक पेड़ है है, तो आप प्रत्येक घटक प्रकार के लिए एक सत्यापित समारोह लिख सकते हैं और के लिए पूरे दस्तावेज़ कॉल सत्यापित करें के लिए सत्यापित करें कार्य हो सकता है प्रत्येक उप-घटक recursively। प्रत्येक घटक प्रकार के लिए वैध फ़ंक्शन पॉलिमॉर्फिक बनाने के लिए या तो प्रोटोकॉल या मल्टीमीड्स का उपयोग करना एक अच्छी चाल है।

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