How does argument passing work in Clojure? - clojure

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

Related

What is the difference between with-redefs and with-redefs-fn in Clojure?

I would like to understand difference between with-redefs and with-redefs-fn.
Concrete examples would be great to understand the fns behaviours.
They're basically the same, the main difference is that with-redefs lets you write out the body explicitly (like in a let), while with-redefs-fn requires a function as the argument, so you may need to wrap what you want in a lambda. Additionally, with-redefs lets you provide bindings using a vector (again, like let), while with-redefs-fn wants a map. I'd argue that both of these differences are just superficial.
e.g.
(with-redefs [http/post (fn [url] {:body "Goodbye world"})]
(is (= {:body "Goodbye world"} (http/post "http://service.com/greet"))))
vs
(with-redefs-fn {#'http/post (fn [url] {:body "Goodbye world"})}
(fn [] (is (= {:body "Goodbye world"} (http/post "http://service.com/greet")))))
In fact, with-redefs is defined in terms of with-redefs-fn, and basically just wraps the body in an anonymous function before passing everything to with-redefs-fn: https://github.com/clojure/clojure/blob/e3c4d2e8c7538cfda40accd5c410a584495cb357/src/clj/clojure/core.clj#L7404
I would ignore with-redefs-fn and use only with-redefs since it is simpler and has the same abilities. Also, beware that the notation #'http/post requires you to use the var for http/post, not the function itself.
For a description of how a Clojure var works, please see this question: When to use a Var instead of a function? It is similar to a C pointer.
In clojure, when you see foo, it is a symbol. When you see #'foo, it is a shortcut for (var foo) which is a "special form" (i.e. a Clojure built-in, not a regular function), which returns the var that foo points to. The var in turn points the the value of foo.

Performance concern of defining functions in a `let` form

Is there any performance penalty for defining anonymous functions in a let form and calling the outer function repeatedly? Like this:
(defn bar [x y]
(let [foo (fn [x] (* x x))]
(+ (foo x) (foo y))))
Compared to defining foo as a separate function, like this:
(defn foo [x] (* x x))
(defn bar [x y] (+ (foo x) (foo y)))
I understood the lexical scope of foo is different in these two cases, I'm just concerned if the foo function would be defined over and over again when calling bar multiple times.
I guess the answer is no, i.e., there is no penalty for this, but how did clojure do this?
Thank you!
let local approach:
foo is compiled only once (when the top-level form is). The result of this compilation is a class implementing the clojure.lang.IFn interface; the actual body lives in the invoke(Object) method of that class. At runtime, each time control reaches the point in bar where the foo local is introduced, a fresh instance of that class is allocated; the two calls to foo use that instance of that class.
Here is a simple way to prove the "single compilation" property at the REPL:
(defn bar [x y]
(let [foo (fn [x] (* x x))]
foo))
(identical? (class (bar 1 2)) (class (bar 1 2)))
;= true
NB. Clojure is smart enough to notice that foo is not an "actual closure" (it closes over the parameters of bar, but it doesn't actually use them), so the runtime representation of foo does not carry any extra fields that a closure would, but a fresh instance of foo's class is nevertheless allocated on each call to bar.
Separate defn approach:
There is a single instance of foo, however calling it involves an indirection through a Var, which itself comes with a non-zero cost. That cost is generally not worth worrying about in all but the most performance-sensitive code, but it's there, so factoring out a local function may not necessarily be a performance win. As usual, if it's worth optimizing, it's worth measuring/benchmarking first.
let over lambda
There is also the final option mentioned by Daniel, where the let goes around, and not inside, the defn. With that approach, there is a single instance of (the class of) foo; it is stored in a field inside bar; and it is used for all calls to foo inside bar.
The answer is yes, there will be a penalty for this but as Michael points out in the let local approach section, it is minimal.
If you want the lexical scoping as you described, then wrap the let block defining foo around the defn for bar. That will do what you are asking. However it is a pattern not commonly seen in Clojure code.

Checking Clojure pre-conditions without running the function?

I have one function that does some (possibly lengthy) work (defn workwork [x] ...) and some other functions to check if the call will succeed ahead of time (defn workwork-precondition-1 [x] ...).
The precondition functions should be evaluated every time workwork is called (e.g. using :pre). The precondition functions should also be collected (and:ed) in a single function and made available to client code directly (e.g. to disable a button).
Which is the idiomatic way to solve this in Clojure while avoiding code duplication?
In particular, is there any way to evaluate the pre-conditions of a function without running the function body?
You can just collect your preconditions into a function:
(defn foo-pre [x]
(even? x))
Then call the function in a :pre-style precondition:
(defn foo [x]
{:pre [(foo-pre x)]}
…)
For functions introduced using defn, you can extract the :pre-style preconditions from the metadata on the Var:
(-> #'foo meta :arglists first meta)
;= {:pre [(foo-pre x)]}
And similarly for the :arglists entries for any other arities.
There are two caveats here:
The automatically-generated :arglists entry in the Var's metadata maybe be overridden. Overriding :arglists results in the above kind of useful automatically-generated metadata to be thrown out.
The {:pre [(foo-pre x)]} value returned by the above (-> #'foo meta …) expression contains foo-pre as a literal symbol – it'd be your responsibility to figure out which function it referred to at foo's point of definition. (This may or may not be possible – for example foo could be defn'd inside a top-level let or letfn form, with foo-pre a local function.)
And finally, anonymous functions may use :pre and :post, but there is currently no mechanism for extracting them from the function itself.
to evaluate the function precondition without running the function body,you can use robert-hooke library https://github.com/technomancy/robert-hooke/
(use 'robert.hooke)
(defn workwork [x] ...)
(defn workwork-precondition-1
[f x]
(if (precondition-1-satisfied? x)
(f x)
:precondition-1-not-satisfied))
(add-hook #'workwork #'workwork-precondition-1)

Clojure, defn, defn-, public/private, defaults

defn = public
defn- = private
Perhaps I have bad Clojure coding style -- but I find that most functions I write in Clojure are small helper functions that I do not want to expose.
Is there some configuration option, where:
defn = private by default,
and to make something public, I have to do defn+?
Thanks!
No. There is not.
An alternative approach which might or might not work for you is to declare a foo.bar.internal namespace containing all the private helpers which is used by your foo.bar namespace. This has advantages over private function declarations when you want to use private functions in macro expansions.
If the "helper functions" are very likely to be used once, you could choose to make them locals of your bigger functions, or write them as anonymous functions. See letfn: http://clojuredocs.org/clojure_core/clojure.core/letfn and http://clojuredocs.org/clojure_core/clojure.core/fn.
I hardly ever use letfn myself.
The beauty of Clojure being a Lisp, is that you can build and adapt the language to suit your needs. I highly recommend you read On Lisp, by Paul Graham. He now gives his book away for free.
Regarding your suggestion of defn+ vs defn vs defn-. This sound to me like a good case for writing your own Macro. defn is a function and defn- is a macro. You can simply redefine them as you wish, or wrap them in your own.
Here follows a suggestion to implementation, based mainly on Clojure's own implementation - including a simple utility, and a test.
(defmacro defn+
"same as Clojure's defn, yielding public def"
[name & decls]
(list* `defn (with-meta name (assoc (meta name) :public true)) decls))
(defmacro defn
"same as Clojure's defn-, yielding non-public def"
[name & decls]
(list* `defn (with-meta name (assoc (meta name) :private true)) decls))
(defn mac1
"same as `macroexpand-1`"
[form]
(. clojure.lang.Compiler (macroexpand1 form)))
(let [ ex1 (mac1 '(defn f1 [] (println "Hello me.")))
ex2 (mac1 '(defn+ f2 [] (println "Hello World!"))) ]
(defn f1 [] (println "Hello me."))
(defn+ f2 [] (println "Hello World!"))
(prn ex1) (prn (meta #'f1)) (f1)
(prn ex2) (prn (meta #'f2)) (f2) )
As stated by #kotarak, there is no way (as far as I know) to do that, nor is it desirable.
Here is why I dislike defn- :
I found out that when using various Clojure libraries I sometimes need to slightly modify one function to better suit my particular needs.
It is often something quite small, and that makes sense only in my particular case. Often this is just a char or two.
But when this function reuses internal private functions, it makes it harder to modify. I have to copy-paste all those private functions.
I understand that this is a way for the programmer to say that "this might change without notice".
Regardless, I would like the opposite convention :
always use defn, which makes everything public
use defn+ (that doesn't exist yet) to specify to the programmer which functions are part of the public API that he is supposed to use. defn+ should be no different from defnotherwise.
Also please note that it is possible to access private functions anyway :
;; in namespace user
user> (defn- secret []
"TOP SECRET")
;; from another namespace
(#'user/secret) ;;=> "TOP SECRET"

In Clojure, how to use a java Class dynamically?

In Clojure, how to use a java Class that is stored in a variable?
How should I fix the following code?
(def a java.lang.String)
(new a "1"); CompilerException java.lang.IllegalArgumentException: Unable to resolve classname: a
And why this one works fine?
(def a str)
(a "1")
The most elegant solution is to write construct that does the same as new but is able to receive a class dynamically:
(defn construct [klass & args]
(clojure.lang.Reflector/invokeConstructor klass (into-array Object args)))
(def a HashSet)
(construct a '(1 2 3)); It works!!!
This solution overcomes the limitation of #mikera's answer (see comments).
Special Thanks to #Michał Marczyk that made me aware of invokeConstructor answering another question of mine: Clojure: how to create a record inside a function?.
Another option is to store the call to the constructor as an anonymous function. In our case:
(def a #(String. %1))
(a "111"); "111"
When you define a in this way, you get a var containing a java.lang.Class
(def a java.lang.String)
(type a)
=> java.lang.Class
You then have 2 options:
A: Construct the new instance dynamically by finding the Java constructor using the reflection API. Note that as Yehonathan points out you need to use the exact class defined in the constructor signature (a subclass won't work as it won't find the correct signature):
(defn construct [klass & args]
(.newInstance
(.getConstructor klass (into-array java.lang.Class (map type args)))
(object-array args)))
(construct a "Foobar!")
=> "Foobar!"
B: Construct using Clojure's Java interop, which will require an eval:
(defn new-class [klass & args]
(eval `(new ~klass ~#args)))
(new-class a "Hello!")
=> "Hello!"
Note that method A is considerably faster (about 60x faster on my machine), I think mainly because it avoids the overhead of invoking the Clojure compiler for each eval statement.
The problem is that Clojure implements Java interop using a number of special forms:
user=> (doc new)
-------------------------
new
Special Form
Please see http://clojure.org/special_forms#new
nil
this basically means the "normal" Clojure syntax is altered to allow for handier constructs when calling Java. As a naive reflection solution to your dynamic Java needs, you can leverage eval:
user=> (def a String) ; java.lang package is implicitly imported
#'user/a
user=> `(new ~a "test") ; syntax quote to create the correct form
(new java.lang.String "test")
user=> (eval `(new ~a "test")) ; eval to execute
"test"
The same strategy works with all the other interop special forms, like method invocation.
EDIT: look also at the answer from #mikera for a more performing alternative via the Java reflection API.