user3522239
user3522239

Reputation: 11

clojure function behaves like a symbol when called without argument

I get the following weird behaviour from a clojure function: When I call it with one argument it seems as if it is a function, when I call it without arguments it appears to be a symbol. Any ideas how this can be?

this is what happens in the interpreter:

=> (input-updatef -1)

ArityException Wrong number of args (1) passed to: modelingutils/create-process-level/input-updatef--2954 clojure.lang.AFn.throwArity (AFn.java:429)

and when I try calling it without any argument:

=> (input-updatef)

ArityException Wrong number of args (0) passed to: Symbol clojure.lang.AFn.throwArity (AFn.java:429)

Thx!

Upvotes: 1

Views: 215

Answers (2)

user3522239
user3522239

Reputation: 11

Thanks, both answers helped.

I did not post the definition, because it contained a complex macro.. The problem was that I called the macro from a normal function and supplied an argument (an ff function) to this macro from the argument list of the calling function. This ff was interpreted as a symbol at macro evaluation time -- this is what caused the strange behaviour.

Solution: I changed the outer calling function into a macro, and unquoted ff in the argument list of the called macro.

Upvotes: 0

Michał Marczyk
Michał Marczyk

Reputation: 84331

Answering "how this can be":

user=> (defn foo [] ('foo))
#'user/foo
user=> (foo 1)
ArityException Wrong number of args (1) passed to: user/foo  clojure.lang.AFn.throwArity (AFn.java:429)
user=> (foo)
ArityException Wrong number of args (0) passed to: Symbol  clojure.lang.AFn.throwArity (AFn.java:429)

Of course your input-updatef situation may be more subtle, but it is at least clear that

  1. either the actual input-updatef function has no unary overload or it has one, but when you call it it ends up calling a function that has no unary overload with just one argument;

  2. it has a nullary overload;

  3. calling the nullary overload results in a call to a symbol with no arguments.

Also, based on the modelingutils/create-process-level/input-updatef--2954 part of your error message it seems to me that input-updatef might be a "local function" – created using letfn or introduced as the value of a let binding – returned at some point from a function called create-process-level. Here's an example of what that could look like:

user=> (defn foo
         ([]
           ('foo))
         ([x]
           (letfn [(f [])]
             (f x))))
#'user/foo
user=> (foo 1)
ArityException Wrong number of args (1) passed to: user/foo/f--4  clojure.lang.AFn.throwArity (AFn.java:429)
user=> (foo)
ArityException Wrong number of args (0) passed to: Symbol  clojure.lang.AFn.throwArity (AFn.java:429)

Using

(defn foo
  ([]
    ('foo))
  ([x]
    (let [f (fn [])]
      (f x))))

would have the same effect.

Upvotes: 3

Related Questions