2010-12-16 2 views
42

मैंने क्लोजर में एक प्रोग्राम लिखा है लेकिन कुछ कार्यों में कोई तर्क नहीं है। किसी भी तर्क के साथ "defn" के बजाय "def" के रूप में ऐसे कार्यों को कोड करने के फायदे क्या होंगे?क्लोजर डीफ़ बनाम बिना किसी तर्क के फ़ंक्शन के लिए defn

+6

तुम्हारा मतलब क्या '(डीईएफ़ एक्स (एफ एन [] (कुछ)))', या '(डीईएफ़ x (कुछ)) '? वे पूरी तरह से अलग हैं, और स्वीकार्य उत्तर केवल दूसरी व्याख्या के लिए सही है। –

+1

मुझे लगता है कि दूसरा इंटरप्रेशन, लेकिन अच्छा बिंदु! – Zubair

उत्तर

61

def एस का मूल्यांकन केवल एक बार किया जाता है जबकि defn एस (तर्क के साथ या बिना तर्क) का मूल्यांकन हर बार किया जाता है (निष्पादित)। इसलिए यदि आपके फ़ंक्शन हमेशा एक ही मान वापस करते हैं, तो आप उन्हें def एस में बदल सकते हैं लेकिन अन्यथा नहीं।

+0

आह, मुझे यह नहीं पता था, आपने मुझे कुछ गंभीर कीड़े से बचाया! तो यदि कोई ऐसा डिफ है जो संदर्भ का उपयोग करता है तो इसे कभी भी पुन: गणना नहीं किया जाएगा? फ़ाइल को पुनः लोड करने के बारे में क्या होगा? फ़ाइल को फिर से लोड होने पर – Zubair

+1

'def' का पुनर्मूल्यांकन किया जाता है। –

+3

मुझे यह कहना गलत लगता है कि 'defn' रूपों का पुनर्मूल्यांकन किया जाता है। जैसा कि अन्य उत्तरों में बताया गया है, 'defn' मैक्रो विस्तार समय पर' def' 'का हल करता है, और वास्तव में वे सभी फ़ाइल लोड समय पर केवल एक बार मूल्यांकन किए जाते हैं। – skuro

28

(नाम का नाम ...) केवल एक मैक्रो है जो (डीफ़ नाम (एफएन ...) में बदल जाता है, इससे कोई फर्क नहीं पड़ता कि इसमें कितने पैरामीटर हैं। तो यह सिर्फ एक शॉर्टकट है। विवरण के लिए देखें (डॉक्टर डीएनएनएन) ।

99
user=> (def t0 (System/currentTimeMillis)) 
user=> (defn t1 [] (System/currentTimeMillis)) 
user=> (t1) 
1318408717941 
user=> t0 
1318408644243 
user=> t0 
1318408644243 
user=> (t1) 
1318408719361 
+14

धन्यवाद। यह कोड उदाहरण 1000 शब्द से अधिक वर्णन के लायक था। – user693960

+15

ताकि कोई भी इस महत्वपूर्ण बिंदु को याद न करे: जैसा कि रोमन बातेव की टिप्पणी का तात्पर्य है, '(def टी 2 (एफएन [] (सिस्टम/वर्तमान समय Millis)) ''t1'' t1' की तरह व्यवहार करेगा। – Mars

8

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

Var कुछ मान के संदर्भ में है, जो सह (दूसरों के बीच) में व्यक्त किया जा uld:
(def x 1) x ; => 1 ; x holds a reference to a number 1

  • एक समारोह रूप है, जो पहले पर करने के लिए मूल्यांकन किया जाता है के रूप में:

    • एक निरंतर रूप है, जो हमेशा अपने मूल्य का मूल्यांकन के रूप में

      इसके परिणामस्वरूप मूल्य:
      (def x (+ 2 2)) x ; => 4 ; x holds a reference to a number 4

    • एक जावा विधि रूप है, जिस पर


      (def x (System/currentTimeMillis)) x ; => 1417811438904 ; x holds a reference to a number 1417811438904 x ; => 1417811438904 ; still the same number!

    • एक लैम्ब्डा प्रपत्र (गुमनाम समारोह) है, जो पहले में आयोजित एक समारोह वस्तु लिए मूल्यांकन किया जाता है के रूप में:
      (def x (fn [] (System/currentTimeMillis))) x ; => #<user$x [email protected]> (x) ; function form, function evaluated ; => 1417811438904 (x) ; function form, function evaluated ; => 1417812565866

    वहाँ पहले इसके परिणामस्वरूप मूल्य लिए मूल्यांकन किया जाता है उपर्युक्त सभी के लिए एक साधारण नियम है। def विशेष रूप से एक अन्य अभिव्यक्ति के रूप में दिया गया एक एस-अभिव्यक्ति का पुनर्मूल्यांकन मूल्यांकन बनाया गया है, इसलिए परिणामस्वरूप Var इस मूल्यांकन के परिणामस्वरूप बाध्य है।

    यहां तक ​​कि fn का मूल्यांकन पहले किया गया है, लेकिन इसके परिणामस्वरूप मान एक फ़ंक्शन ऑब्जेक्ट है जिसमें कोड होता है। इस कोड को निष्पादित किया जाएगा (और मूल्यांकन किया जाएगा) प्रत्येक बार फ़ंक्शन को कहा जाता है। यही कारण है कि अलग-अलग परिणाम हैं।

    defn मैक्रो def की तरह है लेकिन आंतरिक रूप से यह एक अज्ञात फ़ंक्शन बनाता है और उसके बाद एक var ऑब्जेक्ट को बांधता है। इसका दूसरा तर्क इस कार्य का एक समूह बन जाता है और इसका मूल्यांकन "नियमित" तरीके से नहीं किया जाता है। कोई यह भी कह सकता है कि इसका मूल्यांकन किया गया है लेकिन लैम्ब्डा फॉर्म के रूप में - मूल्यांकन का परिणाम एक कार्य वस्तु है, न कि कुछ तत्काल गणना के परिणाम।

    तो लेखन:
    (defn fun [] 1)

    का पर्याय बन गया है:
    (def fun (fn [] 1))

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