पठनीय क्लोजर कोड कैसे लिखें?


13

मैं क्लोजर के लिए नया हूं। मैं अपने द्वारा लिखे गए कोड को समझ सकता हूं लेकिन बाद में इसे समझना बहुत मुश्किल हो जाता है।
कोष्ठकों का मिलान करना कठिन हो जाता है।

विभिन्न स्थितियों में नामकरण और इंडेंटेशन का नामकरण करने के लिए सामान्य सम्मेलनों का क्या करना है?

उदाहरण के लिए मैंने समझने के लिए एक नमूना डी-स्ट्रक्चरिंग उदाहरण लिखा था लेकिन यह दूसरी बार पूरी तरह से अप्राप्य दिखता है।

(defn f [{x :x y :y z :z [a b c] :coll}] (print x " " y  " " z " " a " " b " " c)) 

डी-स्ट्रक्चरिंग के मामले में, क्या यह सीधे पैरामीटर स्तर पर करना बेहतर है या लेट फॉर्म शुरू करना और फिर वहां जारी रखना है?


3
स्टैक ओवरफ्लो में पठनीयता के बारे में एक अच्छा जवाब है। आप इसे देख सकते हैं। stackoverflow.com/a/1894891/1969106
yfklon

2
सामान्य रूप से पठनीय लिस्प कोड लिखना मुश्किल है। उन्होंने एक कारण के लिए बैक्रोनियम "लॉस्ट इन सुपरफ्लस पेरेंटेसिस" का आविष्कार किया।
मेसन व्हीलर

जवाबों:


23

नामकरण की परंपरा

  • कार्यों के लिए नीचे रहना
  • -हाइफ़नेशन के लिए उपयोग (अन्य भाषाओं में अंडरस्कोर या ऊंट का मामला क्या होगा)।

    (defn add-one [i] (inc i))

  • विधेयकों (यानी सही या गलत लौटने वाले कार्य) ? उदाहरणों के साथ समाप्त होते हैं :odd? even? nil? empty?

  • राज्य बदलने की प्रक्रियाएँ समाप्त होती हैं !। आपको set!ठीक याद है? याswap!

  • उनकी पहुंच के आधार पर छोटे चर नाम की लंबाई चुनें। इसका मतलब है कि यदि आपके पास वास्तव में छोटा सहायक चर है, तो आप अक्सर एक-अक्षर के नाम का उपयोग कर सकते हैं। (map (fn [[k v]] (inc v)) {:test 4 :blub 5})आवश्यकतानुसार लंबे चर नाम चुनें, खासकर यदि वे कोड लाइनों के बहुत सारे उपयोग किए जाते हैं और आप तुरंत उनके उद्देश्य का अनुमान नहीं लगा सकते हैं। (मेरी राय)।

    मुझे लगता है कि बहुत सारे क्लोजर प्रोग्रामर सामान्य और संक्षिप्त नामों का उपयोग करते हैं। लेकिन यह वास्तव में वस्तुनिष्ठ अवलोकन नहीं है। मुद्दा यह है कि बहुत सारे क्लोजर फ़ंक्शन वास्तव में काफी सामान्य हैं।

    • सार्थक नामों का उपयोग करें। प्रक्रियाएं कुछ कर रही हैं, इसके लिए आप क्रियाओं का उपयोग करके उनका सबसे अच्छा वर्णन कर सकते हैं। Clojure बिल्ट-इन कार्य सही रास्ते पर आप रखना चाहिए: drop, take, assoc:, आदि तो फिर वहाँ एक अच्छा लेख एक सार्थक नाम का चयन करने के तरीके का वर्णन है http://ecmendenhall.github.io/blog/blog/2013/09/ 02 / साफ-clojure-सार्थक-नाम /

