2010-12-18 15 views
11

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

यानी मैं की तरह कुछ करने में सक्षम होना चाहते हैं:

(defn my-function [a b] (+ a b)) 

(defn add-3-numbers [a b c] 
    (inline (my-function 
    a 
    (inline (my-function 
     b 
     c))))) 

और यह उत्पादन (संकलन समय पर) है ठीक उसी समारोह के रूप में अगर मैं जोड़ अपने आप को इस तरह के रूप inlined था,:

(defn add-3-numbers [a b c] 
    (+ a (+ b c))) 
+0

क्या आपने 'आवेदन' फ़ंक्शन देखा था? http://clojuredocs.org/clojure_core/clojure.core/apply – edbond

+1

रनटाइम पर गतिशील रूप से काम करता है, मैं कुछ ऐसा ढूंढ रहा हूं जो संकलन समय पर इनलाइनिंग करता है .... – mikera

+0

'(रीड-स्ट्रिंग (clojure.repl/स्रोत-एफएन \ 'मेरा-फ़ंक्शन)) 'एक अच्छा प्रारंभिक बिंदु की तरह लगता है! – vemv

उत्तर

14

मामले में आप नहीं जानते थे, तो आप inlined कार्यों का उपयोग कर परिभाषित कर सकते हैं definline

(doc definline) 
------------------------- 
clojure.core/definline 
([name & decl]) 
Macro 
    Experimental - like defmacro, except defines a named function whose 
    body is the expansion, calls to which may be expanded inline as if 
    it were a macro. Cannot be used with variadic (&) args. 
nil 

भी स्रोत की जाँच,

(source definline) 
------------------------- 
(defmacro definline 
    [name & decl] 
    (let [[pre-args [args expr]] (split-with (comp not vector?) decl)] 
    `(do 
     (defn ~name [email protected] ~args ~(apply (eval (list `fn args expr)) args)) 
     (alter-meta! (var ~name) assoc :inline (fn ~name ~args ~expr)) 
     (var ~name)))) 

definline बस मेटा डेटा {:inline (fn definition)} के साथ एक var परिभाषित करता है। तो यद्यपि यह बिल्कुल ठीक नहीं था कि आप क्या पूछ रहे थे लेकिन आप रेखांकित व्यवहार प्राप्त करने के लिए नए मेटाडेटा के साथ var को पुनर्निर्मित कर सकते हैं।

+0

उपयोगी लिंक - यह निश्चित रूप से कई स्थितियों में एक सहायक उपकरण की तरह दिखता है। जो मैं खोज रहा हूं उसके साथ महत्वपूर्ण अंतर यह है कि ऐसा लगता है कि फ़ंक्शन को इनलाइन के रूप में स्पष्ट रूप से परिभाषित करने की आवश्यकता होती है, जबकि मैं एक मनमानी फ़ंक्शन – mikera

+0

इनलाइन करने में सक्षम होना चाहता हूं, मैंने इसे लागू करने में नहीं देखा है, लेकिन मैंने संकेत दिया संभावित समाधान आप एक मैक्रो लिखने का प्रयास कर सकते हैं जो कार्यों को दोबारा जोड़ता है जिसमें मेटाडेटा होता है जिसमें इनलाइन टैग होता है। हल करने की आवश्यकता होने वाली मुख्य समस्या यह सुनिश्चित करना है कि रिबाइंडिंग रनटाइम के बजाए संकलन समय पर की जाती है। – bmillare

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