Let's say that I have the following map in Clojure:
(def person {:name "Jack" :say-hello #(print "hello")})
Question 1:
Is it possible to call the anonymous function of key :say-hello? How?
Question 2
Is it possible to instantiate / clone person vector with different values?
(:say-hello person) returns the function, so ((:say-hello person)) calls it.
The function is just a value like all other values, so you can pass it around and create new maps from it.
Related
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 have this function:
(defn get-validator []
(UrlValidator. (into-array ["https"])))
I want it to be evaluated only once, on the first call, then just return the result. Which is the better way to write it:
(def get-validator (UrlValidator. (into-array ["https"])))
(def ^:const get-validator (UrlValidator. (into-array ["https"])))
(defonce get-validator (UrlValidator. (into-array ["https"])))
Or is there another way that is better? Documentation suggests that defonce is the correct one, but it's not clearly stated.
First of all, def sets a var with the given name and optionally the
given "init" value in that var, when the namespace is loaded/compiled
(note that there is basically not much of a difference between loading
and compiling and that's the reason, why you don't want to have
side-effects in your def).
Roughly all three versions are the same, with the following differences:
:^const allows inlining this value; so this effects the following
forms, when they are compiled and might improve performance in the
following code
defonce prevents re-def-ining the var again once the namespace is
reloaded; this is most useful if you def mutable state, that you
want to survive over reloading your code
In any case, requiring the ns for the first time, will execute the code
to init the var. Then it is basically left alone (imagine a static
property in a Java class with a static initializer).
All that said: if UrlValidator has internal state you might still be
better off using a function to create a fresh one, whenever you need it.
Another approach, assuming UrlValidator. is referentially transparent, is to use clojure.core/memoize.
So
(defn get-validator []
(UrlValidator. (into-array ["https"])))
(def uval (memoize get-validator))
And then use (uval) whenever you need the validator. Because of the memoization, get-validator will be called only once.
This approach will make only one call to UrlValidator. the first time (uval) is executed. All the other suggestions will call UrlValidator., once, when the namespace is loaded.
I'm using an external library, and passing it a function that I write. Something like this, for example:
(ext-func my-func) ...
my-func needs to be given some data to do computation. The way I see it, I have two basic choices:
1) Write my-func in such a way that it accepts my data, and returns a function, which will then have the data bound to it via closure when the external library calls it. For example:
(defn my-func
[mydata]
(fn []
(... access to mydata via closure ... )))
(ext-func (my-func somedata))
2) Do not return a function from my-func, but bind data to it when I pass it to ext-func:
(defn my-func
[mydata]
(... evaluate, use mydata, etc.))
(ext-func (partial my-func somedata))
I suppose which one to use could be answered by how I intend to use the function otherwise. If I'm going to be using it other places, I may prefer not to return a function, for example. But, all other things being equal...
...which of these is the more idiomatic approach?
partial is just sugar to create the anonymous function. Check out it's source. So, effectively they're equivalent. Take your pick. Neither is more idiomatic, just a matter of personal preference.
I know that in Java, if I pass an object to a method as an argument, then the method will let the argument variable point to the same object rather than making a duplicate. How about in Clojure? For example:
(defn print-from-reader [rdr]
(print (.read rdr)))
(...inside some code...
(with-open [rdr (Reader file)]
(print-from-rader rdr)))
Does print-from-reader make another copy of rdr in memory when rdr is passed in, or it's pointing to the same rdr that's already created by with-open binding?
And is there any way to check if two clojure instances are pointing to same memory?
Sorry about my bad terms such as "pointing to" and "instances", I am a newbie in Clojure and still learning it. :-)
According to answer to this question on google groups it's pass by value.
Clojure inherits the argument-passing semantics from Java. So it is pass-by-value, where the value passed is an object reference. In addition there are optimization facilities that enable the passing of primitive-typed values.
So functions don't make copies when parameters are passed. rdr in your code will be the same instance.
Makes sense to implement it like that due to java interoperability - otherwise you couldn't (easily) modify java objects' state with its method.
You can test it easily:
(import 'java.util.HashMap)
(def m (new HashMap))
(defn foo [m] (defn bar [m] (.put m "testkey" "testvalue")) (bar m) (println (get m "testkey")))
(foo m)
Results in :
testvalue
nil
If bar created its own copy of m, then the println wouldn't print the value assigned inside bar.
Clojure is pass-by-value just like Java. I think of it as, the references are passed by value.
It isn't a stretch for Clojure to work like this, Scheme and Common Lisp behave the same way.
You can test whether two references point to the same memory with identical?:
(identical? x y)
Tests if 2 arguments are the same object
Apparently, you can't call apply with a record constructor:
(defrecord Foo. [id field])
(apply Foo. my-list)
fails at read time because it is not expecting Foo. in that place.
The only obvious workaround I could think of was to add a factory function:
(make-foo [id field] (Foo. id field))
which can be apply'ed of course.
Am I missing anything? I'd expect this from C#/Java but just thought it was a bit disappointing in Clojure...
Circling back on this post-1.3....
In Clojure 1.3, defrecord creates two generated constructor functions. Given:
(defrecord Person [first last])
this will create a positional constructor function ->Person:
(->Person "alex" "miller")
and a map constructor function map->Person:
(map->Person {:first "string"})
Because this is a map, all keys are optional and take on a nil value in the constructed object.
You should require/use these functions from the ns where you declare the record, but you do not need to import the record class as you would when using the Java class constructor.
More details:
http://dev.clojure.org/display/design/defrecord+improvements
http://groups.google.com/group/clojure/browse_thread/thread/ce22faf3657ca00a/beb75e61ae0d3f53
Foo. is a Java class constructor so it has typical Java interop constraints with how you call it. Creating a constructor function is a common solution (it also means you don't have to import the Foo when in a different namespace).
The problem is known and there is lots of talk about it on the Clojure mailing list. More support will probably be added in future Clojure versions.
For now you have to use your own functions or use https://github.com/david-mcneil/defrecord2 which supports some features like:
print in an eval'able form
provide clojure function as constructor
accept named parameters (maps) in constructor
participate in pre/post walk multi-method