2010-12-18 12 views
11

Co ciekawsze, że cokolwiek innego (ale z oczekiwaniem, że może to być czasami przydatna sztuczka do dostrajania wydajności), możliwe jest użycie makr Clojure do "wstawiania" istniejącej funkcji?Podpisywanie funkcji za pomocą makr Clojure

tj Chciałbym móc zrobić coś takiego:

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

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

i mieć go produkować (w czasie kompilacji) dokładnie taką samą funkcję, jak gdybym inlined dodatki siebie, takich jak:

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

Czy przyjrzeliśmy się funkcji 'zastosuj'? http://clojuredocs.org/clojure_core/clojure.core/apply – edbond

+1

stosuje się dynamicznie w środowisku wykonawczym, szukam czegoś, co wykonuje inlining w czasie kompilacji ... – mikera

+0

'(read-string (clojure.repl/source-fn \ "my-function))' wydaje się być dobrym punktem wyjścia! – vemv

Odpowiedz

14

W przypadku, gdy nie wiadomo, można zdefiniować za pomocą funkcji 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 

sprawdzenie również źródłem,

(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 prostu definiuje var z meta-danych {:inline (fn definition)}. Więc chociaż nie jest to dokładnie to, o co prosiłeś, ale możesz ponownie powiązać var ​​z nowymi metadanymi, aby uzyskać zorientowane zachowanie.

+0

przydatny link - to zdecydowanie wygląda na pomocne narzędzie w wielu sytuacjach. kluczowa różnica z tym, czego szukam, polega na tym, że wydaje się, że funkcja musi być jawnie zdefiniowana jako wbudowana, podczas gdy ja chcę mieć możliwość wbudowania dowolnej funkcji. – mikera

+0

Nie zajmowałem się jej implementacją, ale zasugerowałem potencjalne rozwiązanie. Możesz spróbować napisać makro, które ponownie powiąże funkcje var do jednego z metadanymi zawierającymi tag: inline. Kluczowym problemem, który należy rozwiązać, jest zapewnienie ponownego wiązania w czasie kompilacji, a nie w czasie wykonywania. – bmillare

Powiązane problemy