2010-04-29 15 views
11

पर अधिकतम 20 पैरामीटर की सीमा क्यों है, क्लोजर फ़ंक्शन ले सकते पैरामीटर की संख्या की सीमा होने लगती है।क्लोजर फ़ंक्शन

जब 20 से अधिक मापदंडों के साथ एक समारोह को परिभाषित मैं इन्हें प्राप्त:

#<CompilerException java.lang.RuntimeException: java.lang.RuntimeException: java.lang.Exception: Can't specify more than 20 params (NO_SOURCE_FILE:0) (NO_SOURCE_FILE:0)>

जाहिर है इस से बचा जा सकता है, लेकिन मैं इस सीमा clojure के लिए एक मौजूदा डीएसएल के निष्पादन मॉडल पोर्टिंग मार गया था, और मैं निम्नलिखित है, जो मैक्रो विस्तार से इस सीमा को छोड़कर काफी आसानी से कार्यों के लिए मैप किया जा सकता की तरह मेरे डीएसएल में निर्माणों है:

(defAlias nn1 ((element ?e1) (element ?e2)) number 
"@doc features of the elements are calculated for entry into 
     the first neural network, the result is the score computed by the latter" 
(nn1-recall (nn1-feature00 ?e1 ?e2) (nn1-feature01 ?e1 ?e2) ... (nn1-feature89 ?e1 ?e2))) 

जो एक डीएसएल बयान है के साथ एक तंत्रिका नेटवर्क कॉल करने के लिए 90 इनपुट नोड्स। बेशक इसके आसपास काम कर सकते हैं, लेकिन यह सोच रहा था कि सीमा कहां से आती है। धन्यवाद।

+0

शैली पर एक ब्याज नोट के रूप में: स्टीव मैककनेल का "कोड पूर्ण" वकालत, आंशिक रूप से प्रोग्रामिंग दक्षता अध्ययनों पर आधारित है, कि एक विधि में 7 से अधिक तर्क नहीं होना चाहिए, और हाल ही में रॉबर्ट सी मार्टिन का "स्वच्छ कोड" सीमा को 3 के रूप में सेट करता है। मुझे 7 इंटरफेस को फिर से इंजीनियर करने का निर्णय लेने के लिए अंगूठे का एक अच्छा नियम मिला है, जबकि 3 थोड़ा चरम लगता है। हां, मैं मैक्रो और सभी के साथ आपकी विशेष परिस्थितियों से अवगत हूं; बस "सामान्य" मामले के लिए इंगित करते हुए, 20 काफी उदार है। –

+0

अपने न्यूरॉन्स को सरणी या कुछ के साथ बनाएं और उन्हें फ़ंक्शन में seqs के रूप में फ़ीड करें। और नक्शा-seqs को कम करें? कुछ इस तरह? http://www.fatvat.co.uk/2009/06/back-propagation-algorithm-in-clojure.html – claj

उत्तर

17

सबसे पहले, सीमा केवल आवश्यक स्थितित्मक तर्क पर लागू होती है; तुम हमेशा के रूप में कई तर्क को संभालने के लिए चर arity मामले (& more-args समारोह के हस्ताक्षर में) के रूप में उपयोग कर सकते हैं आप चाहते हैं:

(defn foo [& args] 
    (count args)) 

(foo 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25) 
;; returns 25 

वास्तव में, पहली नज़र में, & args लिए बिल्कुल सही समाधान होने की संभावना है आपके मुसीबत। (जैसे आप एक अनुक्रम में एकत्रित आपके इनपुट नोड्स पर एक फ़ंक्शन को मैप करने में सक्षम होंगे, loop/recur कहा गया अनुक्रम इत्यादि - - प्रत्येक के लिए अलग-अलग नामों को निर्दिष्ट करने की तुलना में बड़ी संख्या में समान वस्तुओं के साथ अधिक समझदारी करता है उन्हें

(ध्यान दें कि मैं उस विशिष्ट डीएसएल की प्रकृति को जानने का नाटक करता हूं जिसे आप क्लोजर में लिख रहे हैं या आप जिस तरह की समस्याओं से निपट रहे हैं, बस उन बिंदुओं का सुझाव दे सकते हैं जो आपके लिए रूचि रख सकते हैं। यदि आपके पास वास्तव में एक मजेदार स्थिति है जहां यह लागू नहीं होता है, तो शायद आप अधिक जानकारी प्रदान कर सकते हैं और हम देखेंगे कि यहां कोई व्यक्ति क्लोजर में उससे निपटने के लिए कुछ उपयोगी संकेत दे सकता है।)

पूर्णता के लिए, आपजोड़ सकते हैं एक समारोह जो आवश्यक स्थितीय args के रूप में अपनी पहली 19 तर्क लेता करने के लिए 934,623,210 बिट:

(defn bar [a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15 a16 a17 a18 a19 & as] 
    (+ 19 (count as))) 

(bar 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25) 
;; returns 25 

ध्यान दें कि यदि आप 20 स्थितीय आर्ग और उसके ऊपर & आर्ग निर्दिष्ट, जाहिरा तौर पर weirdness पीछा करेंगे।

औचित्य का सवाल है, मेरा मानना ​​है कि इस तथ्य यह है कि JVM अप 20. इतना clojure.lang.Fn वर्ग invoke विधि arities के लिए अतिभारित है बहुत कुशलतापूर्वक arity से एक पद्धति के लिए प्रेषण कर सकते हैं, मैं नहीं कर रहा हूँ के साथ क्या करना है पूरी तरह से यह सुनिश्चित करें कि यह उससे अधिक हो सकता है, लेकिन मुझे लगता है कि ऐसा कुछ नहीं है जो अक्सर लोगों की आवश्यकता होती है ... मेरा मतलब है, मुझे निश्चित रूप से किसी भी एपीआई को एक समारोह में 20 स्थितित्मक तर्कों को निर्दिष्ट करने के लिए थोड़ा सा संदिग्ध लगता है।

+0

धन्यवाद, और तर्क वास्तव में इसे पूरी तरह से संबोधित करते हैं। – GuyC

+2

बस एक नोट फिर से: 20 पोजिशनल तर्क और आराम एक ही समय में तर्क देते हैं: एक ऐसी बग थी जिसने इस धैर्य के लिए फ़ंक्शन के शरीर का मूल्यांकन किए बिना 'शून्य' वापस लौटाया, जिसे रिच ने कुछ मिनट पहले तय किया था। इस प्रकार, 1.2 को यह समस्या नहीं होगी। –

11

माइकल मार्स्कीक का जवाब आपको बताता है कि सीमा के आसपास कैसे जाना है। यदि आप इस सीमा के कारण हस्तक्षेप कर रहे हैं, तो आप इस प्रकार के क्लोजर स्रोत पर एक नज़र डालना चाहेंगे: IFn

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

आप इसे अधिक समर्थन के लिए अधिभारित कर सकते हैं, लेकिन मुझे इस तरह की चीज़ की उपयोगिता पर संदेह है। यदि आपके पास इनपुट स्रोतों का एक गुच्छा है, तो संभवतः उन्हें किसी सरणी के रूप में माना जा सकता है।

+0

माइकल का जवाब मुझे सीमा के चारों ओर ले जाता है, लेकिन वास्तव में आईएफएन को देखना दिलचस्प भी है। धन्यवाद। – GuyC

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