2

ヒント付きパラメーターを使用して実行時に関数を生成しようとしています。

パラメータ シンボルは実行時に認識されます。

事前に知っていれば、次のように関数を動的に作成できます。

(def foo 
  (eval 
    (list 'fn '[^String a] (list '.length 'a))))

これは望ましいパフォーマンスを持っています:

user=> (time (reduce + (map foo (repeat 1000000 "asdf")  )))
"Elapsed time: 164.578 msecs"
4000000

とは対照的に:

(def bar
  (eval 
    (list 'fn '[a] (list '.length 'a))))

user=> (time (reduce + (map bar (repeat 1000000 "asdf")  )))
"Elapsed time: 2392.271 msecs"
4000000

今。私が抱えている問題は、引数の動的リストを使用して実行時にそのような関数を作成する方法です。例えば:

(def baz
  (let [args '[a b]]    
    (eval
      (list 
        'fn 
        (vec (flatten (map (fn [ar] `[^String ~ar]) args))) 
        (list '.length (first args))))))
#'user/baz

user=> (time (reduce + (map baz (repeat 1000000 "asdf") (repeat 1000000 "asdf"))))
"Elapsed time: 2467.178 msecs"
4000000

構文引用符により、コンパイラまたはリーダー マクロが型ヒントを解釈できないようです。型ヒントを使用して動的関数を生成するにはどうすればよいですか?

PS私は、そのような関数の作成が狂っているように見え、evalの代わりにマクロを使用することを提案するかもしれないことを知っていますが、私はこのようにする正当な理由があります.

PPS 特別な形式 'fn' と eval 以外に、実行時に既知のパラメーターを使用してラムダを作成する方法はありますか?

4

1 に答える 1

6

あなたが主張する場合:

(defn bazy [arglist]
  (let [args (mapv #(with-meta (symbol %) {:tag 'String}) arglist)]
    (eval (list 'fn args (list '.length (first arglist))))))

(def baz (bazy '[a b]))
于 2013-08-12T18:24:45.913 に答える