{"record":{"id":"ebdb12e6f69cc48b","repo":"clojure/clojure","slug":"fns-taking-primitives-cannot-be-variadic","errorCode":null,"errorMessage":"fns taking primitives cannot be variadic","messagePattern":"fns taking primitives cannot be variadic","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"src/jvm/clojure/lang/Compiler.java","lineNumber":6002,"sourceCode":"\t\t\t\t\t\tthrow Util.runtimeException(\"Invalid parameter list\");\n\t\t\t\t\t}\n\n\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\tClass pc = primClass(tagClass(tagOf(p)));\n//\t\t\t\t\tif(pc.isPrimitive() && !canBeDirect)\n//\t\t\t\t\t\t{\n//\t\t\t\t\t\tpc = Object.class;\n//\t\t\t\t\t\tp = (Symbol) ((IObj) p).withMeta((IPersistentMap) RT.assoc(RT.meta(p), RT.TAG_KEY, null));\n//\t\t\t\t\t\t}\n//\t\t\t\t\t\tthrow Util.runtimeException(\"Non-static fn can't have primitive parameter: \" + p);\n\t\t\t\t\tif(pc.isPrimitive() && !(pc == double.class || pc == long.class))\n\t\t\t\t\t\tthrow new IllegalArgumentException(\"Only long and double primitives are supported: \" + p);\n\n\t\t\t\t\tif(state == PSTATE.REST && tagOf(p) != null)\n\t\t\t\t\t\tthrow Util.runtimeException(\"& arg cannot have type hint\");\n\t\t\t\t\tif(state == PSTATE.REST && method.prim != null)\n\t\t\t\t\t\tthrow Util.runtimeException(\"fns taking primitives cannot be variadic\");\n\t\t\t\t\t                        \n\t\t\t\t\tif(state == PSTATE.REST)\n\t\t\t\t\t\tpc = ISeq.class;\n\t\t\t\t\targtypes.add(Type.getType(pc));\n\t\t\t\t\targclasses.add(pc);\n\t\t\t\t\tLocalBinding lb = pc.isPrimitive() ?\n\t\t\t\t\t                  registerLocal(p, null, new MethodParamExpr(pc), true)\n\t\t\t\t\t                           : registerLocal(p, state == PSTATE.REST ? ISEQ : tagOf(p), null, true);\n\t\t\t\t\targLocals = argLocals.cons(lb);\n\t\t\t\t\tswitch(state)\n\t\t\t\t\t\t{\n\t\t\t\t\t\tcase REQ:\n\t\t\t\t\t\t\tmethod.reqParms = method.reqParms.cons(lb);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase REST:\n\t\t\t\t\t\t\tmethod.restParm = lb;\n\t\t\t\t\t\t\tstate = PSTATE.DONE;\n\t\t\t\t\t\t\tbreak;","sourceCodeStart":5984,"sourceCodeEnd":6020,"githubUrl":"https://github.com/clojure/clojure/blob/f3b143341d6efc6428b523b2eaa099a6cc99156e/src/jvm/clojure/lang/Compiler.java#L5984-L6020","documentation":"Clojure only supports primitive arities for non-variadic functions, and only for long/double parameters. If a fn has a primitive-typed signature (method.prim set) and also a rest parameter, the compiler rejects the combination because primitive arities cannot be variadic.","triggerScenarios":"Defining (defn f [^long x & rest] ...) or (fn ^long [^double d & more] ...) where a primitive-tagged positional param coexists with a rest param (Compiler.java:6002).","commonSituations":"Trying to write a high-performance variadic primitive function; adding a & rest param to an existing primitive-arity fn for backward compatibility.","solutions":["Remove the rest parameter so the fn has fixed arity with primitive params","Remove the primitive hints so the fn is variadic but boxed","Split into two functions: a fixed-arity primitive version and a variadic boxed version","Keep primitive hints only on long/double and only in fixed-arity fns"],"exampleFix":";; before\n(defn f [^long x & more] (+ x (first more)))\n;; after\n(defn f [^long x] (inc x))\n(defn f-variadic [x & more] (apply + x more))","handlingStrategy":"validation","validationCode":"(defn primitive-variadic? [params]\n  (and (some #{'&} params)\n       (some #(contains? (meta %) :tag) params)))\n;; if true, either drop the hint or drop the rest param","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use primitive hints (^long, ^double) only in fixed-arity fns","Provide separate fixed-arity primitive and variadic boxed versions","Remember only long and double primitives are supported"],"tags":["clojure","primitives","variadic","performance"],"backgroundTag":"conflicting-config-options","analyzedSha":"f3b143341d6efc6428b523b2eaa099a6cc99156e","analyzedAt":"2026-09-09T12:04:58.961Z","contentChangedAt":"2026-09-09T12:04:58.961Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}