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!
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
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;
it has a nullary overload;
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.
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.
Related
I am pretty new with Clojure language.
While reading about Clojure functions, I find the example #([%]). So I try to use it as follows:
(def test1 #([%]))
(test1 5)
As a result, I get the following error:
ArityException Wrong number of args (0) passed to: PersistentVector clojure.lang.AFn.throwArity (AFn.java:429)
which seems to be that it is trying to invoke the array I wanted to return.
After digging a while, I find a solution as follows:
(def test1 #(-> [%]))
(test1 5)
I would have some questions:
Why doesn't the #([%]) work? What did I do with the expression #([x])?
In the correct example I am using the thread-first macro. Based on its documentation, it is used to pass an argument to the next function, e.g. (-> x (+ 1)). In this case I do not even have a function to pass to; *what is the next function in this context? I can not realize why it solved my issue
Question 1
The syntax #([%]) translates into: "Create a function that when called will evaluate the expression ([%]) with % being the first (and only) argument passed to the function". This expression has the syntax of a function call with [%] being the function to be called. You can see what goes on using a macroexpand:
(macroexpand '#([%]))
;; => (fn* [p1__6926#] ([p1__6926#]))
The class of persistent vectors in clojure is clojure.lang.PersistentVector. They implement the IFn interface for arity 1, so that you can treat the vector as a function mapping an index to an element. But they do not implement arity 0, which is what you are trying to call. In other words, your code does not work:
(def test1 #([%]))
(test1 5) ;; ERROR
However, if you would pass the argument 0 to your function [%], you would get back the element:
(def test1 #([%] 0))
(test1 5)
;; => 5
Do you see what happens? However, for the thing you are trying to do, there is a better way: The [a b c] syntax is just sugar for calling (vector a b c). So to get something that works, you can just do
(def test1 vector)
(test1 5)
;; => [5]
Question 2
The thread-first macros has the syntax of (-> x f0 f1 f2 ...) where x is the initial value and f0, f1 and so on are function calls with their first argument left out to be replaced by the value that is being piped through. Again we can use macroexpand to understand:
(macroexpand '(-> x f0 f1 f2))
;; => (f2 (f1 (f0 x)))
But in your case, the function calls are left out. To analyze your second example, we need to use clojure.walk/macroexpand-all for a full expansion, because we have nested macros:
(clojure.walk/macroexpand-all '#(-> [%]))
;; => (fn* [p1__6995#] [p1__6995#])
although, we can also look at it one step at a time:
(macroexpand '#(-> [%]))
;; => (fn* [p1__7000#] (-> [p1__7000#]))
(macroexpand '(-> [p1__7000#]))
;; => [p1__7000#]
So to answer your question: There is no next function in (-> [%]). The number of next functions can be any non-negative number, including zero, which is the case with (-> [%]).
#Rulle gives an exhaustive explanation of the details.
May I point out the most important part? Your reference from Clojure.org says:
;; DO NOT DO THIS
#([%])
So, don't do that! It is a silly trick that will only cause confusion & pain. Why would you want that???
My puzzle is the following example:
(defmacro macro1 [x]
(println x))
(defn func1 [x]
(println x))
(defmacro macro2 [x]
`(macro1 ~x)
(func1 x))
(defmacro macro3 [x]
(func1 x)
`(macro1 ~x))
(println "macro2")
(macro2 hello)
(println "macro3")
(macro3 hello)
Surprisingly, the output is:
macro2
hello
macro3
hello
hello
Why the output of macro2 and macro3 are different? In my understanding, all the calling of macro inside macro could be substituted with function (except for the reason of reuse). Anything wrong in my understanding?
Thanks Michael for clarifying. My general question is how to choose between using function or macro inside macro for the purpose of manipulating the s-expression. I wonder whether they can be used exchangeably except that they're evaled at different phases. Another example:
(defn manipulate-func [x]
(list + x 1))
(defmacro manipulate-macro [x]
(list + x 1))
(defmacro macro1 [x y]
[(manipulate-func x) `(manipulate-macro ~y)])
(println (clojure.walk/macroexpand-all '(macro1 (+ 1 2) (+ 3 4))))
;; [(#<core$_PLUS_ clojure.core$_PLUS_#332b9f79> (+ 1 2) 1) (#<core$_PLUS_ clojure.core$_PLUS_#332b9f79> (+ 3 4) 1)]
macro2 doesn't call macro1. Look at its body:
`(macro1 ~x)
(func1 x)
The first line is syntax-quoted; its value is list structure of the form (user/macro1 x-value) (assuming macro1 is defined in the user namespace; x-value here is the literal argument provided to macro2) and it has no side effects. Because there are no side effects and the value is discarded, this line has no effect.
Responding to the edit:
Firstly, it is important to distinguish calling another macro inside a macros body from emitting a call to another macro:
(defmacro some-macro []
...)
;; calls some-macro:
(defmacro example-1 []
(some-macro))
;; emits a call to some-macro:
(defmacro example-2 []
`(some-macro))
Secondly, in the case of calling functions and macros inside a macro's body, one must keep in mind what the relevant notions of runtime and compile time are:
functions called by a macro will be called at the macro expander's runtime, which is compile time from the point of view of user code;
macros called by a macro will be expanded when the macro body is compiled.
If a macro emits a call to another macro, the notions of runtime and compile time relevant to the emitted macro call will be the same as those relevant to the original macro call. If a macro calls another macro, they are shifted one step back, as it were.
To illustrate, let's consider a macro that delegates all its work to a helper function:
(defn emit-abc [abc-name [a b c]]
`(def ~abc-name {:a ~a :b ~b :c ~c}))
(defmacro defabc [abc-name abc-vals]
(emit-abc abc-name abc-vals))
From the REPL:
user> (defabc foo [1 2 3])
#'user/foo
user> foo
{:a 1, :c 3, :b 2}
If emit-abc were itself a macro, the above definition of defabc wouldn't even compile, because emit-abc would attempt to destructure the literal symbol abc-vals, throwing an UnsupportedOperationException.
Here's another example that makes it easier to explain what's happening:
(let [[a b c] [1 2 3]]
(defabc foo [a b c]))
defabc receives the vector of the three literal symbols a, b and c as the second argument; it has no access to the runtime values 1, 2 and 3. It passes this exact vector of symbols to the function emit-abc, which is then able to reach into this vector and extract the symbols to produce the map {:a a :b b :c c}. This map becomes the expansion of the defabc call. At runtime a, b and c turn out to be bound to the values 1, 2 and three, and so the map {:a 1 :b 2 :c 3} is produced.
Suppose we tried to write emit-abc as a macro with the same body (just changing defn to defmacro in its definition). Then we couldn't usefully call it from defabc, because we wouldn't have any way of conveying to it the actual values of the arguments to defabc. We could write
(emit-abc abc-name [(abc-vals 0) (abc-vals 1) (abc-vals 2)])
to make defabc compile, but this would end up emitting abc-name as the name of the Var being defined and include code for the vector literal [a b c] three times in the generated code. We could however emit a call to it:
`(emit-abc ~abc-name ~abc-vals)
This works as expected.
I think you're confused about the difference between macros and functions.
Macros are evaluated at compile time, and they take code as input and give code as output.
Functions evaluate their results at run time, taking run-time values as input and returning run-time values as output.
The result of a macro should pretty much always be an s-expression representing the source code resulting form applying the macro. This is why macros usually use the syntax quote functionality, since it makes it easy to generate source code with inserted parameterized values via the ~ and ~# escapes.
Defining a couple of functions might help you see how this works. Let's run the following code:
(defn testing-macro-2 [my-arg]
(macro2 my-arg))
(testing-macro-2 "macro 2 test")
(defn testing-macro-3 [my-arg]
(macro3 my-arg))
(testing-macro-3 "macro 3 test")
Here's what I get in my REPL:
user=>
(defn testing-macro-2 [my-arg]
(macro2 my-arg))
my-arg
#'user/testing-macro-2
user=> (testing-macro-2 "macro 2 test")
nil
user=>
(defn testing-macro-3 [my-arg]
(macro3 my-arg))
my-arg
my-arg
#'user/testing-macro-3
user=> (testing-macro-3 "macro 3 test")
nil
As you can see, my-arg is printed when defining the functions where the macros are invoked, not when I call the functions. This is because the macros are evaluated when the Clojure compiler is generating code for the function, so that's when the call to println happens.
However, if you use the syntax-quote in macro1 to make it return code instead of calling println, which returns nil, then it all changes:
user=>
(defmacro macro1 [x]
`(println ~x))
#'user/macro1
user=>
(defn func1 [x]
(println x))
#'user/func1
user=>
(defmacro macro2 [x]
`(macro1 ~x)
(func1 x))
#'user/macro2
user=>
(defmacro macro3 [x]
(func1 x)
`(macro1 ~x))
#'user/macro3
user=>
(defn testing-macro-2 [my-arg]
(macro2 my-arg))
my-arg
#'user/testing-macro-2
user=> (testing-macro-2 "macro 2 test")
nil
(defn testing-macro-3 [my-arg]
(macro3 my-arg))
my-arg
#'user/testing-macro-3
user=> (testing-macro-3 "macro 3 test")
macro 3 test
nil
user=> (macro2 hello)
hello
nil
user=> (macro3 hello)
hello
CompilerException java.lang.RuntimeException: Unable to resolve symbol: hello in this context, compiling:(NO_SOURCE_PATH:107)
Each of the macros still prints the argument due to a println being called when the macro is evaluated, but since macro3 now actually returns source code it actually works like println.
Note that testing-macro-2 prints nothing because macro2 throws away the result of the intermediate calculation `(macro1 ~x) and simply returns nil (the result of println). In other words, using (macro2 foo) is the same as just putting a nil literal in your code, except that the compiler will print foo as a side-effect when it evaluates the macro.
Invoking (macro3 hello) results in a CompilerException because the macro substitution results in the code (println hello), but hello is not defined. If you do something like (def hello "Hello there!") then you won't get an error since it will find a binding for hello.
I'm not satisfied with the answers so far, so let me take a stab...
The issue is that defmacro returns data that is then used as code. Only the last expression in defmacro is returned and, in your example, is then evaluated as code.
So... in your call to macro2 the following steps occur
`(macro1 ~x) is syntax quoted so it evaluates to (macro1 hello) and is not evaluated further because of the syntax quote. This line effectively does nothing as a result.
(func1 x) executes inside the macro, prints the string, and the result nil is returned.
The result of calling (macro2 hello) is nil so nothing further occurs.
Later, you call macro3 and the following steps occur
(func1 x) executes, prints hello, returns nil. But since the macro is not finished this nil does nothing and the next expression is evaluated.
`(macro1 ~x) evaluates (just as before) to (macro1 hello) and is returned as code (it is not evaluated further, yet, because it is syntax quoted). This is the return value of calling macro3 since it is the last expression in the implicit do of defmacro.
The return value of calling macro3 from the previous step is now evaluated. It evaluates to (println hello), but this is not evaluated yet.
Finally the previous steps result is evaluated and a second hello is printed.
I believe the point to understand is that a macro returns code to be executed and only the last expression is returned. Perhaps also, remember that the syntax quote ` prevents the expression following it from being evaluated and instead creates a list in place that is not evaluated further (unless some other action is taken to evaluate the expression).
Yes there is a runtime/compile time difference between when code is evaluated, but for this question I don't think that is the key thing to notice. The key thing to notice is that with macro2 the result of calling macro1 is not returned, but in macro3 it is returned and is therefore evaluated further.
Can someone explain the behavior in the Clojure code below?
I don't get it.
Does Clojure somehow replace or "optimize" function arguments? Why does calling a function with a single nil argument result in an ArityException?
(defn foo [bar] (reduce #(%1) bar))
(foo nil)
-> ArityException Wrong number of args (0) passed to: test$foo$fn clojure.lang.AFn.throwArity (AFn.java:437)
See (doc reduce):
[...]
If coll contains no
items, f must accept no arguments as well, and reduce returns the
result of calling f with no arguments.
[...]
Here coll is nil, which is effectively being treated as a collection containing no items (as it usually is in similar contexts), and f is #(%1).
Thus #(%1) is being called with no arguments and ends up throwing the exception you see.
I am a little confused by the clojure instance? function. It seems quite happy to take a single argument. So
(instance? String)
works fine, but always returns false.
Am I missing something here? I've done this twice in two days, and both times it took me a quite a long time to debug (yes, I agree, to make the mistake once might be regarded as misfortune, but twice looks like carelessness).
Why doesn't it break, with an arity error?
Note added later:
As of Clojure 1.6 this has been fixed!
http://dev.clojure.org/jira/browse/CLJ-1171
Interesting... even though instance? is defined in core.clj, it appears that there is special handling built in to clojure.lang.Compiler for (instance?) forms.
Compiler.java, line 3498:
if(fexpr instanceof VarExpr && ((VarExpr)fexpr).var.equals(INSTANCE))
{
if(RT.second(form) instanceof Symbol)
{
Class c = HostExpr.maybeClass(RT.second(form),false);
if(c != null)
return new InstanceOfExpr(c, analyze(context, RT.third(form)));
}
}
I interpret that to mean that, when you compile/evaluate an (instance?) form, the function defined in core.clj is ignored in favor of the hard-wired behavior, which does interpret a missing second argument as nil. I'm guessing this is done for performance reasons, as a sort of in-lining.
Apparently this special handling only applies in certain cases (and I'm not familiar enough with the compiler to know what they are). As illustrated by Ankur's answer, there are ways of calling instance? that cause the function defined in core.clj to be invoked.
I think it is a bug. If you define a new version of instance?, e.g.
(def
^{:arglists '([^Class c x])
:doc "Evaluates x and tests if it is an instance of the class
c. Returns true or false"
:added "1.0"}
foo? (fn foo? [^Class c x] (. c (isInstance x))))
you will get the expected exception
user=> (foo? String "bar")
true
user=> (foo? String 1)
false
user=> (foo? String)
ArityException Wrong number of args (1) passed to: user$foo-QMARK- clojure.lang.AFn.throwArity (AFn.java:437)
If you look at the instance? code you will see that the method isInstance of Class is called:
(def
^{:arglists '([^Class c x])
:doc "Evaluates x and tests if it is an instance of the class
c. Returns true or false"
:added "1.0"}
instance? (fn instance? [^Class c x] (. c (isInstance x))))
Looks like under the hood, nil (or false) is considered as the default value for x parameter when passed to the isInstance and that returns false.
Hmm....interesting... all the below calls fails (which is how it is supposed to be):
user=> (.invoke instance? String)
ArityException Wrong number of args (1) passed to: core$instance-QMARK- clojure.lang.AFn.throwArity (AFn.java:437)
user=> (instance? (type ""))
ArityException Wrong number of args (1) passed to: core$instance-QMARK- clojure.lang.AFn.throwArity (AFn.java:437)
user=> (apply instance? String [])
ArityException Wrong number of args (1) passed to: core$instance-QMARK- clojure.lang.AFn.throwArity (AFn.java:437)
user=> (#'instance? Long)
ArityException Wrong number of args (1) passed to: core$instance-QMARK- clojure.lang.AFn.throwArity (AFn.java:437)
Event creating a new instance of "instance?" function object works as it is supposed to work:
user=> (def a (.newInstance (aget (.getConstructors (type instance?)) 0) (into-array [])))
#'user/a
user=> (a String)
ArityException Wrong number of args (1) passed to: core$instance-QMARK- clojure.lang.AFn.throwArity (AFn.java:437)
user=> (a String "")
true
Given a list of names for variables, I want to set those variables to an expression.
I tried this:
(doall (for [x ["a" "b" "c"]] (def (symbol x) 666)))
...but this yields the error
java.lang.Exception: First argument to def must be a Symbol
Can anyone show me the right way to accomplish this, please?
Clojure's "intern" function is for this purpose:
(doseq [x ["a" "b" "c"]]
(intern *ns* (symbol x) 666))
(doall (for [x ["a" "b" "c"]] (eval `(def ~(symbol x) 666))))
In response to your comment:
There are no macros involved here. eval is a function that takes a list and returns the result of executing that list as code. ` and ~ are shortcuts to create a partially-quoted list.
` means the contents of the following lists shall be quoted unless preceded by a ~
~ the following list is a function call that shall be executed, not quoted.
So ``(def ~(symbol x) 666)is the list containing the symboldef, followed by the result of executingsymbol xfollowed by the number of the beast. I could as well have written(eval (list 'def (symbol x) 666))` to achieve the same effect.
Updated to take Stuart Sierra's comment (mentioning clojure.core/intern) into account.
Using eval here is fine, but it may be interesting to know that it is not necessary, regardless of whether the Vars are known to exist already. In fact, if they are known to exist, then I think the alter-var-root solution below is cleaner; if they might not exist, then I wouldn't insist on my alternative proposition being much cleaner, but it seems to make for the shortest code (if we disregard the overhead of three lines for a function definition), so I'll just post it for your consideration.
If the Var is known to exist:
(alter-var-root (resolve (symbol "foo")) (constantly new-value))
So you could do
(dorun
(map #(-> %1 symbol resolve (alter-var-root %2))
["x" "y" "z"]
[value-for-x value-for-y value-for z]))
(If the same value was to be used for all Vars, you could use (repeat value) for the final argument to map or just put it in the anonymous function.)
If the Vars might need to be created, then you can actually write a function to do this (once again, I wouldn't necessarily claim this to be cleaner than eval, but anyway -- just for the interest of it):
(defn create-var
;; I used clojure.lang.Var/intern in the original answer,
;; but as Stuart Sierra has pointed out in a comment,
;; a Clojure built-in is available to accomplish the same
;; thing
([sym] (intern *ns* sym))
([sym val] (intern *ns* sym val)))
Note that if a Var turns out to have already been interned with the given name in the given namespace, then this changes nothing in the single argument case or just resets the Var to the given new value in the two argument case. With this, you can solve the original problem like so:
(dorun (map #(create-var (symbol %) 666) ["x" "y" "z"]))
Some additional examples:
user> (create-var 'bar (fn [_] :bar))
#'user/bar
user> (bar :foo)
:bar
user> (create-var 'baz)
#'user/baz
user> baz
; Evaluation aborted. ; java.lang.IllegalStateException:
; Var user/baz is unbound.
; It does exist, though!
;; if you really wanted to do things like this, you'd
;; actually use the clojure.contrib.with-ns/with-ns macro
user> (binding [*ns* (the-ns 'quux)]
(create-var 'foobar 5))
#'quux/foobar
user> quux/foobar
5
Evaluation rules for normal function calls are to evaluate all the items of the list, and call the first item in the list as a function with the rest of the items in the list as parameters.
But you can't make any assumptions about the evaluation rules for special forms or macros. A special form or the code produced by a macro call could evaluate all the arguments, or never evaluate them, or evaluate them multiple times, or evaluate some arguments and not others. def is a special form, and it doesn't evaluate its first argument. If it did, it couldn't work. Evaluating the foo in (def foo 123) would result in a "no such var 'foo'" error most of the time (if foo was already defined, you probably wouldn't be defining it yourself).
I'm not sure what you're using this for, but it doesn't seem very idiomatic. Using def anywhere but at the toplevel of your program usually means you're doing something wrong.
(Note: doall + for = doseq.)