Why does this code work?
(defn g []
do (println 10) (println 20))
Note: There is no ( before the do.
In theory this shouldn't even compile. The compiler ought to complain that do cannot be resolved since it is a special symbol not in the first position of a form.
This is a (likely unintended) consequence of using the same BodyExpr parsing code for both the do special form and the body of the fn* special form. When compiling a do special form, the leading do is dropped and the remaining forms compiled. Using this same parser for a function body means a single naked do can also appear first.
public static class BodyExpr implements Expr, MaybePrimitiveExpr{
...
public Expr parse(C context, Object frms) {
ISeq forms = (ISeq) frms;
if(Util.equals(RT.first(forms), DO))
forms = RT.next(forms);
....
You'll notice that if the do is repeated, this
(defn g [] do do (println 10) (println 20))
;=> CompilerException java.lang.RuntimeException:
Unable to resolve symbol: do in this context ...
does not compile, as expected.
Related
This question answers how to read a public field from a Java object:
(let [p (java.awt.Point.)]
(.x p)) ; <- returns 0
I thought I could write the field in a similar way:
(let [p (java.awt.Point.)]
(.x p 42))
But I get the following error:
IllegalArgumentException No matching method found: x for class java.awt.Point
clojure.lang.Reflector.invokeMatchingMethod (Reflector.java:53)
This is covered in the Clojure - Java Interop:
(set! (. instance-expr instanceFieldName-symbol) expr)
Assignment special form.
When the first operand is a field member access form, the assignment is to the corresponding field. If it is an instance field, the instance expr will be evaluated [and assigned to the corresponding instance field].
Also note the use of '-' in resolving a field:
If the second operand [of (. instance-expr member)] is a symbol starting with -, the member-symbol will resolve only as field access (never as a 0-arity method) and should be preferred when that is the intent..."
Thus:
(set! (. p -x) 42)
Alternatively, the "preferred idiomatic forms for accessing field or method members" is slightly different, and this equivalency is shown in the macro expansion at the top of the page.
(set! (.-x p) 42)
Why do I get the error:
IllegalArgumentException First argument to defn must be a symbol clojure.core/defn (core.clj:277)
When I try to define a function like this:
(defn (symbol "f[]") 1)
Or like this:
(defn (symbol "f") [] 1)
Why aren't those the equivalent of straight forward example below ?
(defn f [] 1)
This is esoteric I know: but it just occurred to me that I might want to name a function dynamically at some point. (No real use case here - just trying to understand Clojure's mind...)
When you pass arguments to a macro, they are not evaluated beforehand. Since defn is a macro, what you're passing it in those two cases are not equivalent.
You are mixing code and data. It is a very common mistake to do. Eg.
(+ 4 5) ; ==> 9
('+ 4 5) ; ==> Error
'+ evaluates to a symbol. It is not the same as the variable + that is code and evaluates for a function. It's easy to check by evaluating them:
+ ; ==> #<core$_PLUS_ clojure.core$_PLUS_#312aa7c>
'+ ; ==> +
defn is a macro that expands to def so your beef is with def. The reason (def (symbol "x") 5) doesn't work is because def happens at compile time. The first arguments is never evaluated, but used for all references to the same identifiers within the same namespace. An expression like (symbol "x") won't work pretty much because of the same reason + and '+ cannot be mixed. You can do this in compile time though:
(defmacro make-fun [name expression]
`(defn ~(symbol name) [] ~expression))
(macroexpand-1 '(make-fun "f" 1))
; ==> (clojure.core/defn f [] 1)
(make-fun "f" 1)
; ==> #'user/f
(f) ; ==> 1
So what is happening is that before the code runs (make-fun "f" 1) gets replaced with (clojure.core/defn f [] 1) and the runtime never ever sees where it came from. While this seems useful you still cannot use a binding or input to make your function:
(def fun-name "f")
(def fun-value 1)
(macroexpand-1 '(make-fun fun-name fun-value))
; ==> (clojure.core/defn fun-name [] fun-value)
Macros are just a way to simplify and abstract on syntax. If you always write a pattern that looks like (defn name [& args] (let ...) you can make the parts that differ bindings in a macro and shorten every place you use the abstraction with the new macro. It is a code translation service. In compile time the arguments are just the literal code that it is suppsoed to replace and you never have the luxury to see if a variable or expression has a certain value since you only knows about the code and never what they actually represent. Thus the errors usually arises in when the code in the end result runs.
In the end you can do anything in runtime with eval. I've seen eval being used in a sensible manner twice in my 19 year run as a professional programmer. You could do:
(defn make-fun [name value]
(eval `(defn ~(symbol name) [] ~value)))
(make-fun fun-name fun-value)
; #'user/f
(f)
; ==> 1
Now while this works you shouldn't do it unless this is some sort of tool to test or do something with code rather than it being a part of the code to be run as a service with the string coming in from a unsafe source. I would have opted for using dictionaries instead such that you do not update your own environment. Imagine if the input was make-fun or some other part of your code that would give the client control over your software.
The answer is what Josh said (defn is a macro; if it was a function then your code really would work in this way). You can define your own defn variation macro that would do what you want or just use eval:
(eval `(defn ~(symbol "f") [] 1))
; => #'user/f
(f)
; => 1
You really don't need to use eval.
You have hit the problem known as "turtles all the way down". Once you try to treat a macro like a function (perhaps passing it to map, for example), you find you cannot do it without writing another macro. The same applies to macro #2, etc.
Thus, you can't compose macros as well as you can compose functions. This is the genesis of the general advice, "Never use a macro when you can use a function."
In this case, defn is a macro, so you have no choice but to write another macro (def behaves the same way, even though it is a special form instead of a macro). Our new macro dyn-defn dynamically creates the function name from a list of strings:
(defn fun-1 [] 1)
(def fun-2 (fn [] 2))
; (def (symbol (str "fun" "-3")) (fn [] 3))
; => Exception: First argument to def must be a Symbol
(defmacro dyn-defn
"Construct a function named dynamically from the supplied strings"
[name-strs & forms]
(let [name-sym (symbol (str/join name-strs)) ]
(spyx name-sym)
`(defn ~name-sym ~#forms)))
(dyn-defn ["fun" "-3"]
[]
3)
with result:
*************** Running tests ***************
:reloading (tst.demo.core)
name-sym => fun-3 ; NOTE: this is evaluated at compile-time
Testing _bootstrap
-------------------------------------
Clojure 1.9.0 Java 1.8.0_161
-------------------------------------
Testing demo.core
Testing tst.demo.core
(fun-1) => 1 ; NOTE: these are all evaluated at run-time
(fun-2) => 2
(fun-3) => 3
Note that the function name is an argument to the defn macro, and must be a symbol, not a function call.
Note:
Correct, you can't tell by looking at it if a form is "calling" a function or a macro. In fact, many "build-in" features of Clojure are constructed from more fundamental parts of the language, whether macros like when (source code) or functions like into (source code).
Perhaps you can help me find this in the docs. I'm using pound-quote to be able to pass around unevaluated function names prior to execution. For example:
(#'cons 1 ())
;(1)
(defn funcrunner [func a b]
(func a b))
(funcrunner cons 'a ())
;(a)
(funcrunner 'cons 'a ())
'()
(funcrunner #'cons 'a ())
;(a)
#'cons
;#'clojure.core/cons
(resolve (symbol 'cons))
;#'clojure.core/cons
My guess is that this is a reader macro.
My question is (a) What is the pound quote (#') shorthand for? (b) Can you explain what it is doing? (c) Can you locate it in the docs? (d) Is it actually shorthand for for resolve and symbol functions?
PS - For those not in the US - # is also known as a 'hash' or a 'cross-hash'.
PPS - I'm aware my example makes the need for this somewhat redundant. I'm interested to know if this is completely redundant or there are specific use cases.
#' is a reader macro that expands to (var foo). What you're doing here is not passing around unevaluated functions, you're passing around vars which contain functions. The reason this works the way it does is because vars are functions that look up their contained value and call it:
user=> (defn foo [x] (+ x 10))
#'user/foo
user=> (#'foo 10)
20
user=> ((var foo) 10)
20
Notice that when I defined the function, a var was returned. It looks like what you've been doing! :)
#' is the reader macro for var. See http://clojure.org/special_forms#var and http://clojure.org/vars
(var foo) returns the var named by the symbol foo, which can hold any kind of value, including functions.
So following on from Clojure macro to create a synonym for a function , I discovered that def can't be used to define a synonym for a macro. Below are examples I tried that Clojure doesn't allow.
;(def def-function defn)
;(def case cond)
;(def function fn)
Is it possible to define synonyms/aliases for macros in Clojure? Would it require using defmacro?
May sound (line-)noisy but
(def ^:macro case #'cond)
works!
You can use a macro:
user=> (defmacro def-function [& args] `(defn ~#args))
#'user/def-function
user=> (def-function g [] 2)
#'user/g
user=> (g)
2
Or you can use clojure.contrib.def/defalias:
user=> (use 'clojure.contrib.def)
nil
user=> (defalias def-function defn)
#'user/def-function
user=> (def-function g [] 2)
#'user/g
user=> (g)
2
To do this, in essence, you would have to rewrite the macro exactly as the original just substituting a different name (you would of course use defmacro to do this). That's the only way this is possible since macros don't return a value, but simply write out code which is to be subsequently evaluated.
Def requires binding a name to a value rather than a block of code.
(def symbol init?)
Creates and interns or locates a global var with the name of symbol and a namespace of the value of the current namespace (ns). If init is supplied, it is evaluated, and the root binding of the var is set to the resulting value. If init is not supplied, the root binding of the var is unaffected. def always applies to the root binding, even if the var is thread-bound at the point where def is called. def yields the var itself (not its value). Throws an exception if symbol is already in the namespace and not mapped to an interned var.
from Clojure: Special Forms
Macros don't evaluate their forms:
Macros are functions that manipulate forms, allowing for syntactic abstraction. If the operator of a call is a symbol that names a global var that is a macro function, that macro function is called and is passed the unevaluated operand forms [italics mine]. The return value of the macro is then evaluated in its place.
from Clojure: Evaluation
In sum, the point of the macro is to delay evaluation, so it cannot provide a value for def to bind to a symbol.
I have a symbol "a" bound to a function:
(defn a []
(println "Hello, World"))
user=> a
#<user$a__292 user$a__292#97eded>
user=> (a)
Hello, World
nil
Then I use syntax-quote, it "resolves the symbol in the current context, yielding a fully-qualified symbol", according to Clojure documentation. But why can't I use it the same way as unqualified symbol?
user=> `a
user/a
user=> (`a)
java.lang.IllegalArgumentException: Wrong number of args passed to: Symbol (NO_SOURCE_FILE:0)
Second question: if I have a symbol in a list, why can't I evaluate it the same way as if I would evaluate the symbol directly?
user=> (def l '(a 1 2))
#'user/l
user=> 'l
l
user=> (first l)
a
user=> ((first l))
java.lang.IllegalArgumentException: Wrong number of args passed to: Symbol (NO_SOURCE_FILE:0)
I have a suspicion I have a fatal flaw somewhere in the fundamental understanding of how symbols work here. What is wrong with above code?
REPL = read eval print loop. Step through the read-eval process.
READ: Clojure sees the string "(`a)", parses it and ends up with a data structure. At read time, reader macros are expanded and not much else happens. In this case, the reader expands the backquote and ends up with this:
user> (read-string "(`a)")
((quote user/a))
EVAL: Clojure tries to evaluate this object. Evaluation rules vary depending on what kind of object you're looking at.
Some objects evaluate as themselves (numbers, strings, keywords etc.).
A Symbol is evaluated by resolving it in some namespace to obtain some value (usually).
A List is evaluated by macro-expanding the list until there are no macros left, then recursively evaluating the first item in the list to obtain some resulting value, then using the value of the first item in the list to decide what to do. If the first value is a special form, special stuff happens. Otherwise the first value is treated as a function and called with the values of the rest of the list (obtained by recursively evaluating all of the list's items) as parameters.
etc.
Refer to clojure.lang.Compiler/analyzeSeq in the Clojure source to see the evaluation rules for lists, or clojure.lang.Compiler/analyzeSymbol for symbols. There are lots of other evaluation rules there.
Example
Suppose you do this:
user> (user/a)
The REPL ends up doing this internally:
user> (eval '(user/a))
Clojure sees that you're evaluating a list, so it evaluates all items in the list. The first (and only) item:
user> (eval 'user/a)
#<user$a__1811 user$a__1811#82c23d>
a is not a special form and this list doesn't need to be macroexpanded, so the symbol a is looked up in the namespace user and the resulting value here is an fn. So this fn is called.
Your code
But instead you have this:
user> (eval '((quote user/a)))
Clojure evaluates the first item in the list, which is itself a list.
user> (eval '(quote user/a))
user/a
It evaluated the first item in this sub-list, quote, which is a special form, so special rules apply and it returns its argument (the Symbol a) un-evaluated.
The symbol a is the value in this case as the fn was the value up above. So Clojure treats the Symbol itself as a function and calls it. In Clojure, anything that implements the Ifn interface is callable like an fn. It so happens that clojure.lang.Symbol implements Ifn. A Symbol called as a function expects one parameter, a collection, and it looks itself up in that collection. It's meant to be used like this:
user> ('a {'a :foo})
:foo
This is what it tries to do here. But you aren't passing any parameters, so you get the error "Wrong number of args passed to: Symbol" (it expects a collection).
For your code to work you'd need two levels of eval. This works, hopefully you can see why:
user> (eval '((eval (quote user/a))))
Hello, world
user> ((eval (first l)))
Hello, world
Note that in real code, using eval directly is usually a really bad idea. Macros are a better idea by far. I'm only using it here for demonstration.
Look in Compiler.java in the Clojure source to see how this all plays out. It's not too hard to follow.
Using a Symbol as a function is not the same thing as evaluating it. Symbols-as-functions work the same way as keywords-as-functions. Like this:
user=> (declare a)
#'user/a
user=> (def a-map {'a "value"})
#'user/a-map
user=> ('a a-map)
"value"
user=>
This is not how you would normally use a symbol. They are more commonly used for looking up vars in a namespace, and when generating code in a macro.
To break down the layers of indirection, let's define "x" as 1 and see what happens:
user=> (def x 1)
#'user/x
Using def, we have created a "var." The name of the var is the symbol user/x. The def special form returns the var itself to the repl, and this is what we can see printed. Let's try and get a hold of that var:
user=> #'x
#'user/x
The #' syntax is a reader macro that says "give me the var referred to by the following symbol." And in our case, that symbol is "x". We got the same var back as before. Vars are pointers to values, and can be dereferenced:
user=> (deref #'x)
1
But the var needs to be found before it can be dereferenced. This is where the callability of symbols come into play. A namespace is like a map, where the symbols are keys and vars are the values, and when we plainly name a symbol, we implicitly look up its var in our namespace. Like this:
user=> ('x (.getMappings *ns*))
#'user/x
Although, in reality, it is probably more like this:
user=> (.findInternedVar *ns* 'x)
#'user/x
And now we have come full circle on the journey of the unquoted symbol:
user=> (deref (.findInternedVar *ns* 'x))
1
user=> x
1
The two are not entirely equal, though. Because the evaluator does this for all symbols, including deref and *ns*.
The thing about quoting is that you essentially bypass this whole mechanism, and just get the plain symbol back. Like the #' reader macro get plain vars back, the ` and ' reader macros will get plain symbols back, with or without a namespace qualification respectively:
user=> 'x
x
user=> `x
user/x
user=> (def l '(a 1 2))
user=> ((first l))
Turn this into:
user=> (def l `(~a 1 2))
The ~ here resolves the symbol a to its corresponding var, and the backtick makes unquoting work.
In general, you must understand the difference between vars (which are bound to something) and symbols (which are never bound to anything).
I'll try to explain it (in the hope that my exaplanation does not confuse you further):
user=> (def v "content")
#'user/content
-> defines a var in the current namespace under the symbol 'v (fully qualified 'user/v, assuming this is the current namespace), and binds it (the var, not the symbol) to the object "content".
user=> v
"content"
-> resolves v to the var, and gets the bound value
user=> #'v
#'user/v
-> resolves to the var itself
user=> 'v
v
-> does not resolve anything, just a plain symbol (unfortunately, the REPL does not indicate this, printing 'v as v)
user=> `v
user/v
-> as you already quoted, resolves to the symbol in the current context (namespace), but the result is still a symbol (fully qualified), not the var user/v
user=> '(v)
(v)
-> plain quoting, does not resolve anything
user=> `(v)
(user/v)
-> syntax-quote, same as quoting, but resolves symbols to namespace-qualified symbols
user=> `(~v)
("content")
-> resolve the symbol to its var (which is implicitely dereferenced), yielding its bound object