-
-
Notifications
You must be signed in to change notification settings - Fork 56
Closed
Description
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/fooClojureScript 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.
Metadata
Metadata
Assignees
Labels
No labels