Curious behavior of when-not and/or defmulti - clojure

Why does it happen that after I execute defmulti within a when-not, the previously unresolved symbol resolves fine, but not bound to the value?
user=> (resolve 'buux)
nil
user=> (when-not (resolve 'buux) (defmulti buux class))
nil
user=> (resolve 'buux)
#'user/buux
user=> (bound? #'buux)
false
user=> (defmulti buux class)
#'user/buux
user=> (bound? #'buux)
true

defmulti will be expanded with a let-block that uses def to define the symbol. As a matter of fact, the expression returned by defmulti will not be evaluated, but it will be generated as form using let, Thus, the object becomes defined globally. This results in your test-condition (for when not) to succeed after the var has been defined, before the multi-fn was created and the root binding of the var was affected. Your defmulti block was never executed (also the when-not expression returned nil), but expanded.
Further explanation:
Here you can see how that happens:
(macroexpand '(defmulti buxx class))
Now you can see the form that the macro call will generate:
(clojure.pprint/write (macroexpand '(defmulti buxx class))
:with-dispatch clojure.pprint/code-dispatch)
=>
(let*
[v__4080__auto__ (def buxx)]
(clojure.core/when-not
(clojure.core/and
(.hasRoot v__4080__auto__)
(clojure.core/instance? clojure.lang.MultiFn #v__4080__auto__))
...
This results in (def buux) being expanded. If you evaluate (def buux) in your repl you can make the same tests.
From the docstring of def:
def yields the var itself (not its value).
This means, when being expanded, it is being replaced with a (possibly unbound) var.
So when being expanded, def always creates a var but the optional form that returns the new value (for the var) will be only evaluated when the expanded def is evaluated. Macros and special forms will be expanded before they are actually evaluated. E. g. testing with
(defmacro i-have-side-effects
[]
(println "I was invoked!")
42)
(when-not true
(println (i-have-side-effects)))
=>
#'user/i-have-side-effects
I was invoked!
nil
So probably you should not define a multi-method conditionally anyway.

Related

Difference between calling function and macro inside macro?

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.

How can I define a variable in another namespace within a function/macro in Clojure?

I'm experimenting with ns in Clojure, here's what I try:
user=> (in-ns 'some-ns)
#<Namespace some-ns>
some-ns=> (def aa 100)
#'some-ns/aa
some-ns=> (in-ns 'user)
#<Namespace user>
user=> (= some-ns/aa 100)
true
user=> (= user/aa 100)
CompilerException java.lang.RuntimeException: No such var: user/aa, compiling:(NO_SOURCE_PATH:5:1) ;this works as expected
user=> (defn function [] (in-ns 'some-other-ns) (def cc 100) (in-ns 'user))
#'user/function
user=> (function)
#<Namespace user>
user=> (= some-other-ns/cc 100)
CompilerException java.lang.RuntimeException: No such var: some-other-ns/cc, compiling:(NO_SOURCE_PATH:8:1)
user=> (= user/cc 100)
true
I'm confused, why it doesn't work in function? Also, I tried following:
user=> (binding [*ns* (create-ns 'some-a-ns)] (def dd 100))
#'user/dd
user=> (= some-a-ns/dd 100)
CompilerException java.lang.RuntimeException: No such var: some-a-ns/dd, compiling:(NO_SOURCE_PATH:11:1)
user=> (= user/dd 100)
true
according to clojure doc
Creates and interns or locates a global var with the name of symbol and a namespace of the value of the current namespace (*ns*).
what I'm missing?
PS. I know I can use (intern 'some-ns 'a 100), but what I really want is a generic function/macro to do like
(with-ns 'some-ns (def a 100))
(= some/a 100)
intern is the correct solution and you can use it in any functions / macros of your own. (Functions can call intern; macros can expand to code calling intern.)
def should only ever be used directly at top level or nested within top-level forms where it will be immediately executed as soon as the top-level form is. So, def in let is fine, def inside a function is not.
def receives special handling from the compiler in that the Vars defined by def forms are actual created as soon as the def is compiled; the initial bindings specified in def forms are installed, however, if and when the flow of control actually reaches the def form. This explains why the binding example doesn't work -- it is the compile-time value of *ns* which counts, while the binding introduced by this binding form will come into effect at run time.
Finally, if you absolutely insist on using def forms to create Vars at runtime, the way to do it is with eval:
(binding [*ns* some-ns]
(eval '(def foo 1)))
;; some-ns/foo comes into existence with a root binding of 1
Note that here def does occur at top-level and will be immediately executed after compilation.

Clojure global variable behavior in a threaded environment

Given that this works as I'd expect:
(do
(println (resolve 'a)) ; nil
(def a "a")
(println (resolve 'a))) ; #'user/a
I'd like to understand why this doesn't:
(future
(println (resolve 'b)) ; #'user/b (shouldn't it be still undefined at this point?)
(def b "b")
(println (resolve 'b))) ; #'user/b
I'd also like to know if this is a proper solution (not exactly solving the same problem, but doing an equivalent job in my context):
(def c (atom nil))
(future
(println #c) ; nil
(reset! c "c")
(println #c)) ; c
This behaviour comes about as a result of the way in which def forms are compiled.
Note that using def forms not at top-level (or perhaps inside a top-level let -- see below for more comments on this case) is frowned upon as a matter of style in any case. The snippet using an Atom, on the other hand, is fine -- no reason not to use it if it does what you want.
On to the def story:
Compilation of def forms:
When a def form is encountered, a Var of the appropriate name is created at that moment by the compiler in the current namespace. (Attempting to def a Var outside the current namespace by using a namespace-qualified symbol as the name argument to def results in an exception). That Var is at first unbound and stays unbound until the def is actually executed; for a top-level def, that'll be right away, but for a def hidden inside a function's body (or inside a let form -- see below), that'll be when the function is called:
;;; in the user namespace:
(defn foo []
(def bar "asdf")
:done)
; => #'user/foo
bar
; => #<Unbound Unbound: #'user/bar>
;;; let's change the namespace and call foo:
(ns some.ns)
(user/foo)
; => :done
bar
; exception, the bar Var was created in the user namespace!
user/bar
; => "asdf"
; the Var's namespace is fixed at compile time
The first example -- with the do form:
Top level dos are treated as if their contents were spliced into the flow of code at the place where the do occurs. So if you type (do (println ...) (def ...) (println ...)) at the REPL, that's equivalent to typing in the first println expression, then the def, then the second println expression (except the REPL only produces one new prompt).
The second example -- with future:
(future ...) expands to something close to (future-call (fn [] ...)). If ... includes a def form, it'll be compiled in the manner we have seen above. By the time the anonymous function executes on its own thread the Var will have been created, thus resolve will be able to find it.
As a side note, let's have a look at a similar snippet and its output:
(let []
(println (resolve 'c))
(def c "c")
(println (resolve 'c)))
; #'user/c
; #'user/c
; => nil
The reason is as before with the extra point that let is first compiled, then executed as a whole. This is something one should keep in mind when using top-level let forms with definitions inside -- it's generally ok as long as no side-effecty code is intermingled with the definitions; otherwise one has to be extra careful.

Clojure vars and Java static methods

I'm a few days into learning Clojure and are having some teething problems, so I'm asking for advice.
I'm trying to store a Java class in a Clojure var and call its static methods, but it doesn't work.
Example:
user=> (. java.lang.reflect.Modifier isPrivate 1)
false
user=> (def jmod java.lang.reflect.Modifier)
#'user/jmod
user=> (. jmod isPrivate 1)
java.lang.IllegalArgumentException: No matching method found: isPrivate for class java.lang.Class (NO_SOURCE_FILE:0)
at clojure.lang.Compiler.eval(Compiler.java:4543)
From the exception it looks like the runtime expects a var to hold an object, so it calls .getClass() to get the class and looks up the method using reflection. In this case the var already holds a class, so .getClass() returns java.lang.Class and the method lookup obviously fails.
Is there some way around this, other than writing my own macro?
In the general case I'd like to have either an object or a class in a varible and call the appropriate methods on it - duck typing for static methods as well as for instance methods.
In this specific case I'd just like a shorter name for java.lang.reflect.Modifier, an alias if you wish. I know about import, but looking for something more general, like the Clojure namespace alias but for Java classes. Are there other mechanisms for doing this?
Edit:
Maybe I'm just confused about the calling conventions here. I thought the Lisp (and by extension Clojure) model was to evaluate all arguments and call the first element in the list as a function.
In this case (= jmod java.lang.reflect.Modifier) returns true, and (.getName jmod) and (.getName java.lang.reflect.Modifier) both return the same string.
So the variable and the class name clearly evaluate to the same thing, but they still cannot be called in the same fashion. What's going on here?
Edit 2
Answering my second question (what is happening here), the Clojure doc says that
If the first operand is a symbol that
resolves to a class name, the access
is considered to be to a static member
of the named class... Otherwise it is
presumed to be an instance member
http://clojure.org/java_interop under "The Dot special form"
"Resolving to a class name" is apparently not the same as "evaluating to something that resolves to a class name", so what I am trying to do here is not supported by the dot special form.
(Update: I've prepared something which might be acceptable as a solution... The original answer remains below a horizontal rule towards the end of the post.)
I've just written a macro to enable this:
(adapter-ns java.lang.reflect.Modifier jmod)
; => nil
(jmod/isStatic 1)
; => false
(jmod/isStatic 8)
; => true
The idea is to create a single-purpose namespace, import the statics of a given class as Vars into that namespace, then alias the namespace to some useful name. Convoluted, but it works! :-)
The code is looks like this:
(defmacro import-all-statics
"code stolen from clojure.contrib.import-static/import-static"
[c]
(let [the-class (. Class forName (str c))
static? (fn [x]
(. java.lang.reflect.Modifier
(isStatic (. x (getModifiers)))))
statics (fn [array]
(set (map (memfn getName)
(filter static? array))))
all-fields (statics (. the-class (getFields)))
all-methods (statics (. the-class (getMethods)))
import-field (fn [name]
(list 'def (symbol name)
(list '. c (symbol name))))
import-method (fn [name]
(list 'defmacro (symbol name)
'[& args]
(list 'list ''. (list 'quote c)
(list 'apply 'list
(list 'quote (symbol name))
'args))))]
`(do ~#(map import-field all-fields)
~#(map import-method all-methods))))
(defmacro adapter-ns [c n]
(let [ias (symbol (-> (resolve 'import-all-statics) .ns .name name)
"import-all-statics")]
`(let [ns-sym# (gensym (str "adapter_" ~n))]
(create-ns 'ns-sym#)
(with-ns 'ns-sym#
(clojure.core/refer-clojure)
(~ias ~c))
(alias '~n 'ns-sym#))))
The above looks up the Var holding the import-all-statics macro in a somewhat convoluted way (which is, however, guaranteed to work if the macro is visible from the current namespace). If you know which namespace it's going to be found in, the original version I've written is a simpler replacement:
(defmacro adapter-ns [c n]
`(let [ns-sym# (gensym (str "adapter_" ~n))]
(create-ns 'ns-sym#)
(with-ns 'ns-sym#
(clojure.core/refer-clojure)
;; NB. the "user" namespace is mentioned below;
;; change as appropriate
(user/import-all-statics ~c))
(alias '~n 'ns-sym#)))
(Original answer below.)
I realise that this is not really what you're asking for, but perhaps clojure.contrib.import-static/import-static will be useful to you:
(use 'clojure.contrib.import-static)
(import-static clojure.lang.reflect.Modifier isPrivate)
(isPrivate 1)
; => false
(isPrivate 2)
; => true
Note that import-static imports static methods as macros.
You are successfully storing the class in jmod, but isPrivate is a static method of java.lang.reflect.Modifier, not of java.lang.Class.
You could do this with reflection:
(. (. jmod getMethod "isPrivate" (into-array [Integer/TYPE]))
invoke nil (into-array [1]))
Here is a macro inspired by the two previous answers that handles static methods on class names and variables with class names as well as instance methods on objects:
(defmacro jcall [obj & args]
(let [ref (if (and (symbol? obj)
(instance? Class (eval obj)))
(eval obj)
obj) ]
`(. ~ref ~#args)))
As a relative newbie on macros, the tricky part was getting the evaluation order right.
For other newbies: The obj parameter to the macro is passed in with no evaluation, and we need to force the evaluation of vars so the var name expands into the class name it holds. We need an explicit eval for that, outside the actual macro body.
The test for whether obj is a symbol is there to restrict the evaluation to variables. The test for whether the variable contains a class is there to skip evaluation of non-classes, then it works for objects and instance methods too.
Example use:
;; explicit class name, static method
user=> (jcall java.lang.reflect.Modifier isPrivate 1)
false
;; class name from var, static method
user=> (jcall jmod isPrivate 1)
false
;; works for objects and instance methods too
user=> (jcall (Object.) toString)
"java.lang.Object#3acca07b"
;; even with the object in a variable
user=> (def myobj (Object.))
#'user/myobj
user=> (jcall myobj toString)
"java.lang.Object#4ccbb612"
;; but not for instance methods on classes
user=> (jcall Object toString)
java.lang.NoSuchFieldException: toString (NO_SOURCE_FILE:747)

In Clojure, how to define a variable named by a string?

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.)