लैम्ब्डा कार्य करता है

  • आप वास्तव में लैम्ब्डा कार्यों को नाम दे सकते हैं। यह डिबगिंग और प्रोफाइलिंग के लिए सुविधाजनक है (मेरा अनुभव यहां क्लोजरस्क्रिप्ट के साथ है)।

    (fn square-em [[k v]] {k (* v v)})

  • इनलाइन लैम्ब्डा कार्यों #()को सुविधाजनक रूप में उपयोग करें

श्वेत रिक्ति

  • केवल परासन रेखाएँ नहीं होनी चाहिए। यानी कोष्ठकों को तुरंत बंद करें। याद रखें कि संपादक और संकलक के लिए परेंस हैं, इंडेंटेशन आपके लिए है।

  • फ़ंक्शन पैरामीटर सूचियाँ एक नई लाइन पर जाती हैं

   (अशुद्ध विपक्ष
     [Ab]
     (सूची अब)

यह समझ में आता है अगर आप डॉक्टर तार के बारे में सोचते हैं। वे फ़ंक्शन नाम और मापदंडों के बीच हैं। निम्नलिखित डॉक्टर स्ट्रिंग शायद सबसे बुद्धिमान नहीं है;)

   (अशुद्ध विपक्ष
     "चीजों को बाँधना"
     [Ab]
     (सूची अब)
  • जब तक आप जोड़ी बनाए रखते हैं, तब तक पेयर किए गए डेटा को एक नई लाइन द्वारा अलग किया जा सकता है
  (डी एफ एन 
    [{एक्स: एक्स 
      Y y 
      z: z  
      [abc]: coll}] 
    (प्रिंट x "" y "" z "" "a" b "" c)) 

(आप अपनी ,इच्छानुसार इसमें प्रवेश भी कर सकते हैं लेकिन यह अस्पष्ट लगता है)।

  • इंडेंटेशन के लिए पर्याप्त रूप से अच्छे संपादक का उपयोग करें। वर्षों पहले यह लिस्प संपादन के लिए एमएसीएस था, आज विम भी महान है। विशिष्ट क्लोजर आईडीई को यह कार्यक्षमता प्रदान करनी चाहिए। बस एक यादृच्छिक पाठ संपादक का उपयोग न करें।

    Vim in कमांड मोड में आप =कमांड को ठीक से इंडेंट करने के लिए उपयोग कर सकते हैं ।

  • यदि कमांड बहुत लंबी है (नेस्टेड, आदि) तो आप पहले तर्क के बाद एक नई पंक्ति सम्मिलित कर सकते हैं। अब निम्न कोड बहुत संवेदनहीन है, लेकिन यह दर्शाता है कि आप समूह और इंडेंट भाव कैसे कर सकते हैं:

(+) (अगर-चलो [उम्र: (व्यक्तिगत-उम्र के टकराव)]
     (यदि (18 वर्ष की आयु)
       आयु
       0))
   (गिनती (रेंज - 3 बी)
                 (कम करें + 
                         (रेंज बी 10)))))

अच्छे इंडेंटेशन का मतलब है कि आपको कोष्ठक की गिनती नहीं करनी है। कोष्ठक कंप्यूटर के लिए हैं (स्रोत कोड की व्याख्या करने और इसे इंडेंट करने के लिए)। इंडेंटेशन आपकी आसान समझ के लिए है।

उच्चतर आदेश कार्य बनाम forऔर doseqरूप

इस योजना की पृष्ठभूमि से आकर मुझे समझ में आने पर गर्व हुआ mapऔर लंबोदर के कार्यों, इत्यादि पर बहुत बार, मैं कुछ इस तरह लिखूंगा

(map (fn [[k x]] (+ x (k data))) {:a 10 :b 20 :c 30})

यह पढ़ने में काफी कठिन है। forप्रपत्र तरह से अच्छे है:

(for [[k x] {:a 10 :b 20 :c30}]
  (+ x (k data)))

