This question already has answers here:
Why does using keywords or symbols as functions to lookup values from maps work?
(3 answers)
What do Clojure symbols do when used as functions?
(1 answer)
Closed 1 year ago.
In clojue I can invoke a symbol as a function:
('sym 1 2) => 2
('sym 1) => nil
('sym 1 2 3) => ArityException
What's the point? how are symbols as functions used in clojure?
Symbols as function behave the same way as keywords behave. They work
like get and are used for lookup.
(println ('+ {'+ + '- -}))
; → #object[clojure.core$_PLUS_ 0xe3cee7b clojure.core$_PLUS_#e3cee7b]
The 2-arity version, like get, provides is for providing a fallback, in case
the symbol is not a key where you look it up. Since Clojure is very lenient
with inputs, you will just get back nil (or the default 2 in your first
example as default) for 1, which does not support looking things up by key.
Symbols are used to lookup values in maps where the symbol itself occurs as a key. It can be used like this on a map:
('a {'a 2 'b 3})
;; => 2
('a {'b 3})
;; => nil
('a {'b 3} 119)
;; => 119
Don't be afraid to look at the source code of the Symbol class. It has two methods that implement the IFn interface. The IFn interface is implemented by Clojure functions. Here is the implementation of two invoke methods of that interface inside the Symbol class:
public Object invoke(Object obj) {
return RT.get(obj, this);
}
public Object invoke(Object obj, Object notFound) {
return RT.get(obj, this, notFound);
}
Pay attention to the occurrence of the this keyword in the code above, which is the symbol itself passed as key argument to the clojure.lang.RT.get method in order to lookup the value from a map.
In fact, the Symbol class implements the IFn interface indirectly through the AFn abstract class as seen at the top of the Symbol.java file: public class Symbol extends AFn.
What is the point?
Answer: Convenience, brevity. You could just as well call the get function to lookup a symbol in a map:
(get {'a 2 'b 3} 'a)
;; => 2
Remember that in Clojure you can typically use any Java object as a key in a Clojure hash map as long as it implements the .hashcode and .equals method. Symbols are a form of interned strings and are therefore very efficient to lookup. Because of their suitability to use as keys in a map, it is natural to implement the IFninterface for convenience.
Another class that is related to Symbol is Keyword which is also a form of interned string. The Keyword class is in fact based internally on the Symbol class.
Related
Whenever I type the following on the REPL
(defn test_function
[]
()
)
The output is -
#'clojure.repl/test_function
As functions are objects in Clojure, how to get the value of the reference that refers to this function object?
In Clojure, a Var (the Java class is clojure.lang.Var) is a container in which you can store any immutable value. You can even store a different immutable value into this container at a later time - but, for now, let's ignore that. The container can be referred to using a name (aka symbol). The mapping between the name and the Var is stored in each namespace. So, when you say
(defn testf [] ())
that is (more or less) equivalent to
(def testf (fn [] ()))
That will create a Var, store the newly created function object into that Var, and create a mapping between the symbol testf and the Var. You can get the function object by just evaluating the symbol. Thus
user=> testf
#object[user$test_function 0x67207d8a "user$testf#67207d8a"]
user=> (class testf)
user$testf
That tells you that the function is a Java object of the class user$testf.
If you want to inspect the Var itself (rather than the value that it contains), you can do the following
user=> (var testf)
#'user/testf
user=> (class (var testf))
clojure.lang.Var
which tells you that the Var is #'user/testf and the Java class that implements a Clojure Var is clojure.lang.Var.
You might benefit from reading Clojure - Vars and the Global Environment or the sources for more details.
To finally answer your question ... you can consider the Var as the holder to a reference to the object. In that case, you can "print" the Var that is bound to a symbol foo by evaluating (var foo). And you can "print" the object itself by evaluating foo.
Clojure compiles your code down to JVM byte code if you load source
files and there is no way around to create classes to do that
(everything except primitive types is an Object descendant in the JVM).
You can see lot's of what is going on, if you check out an uberjar of
your lein project or if you AOT compile clj files.
You can get the class from your function:
(defn test-function []
(println :hello))
(println (class test-function))
; ⇒ user$test_function
The $ indicates, that there is an inner class used; this is just
a convention. Also the - has changed to a _, which clojure calls
"munging".
Now you can create a new instance of that class and you can .invoke it
(as it's implements the
IFn
interface):
(let [tf (new user$test_function)]
(.invoke tf))
; ⇒ :hello
Is var in Clojure is stored as an object?
Question 1:
If yes, then object of which class?
Question 2:
In Java, we have references stored on the thread stack and the they refer to the objects stored on process heap.
How to interpret vars in Clojure like the analogy of objects in Java.
EDITS:
To try the first question by myself, I used type/class to check the class of the object.
Case 1:
(def a 100)
(type a)
O/P:
java.lang.Long
In this case, it is clear that a is an object of Long class.
But, how to check the same thing for functions. For example -
case 2:
(type identity)
O/P:
clojure.core$identity
So, from the case 2, type returns the namespace instead of class.
How to get the class?
If you call (type x) on some previously defined x, then you are using the value of x. If you want to find out about the type of the var, you need to look at the var:
user=> (type #'a)
clojure.lang.Var
A naive way to get information about object is the bean function
user=> (bean #'a)
{:watches {}, :validator nil, :public true, :threadBinding nil, :bound true, :dynamic false, :macro false, :class clojure.lang.Var, :rawRoot 42, :tag nil}
Finding out about the hierarchy via parents:
user=> (parents (class #'a))
#{java.io.Serializable clojure.lang.IFn clojure.lang.Settable clojure.lang.IRef clojure.lang.ARef}
Everything in the JVM is an Object-descendant (except the primitive types).
Updated - typed original answer too quickly
The concept of a "Var" is built into the Clojure language/compiler. A Var is normally accessed via a namespaced symbol. Each namespace is implemented like a map, where the map keys are Clojure symbols and the map values are Clojure Var objects.
Each Var object is a mutable object that points to an immutable Clojure "value" (eg 5, [1 2 3], {:a 1 :b 2} etc).
Please see this list of documentation sources, esp "Getting Clojure". For the nitty gritty details, look into the Clojure namespace and its implementation.
Clojure CheatSheet
I'd like to hide the details of my persistence layer behind some sort of interface. In Java I would just create an interface and choose the correct implementation in some sort of bootup function. I'm still struggling on how to do that in Clojure. I don't necessarily need any type-safety here, I trust in my unit tests to find any issues there. The best thing I could come up with was to create a map containing anonymous functions with specific keys, like so:
(def crux-db {
:get-by-id (fn [id] (get-obj...))
:save (fn [id obj] (store-obj...))
})
(def fs-db {
:get-by-id (fn [id] (get-obj...))
:save (fn [id obj] (store-obj...))
})
If I'm not missing something, this would allow me to replace the database implementation by def-ing (def db crux-db) or (def db fs-db), as long as all the functions exist in all implementation maps. Somehow I feel like this is not the clojure way but I can't put my finger on it. Is there another way to do this?
Protocols are a way to do that. They let you define what functions should be there. And
you can later implement them for different things with e.g.
a defrecord.
A protocol is a named set of named methods and their signatures, defined using defprotocol:
(defprotocol AProtocol
"A doc string for AProtocol abstraction"
(bar [a b] "bar docs")
(baz [a] [a b] [a b c] "baz docs"))
No implementations are provided
Docs can be specified for the protocol and the functions
The above yields a set of polymorphic functions and a protocol object
all are namespace-qualified by the namespace enclosing the definition
The resulting functions dispatch on the type of their first argument, and thus must have at least one argument
defprotocol is dynamic, and does not require AOT compilation
defprotocol will automatically generate a corresponding interface, with the same name as the protocol, e.g. given a protocol my.ns/Protocol, an interface my.ns.Protocol. The interface will have methods corresponding to the protocol functions, and the protocol will automatically work with instances of the interface.
Since you mentioned crux in your code, you can have a peek at how they
use it
here
and then using defrecords to implement some of
them
There are several ways to achieve this. One way would be to use protocols. The other way would be to just use higher-order functions, where you would "inject" the specific function and expose it like so:
(defn get-by-id-wrapper [implementation]
(fn [id]
(implementation id)
...))
(defn cruxdb-get-by-id [id]
...)
(def get-by-id (get-by-id-wrapper cruxdb-get-by-id))
Also worth mentioning here are libraries like component or integrant which are used to manage the lifecylce of state.
I am interested in if it is possible to redefine or override the bindings that are the result of a closure when programming in Clojure?
For example I can do the following just fine:
(defn triple-adder-fn [a b] (fn [x] (+ x a b)))
(def triple-adder (triple-adder-fn 1 2))
(triple-adder 3)
;; => 6
However this creates a local closure that has the bindings of a = 1 and b = 2 and when I call triple-adder it uses them accordingly.
Now the question is could I do something like the following mock code that would allow me to override those local bindings?
(binding ['a 5
'b 6]
(triple-adder 3))
;; => 14
For my simple example it'd be real easy to call the triple-adder-fn to get a new function with new bindings. However, for my actual situation, I am in a position where I don't actually control the triple-adder-fn and only have access to the resulting function.
From your description there is no solution to your problem. Once a closure has "closed over" free params, they can't be changed.
To solve this, you would have to make a new closure, or perhaps redefine triple-adder-fn to use global dynamic vars instead of local parameters. Or, you could copy triple-adder-fn and change the copy to work as you wish.
I would like to provide some methods for a clojure protocol starting with the : character. Is there any way to override this in Clojure?
Don't think so. Clojure keywords are implemented in the reader and I don't think there's any way of overriding that behavior.
When you use a keyword as a function, that is equivalent to (get arg :keyword). You can extend what that does by implementing ILookup in your protocol.
Joost.
Sounds like a bad idea: colons are reserved for keywords so even if you could do this I think it would make for some confusing code.
You can of course, put a function inside a record mapped by a keyword:
(defrecord Foo [])
(def foo (Foo. nil {:method (fn [a b] (* a b))}))
((:method foo) 7 10)
=> 70
I've found this to be a useful trick sometimes......