When skipping an arity
The following function does not have an arity 2
(defn foo
([a] "1")
([a b c] "3")
([a b c & args] "3 and more"))
In Clojure
Clojure 1.11.1
user=> (defn foo ([a] "1") ([a b c] "3") ([a b c & args] "3 and more"))
#'user/foo
user=> (foo 1 2)
Execution error (ArityException) at user/eval137 (REPL:1).
Wrong number of args (2) passed to: user/foo
ClojureScript also behaves the same
In Clava
./node_cli.js -e '(do (defn foo ([a] "1") ([a b c] "3") ([a b c & args] "3 and more")) (prn (foo 1 2)))'
"3 and more"
An Error was expected but instead vararg variant is invoked.
We do get an error if vararg is not there.
Vararg performance
Consider the following example
(defn foo
([a] "1")
([a & args] "vararg"))
Following is part of the code which is generated
let f44 = function (var_args) {
let G__4849 = arguments["length"];
switch (G__4849) {
case 1:
return f44.cljs$core$IFn$_invoke$arity$1(arguments[0]);
break;
default:
let args_arr4651 = [];
let len__22086__auto__52 = arguments["length"];
let i4753 = 0;
while (true) {
if (i4753 < len__22086__auto__52) {
args_arr4651.push(arguments[i4753]);
let G__54 = i4753 + 1;
i4753 = G__54;
continue;
}
break;
}
let argseq__22178__auto__55 =
1 < args_arr4651["length"] ? args_arr4651.slice(1) : null;
return f44.cljs$core$IFn$_invoke$arity$variadic(
arguments[0],
argseq__22178__auto__55
);
}
};
f44["cljs$core$IFn$_invoke$arity$1"] = function (a) {
return "1";
};
f44["cljs$core$IFn$_invoke$arity$variadic"] = function (a, args) {
return "vararg";
};
f44["cljs$lang$applyTo"] = function (seq56) {
let G__5758 = first(seq56);
let seq5659 = next(seq56);
let self__22117__auto__60 = this;
return self__22117__auto__60.cljs$core$IFn$_invoke$arity$variadic(
G__5758,
seq5659
);
};
f44["cljs$lang$maxFixedArity"] = 1;
the problometic part is the default case in the switch statement.
Using the new es6 spread feature the variadic function could be rewritten as
f44["cljs$core$IFn$_invoke$arity$variadic"] = function (a, ...args) {
return "vararg";
};
the diffrence is the ...before the args
then the default case in the switch could be rewriten as
let f44 = function (...var_args) {
let G__4849 = var_args["length"];
switch (G__4849) {
case 1:
return f44.cljs$core$IFn$_invoke$arity$1(var_args[0]);
break;
default:
if(G__4849 > f44["cljs$lang$maxFixedArity"]) {
return f44.cljs$core$IFn$_invoke$arity$variadic(...var_args)
}
throw `Wrong number of args (${G__4849}) passed to: user/foo`
}
};
also f44["cljs$lang$applyTo"] could be simplified in a similarly.
When skipping an arity
The following function does not have an arity 2
In Clojure
ClojureScript also behaves the same
In Clava
An Error was expected but instead vararg variant is invoked.
We do get an error if vararg is not there.
Vararg performance
Consider the following example
Following is part of the code which is generated
the problometic part is the default case in the switch statement.
Using the new es6 spread feature the variadic function could be rewritten as
the diffrence is the
...before theargsthen the default case in the switch could be rewriten as
also
f44["cljs$lang$applyTo"]could be simplified in a similarly.