`मानचित्र में बहुत सारे उपयोग हैं और यदि आप नामित कार्यों का उपयोग कर रहे हैं तो यह वास्तव में अच्छा है। अर्थात

(map inc [12 30 10]

(map count [[10 20 23] [1 2 3 4 5] (range 5)])

थ्रेडिंग मैक्रो का उपयोग करें

जब भी लागू हो थ्रेडिंग मैक्रोज़ ->और ->>साथ ही उपयोग करें doto

मुद्दा यह है कि थ्रेडिंग मैक्रोज़ सोर्स कोड को फंक्शन रचना की तुलना में अधिक रैखिक बनाते हैं। थ्रेडिंग मैक्रो के बिना कोड का निम्नलिखित टुकड़ा बहुत ही अपठनीय है:

   (f (g (h 3) 10) [10 3 2 3])

तुलना करना

   (-> 
     (h 3)
     (g 10)
     (f [10 3 2 3]))

थ्रेडिंग मैक्रो का उपयोग करके, आमतौर पर अस्थायी वेरिएबल को शुरू करने से बच सकते हैं जो केवल एक बार उपयोग किए जाते हैं।

अन्य बातें

  • Docstrings का प्रयोग करें
  • कार्यों को छोटा रखें
  • अन्य क्लोजर कोड पढ़ें

डी-स्ट्रक्चरिंग के साथ यह फ़ंक्शन इंडेंटेशन के साथ सुंदर दिखता है!
अमोघ तलपलीकर

कार्यों को छोटा रखने के लिए +1। बहुत कम कार्य बहुत अधिक स्व दस्तावेज हैं
डैनियल ग्रैज़र

1
मैं दृढ़ता से असहमत हूं कि "कम-पहुंच वाले" कार्यों में भी छोटे चर नाम का उपयोग करना अच्छा है। अच्छा चर नाम पठनीयता के लिए महत्वपूर्ण है और वे कुंजी स्ट्रोक के अलावा कुछ भी खर्च नहीं करते हैं। यह उन चीजों में से एक है जो मुझे क्लोजर समुदाय के बारे में सबसे अधिक परेशान करता है। वर्णनात्मक चर नामों के लगभग शत्रुतापूर्ण प्रतिरोध के साथ कई लोग हैं। क्लोजर कोर फ़ंक्शन तर्कों के लिए 1-अक्षर चर नामों से अटे पड़े हैं, और इससे भाषा सीखना बहुत कठिन हो जाता है (जैसे चल रहा है docया sourceएक REPL में)। रेंट का अंत, अन्यथा एक उत्कृष्ट जवाब के लिए
नाथन वालेस

@NathanWallace एक तरह से मैं आपसे सहमत हूँ, लेकिन कुछ पहलुओं में मैं नहीं। लंबे नाम कभी-कभी कार्यों को ओवरस्पीक बनाने के लिए होते हैं। तो आपको लग सकता है कि कुछ सामान्य फिल्टर ऑपरेशन वास्तव में सामान्य हैं, जबकि जब तर्क के applesबजाय xs, आपने सोचा था कि यह सेब के लिए विशिष्ट था। फिर, मैं लूप वेरिएबल के लिए फंक्शन लॉजिक नामों को ले-आउट से आगे तक पहुंचने पर विचार करूंगा। इसलिए अगर जरूरत हो, तो आप उन्हें लंबे समय तक रख सकते हैं। एक अंतिम विचार के रूप में: मैं आपको "नाम कोड नहीं मान" concatenative.org/wiki/view/Concatenative%20language/… के
wirrbel

मैं निजी बनाम सार्वजनिक इंटरफेस जैसी किसी चीज़ पर एक अनुच्छेद जोड़ सकता हूं। खासकर पुस्तकालयों के बारे में। यह कोड गुणवत्ता का एक पहलू है जिसके बारे में पर्याप्त बात नहीं की गई है और मैंने उस उत्तर को लिखने के बाद से इस बारे में टन सीखा है।
wirrbel
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.