diff --git a/src/sci/impl/fns.cljc b/src/sci/impl/fns.cljc index 78f98216..4775fc21 100644 --- a/src/sci/impl/fns.cljc +++ b/src/sci/impl/fns.cljc @@ -222,12 +222,13 @@ f))) (defn lookup-by-arity [arities arity] - (some (fn [f] - (let [{:sci.impl/keys [fixed-arity min-var-args-arity]} (meta f)] - (when (or (= arity fixed-arity ) - (and min-var-args-arity - (>= arity min-var-args-arity))) - f))) arities)) + (let [arities-with-variadic-last (sort-by (comp :sci.impl/min-var-args-arity meta) arities)] + (some (fn [f] + (let [{:sci.impl/keys [fixed-arity min-var-args-arity]} (meta f)] + (when (or (= arity fixed-arity) + (and min-var-args-arity + (>= arity min-var-args-arity))) + f))) arities-with-variadic-last))) (defn eval-fn [ctx interpret {:sci.impl/keys [fn-bodies fn-name var] :as f}] diff --git a/test/sci/core_test.cljc b/test/sci/core_test.cljc index 1a2172f8..4a801c43 100644 --- a/test/sci/core_test.cljc +++ b/test/sci/core_test.cljc @@ -189,6 +189,8 @@ (is (= 2 (eval* '((fn foo [x & [y]] y) 1 2 3)))) (is (= 1 (eval* '((fn ([x] x) ([x y] y)) 1)))) (is (= 2 (eval* '((fn ([x] x) ([x y] y)) 1 2)))) + (is (= "otherwise" (eval* '((fn ([x & xs] "variadic") ([x] "otherwise")) 1)))) + (is (= "otherwise" (eval* '((fn ([x] "otherwise") ([x & xs] "variadic")) 1)))) (is (= '(2 3 4) (eval* '(apply (fn [x & xs] xs) 1 2 [3 4])))) (is (thrown-with-msg? #?(:clj Exception :cljs js/Error) #"Can't have fixed arity function with more params than variadic function"