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.
Related
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.
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 am using binding as a means to make it easier to pass around state within a call. I currently have something like the following
(binding [*private-key-path* "/Users/dcapwell/.ssh/id_dsa"]
(binding [*session* (session "localhost")]
...
The reason that I need to do this is that the session function requires private-key-path to be defined. Since binding doesn't allow related values, is there any simpler way to do the above without the needed nesting?
EDIT:
Currently prototyping using clj-ssh.ssh. The plan is to make most of my current usage of binding to be a static config (most are static values already, so read once on boot). Was using binding as a way to make prototyping easier so I didn't have to keep passing things around while seeing how the API worked.
I was just curios how I can get the bindings to be dependent on each other. When I use let, the second binding has access to the first one, but it seems that when I do this that the second binding doesn't have access to the first. I would assume there would be another function that acts like binding but would allow the second binding to have access to the first. I can also see this not existing in the default since its more of state than anything else.
Edited: some experiment in the REPL
(def ^:dynamic *a* "a not bound")
(def ^:dynamic *b* "b not bound")
(defn show-a! []
*a*)
(binding [*a* 1 *b* (show-a!)] *b*) ;; => "a not bound"
(binding [*a* 1]
(binding [*b* (show-a!)]
*b*)) ;; => 1
I was surprised to know the given code is NOT the same as:
(binding [*private-key-path* "/Users/dcapwell/.ssh/id_dsa"
*session* (session "localhost")]
...)
so Clojure tends to have less parentheses than other Lisps in let forms cases but not binding.
Please think about your overall code (and/or API design?) again and again. Dynamic bindings are bad. You will suffer soon. Tip: make more and more code unit-testable.
I'm not sure what you are trying to do, so I recommend this:
A feature called "Graph" for structural computation. Never worry about dependencies between functions again!
https://github.com/Prismatic/plumbing
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
I wish to know what is the idiomatic way to achieve data encapsulation
in Clojure. Below I describe my particular use case to motivate the example
code I provide.
I have code in a dbaccess module that performs a complex
database query to fetch some
data from a database. I also have a number of functions that operate
on the returned, raw, data. These functions then provide more
processed, refined views of the data and are invoked numerous
times with different arguments from
other modules in the system. Let's call them "API functions".
The query is heavy and should execute only once at the beginning,
the API functions will then operate on the raw-data
from memory without having to perform another DB query.
Here's my approach using closures:
dbaccess module
(ns dbaccess)
(let
[raw-data (complex-database-query)]
(defn create-client-names []
(fn [some-args] raw-data))
(defn create-client-portfolio []
(fn [some-args] raw-data))
(defn create-client-stocks []
(fn [some-args] raw-data)))
some other client module
(def client-names (create-client-names))
(doall (map println (client-names "Baltimore")))
I dislike having to name the created functions that have
captured the raw-data.
More importantly, the code above doesn't allow
the client modules to configure aspects of the query before it executes
(e.g. the database connection information).
If, on the other hand, closures are not used I will have to
explicitly pass the raw-data
back and forth between the dbaccess module and the other modules that need to invoke API functions.
Is there a better way? Should I perhaps use mutable state in the dbaccess module?
I will have to explicitly pass the raw-data back and forth between the
dbaccess module and the other modules that need to invoke API
functions
You should do this, pass the data the function need explicitly, because:
This will lead to loose coupling between how the data is created and how it is processed.
Functions will be more clear to understand while reading it.
Testing of the individual function will be easy as you can mock data easily.
I guess you don't need let in this case:
(def ^:private raw-data (promise))
(future (deliver raw-date (complex-database-query))) ;; A. Webb mentioned this
(defn create-client-names []
(fn [some-args] #raw-data))
...
Why aren't create-client-names and other functions just
(defn create-client-names [some-args]
#raw-data)
...
?
And IMO It's better to use doseq instead of map if there is imperative body:
(doseq [name (client-names "Baltimore")]
(println name))