I started to learn clojure so pardon for noob question
I try to implement following function
pseudo code:
function(x y) {
if (x != oldX)
dosomething(y);
oldX = x;
}
oldX is global variable
How can i properly do this the clojure way?
I wrote something this but is this correct way or not?
(defn rec [x y]
(if (not= x oldX)
(println "y"))
(def oldX x))
defs should only be top level. (def oldX (atom nil)) and (reset! oldX x) is more correct.
Clojure is a functional programming language. This is a different paradigm than it is used in other popular programming languages like Python. It appears that you are not thinking functional ;-)
The Clojure-way would be not to use a variable for this case. Just solve it with functions or, if it is really necessary, use atoms or refs, depending on what you need.
An atom or a ref can be modified within a function to store the old result - this may be the solution you are looking for.
But for most cases there exists a simpler solution without the need for a variable like oldX - and this is were the benefits of a functional language come into place.
Your Code
(defn rec [x y]
(if (not= x oldX)
(println "y"))
(def oldX x))
As #cgrand already said, def should only be used on the first level.
You use if, but you define only the true case. If you check only, if a certain statement is true, then you can use when.
The last line defines a new oldX in the scope of the function rec. This is a new variable, not the old one with a new value, in the active namespace (thanks to #user1571406).
I think what you're looking for is something like this. I've tried to keep your var names as your originals, so it's easier to see the difference.
Use an atom to store oldX
Use a compare-and-set! to determine whether you've changed the atom
If you've changed the atom, call your (dosomething y)
Note: This is kind of like a swap!, except swap! returns the value swapped in, not whether or not your call to swap! changed the value, so it's less useful here.
Something like this:
(defn dosomething [y]
;; does something, presumably with y...
)
(defonce x-atom (atom nil))
(defn swap-x
"swaps x-atom for new x, calls (dosomething ...) with y if successful"
[x y]
(let [oldX #x-atom] ; get the cur value of x
(when (not= oldX x)
(when (compare-and-set! x-atom oldX x)
(dosomething y))
If the compare-and-set! fails, then it means some other thread has modified the atom since you got its value. If you need to handle that case, the answer is a little different. You could either use a swap! or a loop+recur. If you're unfamiliar, a swap! is sort of like a compare-and-set! that recurs on failure.
Related
Suppose I've got a function (remove-bad-nodes g) that returns a sequence like this:
[updated-g bad-nodes]
where updated-g is a graph with its bad nodes removed, and bad-nodes is a collection containing the removed nodes.
As an argument to a function or inside a let, I could destructure it like this:
(let [[g bads] (remove-bad-nodes g)]
...)
but that only defines local variables. How could I do that in the REPL, so that in future commands I can refer to the updated graph as g and the removed nodes as bads? The first thing that comes to mind is this:
(def [g bads] (remove-bad-nodes g)
but that doesn't work, because def needs its first argument to be a Symbol.
Note that I'm not asking why def doesn't have syntax like let; there's already a question about that. I'm wondering what is a convenient, practical way to work in the REPL with functions that return "multiple values". If there's some reason why in normal Clojure practice there's no need to destructure in the REPL, because you do something else instead, explaining that might make a useful answer. I've been running into this a lot lately, which is why I'm asking. Usually, but not always, these functions return an updated version of something along with some other information. In side-effecting code, the function would modify the object and return only one value (the removed nodes, in the example), but obviously that's not the Clojurely way to do it.
I think the way to work with such functions in the repl is just to not def your intermediate results unless they are particularly interesting; for interesting-enough intermediate results it's not a big hassle to either def them to a single name, or to write multiple defs inside a destructuring form.
For example, instead of
(def [x y] (foo))
(def [a b] (bar x y))
you could write
(let [[x y] (foo),
[x' y'] (bar x y)])
(def a x') ; or maybe leave this out if `a` isn't that interesting
(def b y'))
A nice side effect of this is that the code you write while playing around in the repl will look much more similar to the code you will one day add to your source file, where you will surely not be defing things over and over, but rather destructuring them, passing them to functions, and so on. It will be easier to adapt the information you learned at the repl into a real program.
There's nothing unique about destructuring w/r/t the REPL. The answer to your question is essentially the same as this question. I think your options are:
let:
(let [[light burnt just-right] (classify-toasts (make-lots-of-toast))]
(prn light burnt just-right))
def the individual values:
(def result (classify-toasts (make-lots-of-toast)))
(def light (nth result 0))
(def burnt (nth result 1))
(def just-right (nth result 2))
Or write a macro to do that def work for you.
You could also consider a different representation if your function is always returning a 3-tuple/vector e.g. you could alternatively return a map from classify-toasts:
{:light 1, :burnt 2, :just-right 3}
And then when you need one of those values, destructure the map using the keywords wherever you need:
(:light the-map) => 1
Observe:
user=> (def results [1 2 3])
#'user/results
user=> (let [[light burnt just-right] results] (def light light) (def burnt burnt) (def just-right just-right))
#'user/just-right
user=> light
1
user=> burnt
2
user=> just-right
3
What's the (most) idiomatic Clojure representation of no-op? I.e.,
(def r (ref {}))
...
(let [der #r]
(match [(:a der) (:b der)]
[nil nil] (do (fill-in-a) (fill-in-b))
[_ nil] (fill-in-b)
[nil _] (fill-in-a)
[_ _] ????))
Python has pass. What should I be using in Clojure?
ETA: I ask mostly because I've run into places (cond, e.g.) where not supplying anything causes an error. I realize that "most" of the time, an equivalent of pass isn't needed, but when it is, I'd like to know what's the most Clojuric.
I see the keyword :default used in cases like this fairly commonly.
It has the nice property of being recognizable in the output and or logs. This way when you see a log line like: "process completed :default" it's obvious that nothing actually ran. This takes advantage of the fact that keywords are truthy in Clojure so the default will be counted as a success.
There are no "statements" in Clojure, but there are an infinite number of ways to "do nothing". An empty do block (do), literally indicates that one is "doing nothing" and evaluates to nil. Also, I agree with the comment that the question itself indicates that you are not using Clojure in an idiomatic way, regardless of this specific stylistic question.
The most analogous thing that I can think of in Clojure to a "statement that does nothing" from imperative programming would be a function that does nothing. There are a couple of built-ins that can help you here: identity is a single-arg function that simply returns its argument, and constantly is a higher-order function that accepts a value, and returns a function that will accept any number of arguments and return that value. Both are useful as placeholders in situations where you need to pass a function but don't want that function to actually do much of anything. A simple example:
(defn twizzle [x]
(let [f (cond (even? x) (partial * 4)
(= 0 (rem x 3)) (partial + 2)
:else identity)]
(f (inc x))))
Rewriting this function to "do nothing" in the default case, while possible, would require an awkward rewrite without the use of identity.
I am new to Clojure an Functional Programming both.
I tried my best, understanding the loop construct.
I can use it, I can look at a code written with it and tell the output but what I dont understand is,How does it work ?
is it same as writing an anonymous function with parameters and then keeping recur at the tail with same arity and new values ?
is it an inbuilt macro or something for it ?
Actually, loop is not a function or a macro. It is a special form. It works just like let (which is also a special form) except that it acts as a target for recur.
One way to differentiate functions, macros, and special forms is to examine how their arguments are evaluated:
Function arguments are always evaluated, and then the results are passed to the function.
Macro arguments are not evaluated until the macro expands to a new unevaluated form.
Special form arguments are not evaluated when passed, but the special form may or may not choose to evaluate them internally.
dbyrne's answer is all true, and good, but I'd like to address your further question "Is it the same as writing an anonymous function with parameters and then recur at the tail with same arity and new values?". Yes, it is exactly like that:
(loop [x 1, y 2]
(if (whatever x y)
(recur (inc x) (dec y))
(* x y)))
is functionally identical to
((fn [x y]
(if (whatever x y)
(recur (inc x) (dec y))
(* x y)))
1 2)
If loop didn't exist, you could write it as a simple macro that emits this sort of form, but the compiler has a special loop form which is faster.
(defmacro loop [bindings & body]
(let [bindings (partition 2 bindings)]
`((fn [~#(map first bindings)]
(do ~#body))
~#(map second bindings))))
How do I programmatically figure out which Vars may affect the results of a function defined in Clojure?
Consider this definition of a Clojure function:
(def ^:dynamic *increment* 3)
(defn f [x]
(+ x *increment*))
This is a function of x, but also of *increment* (and also of clojure.core/+(1); but I'm less concerned with that). When writing tests for this function, I want to make sure that I control all relevant inputs, so I do something like this:
(assert (= (binding [*increment* 3] (f 1)) 4))
(assert (= (binding [*increment* -1] (f 1)) 0))
(Imagine that *increment* is a configuration value that someone might reasonably change; I don't want this function's tests to need changing when this happens.)
My question is: how do I write an assertion that the value of (f 1) can depend on *increment* but not on any other Var? Because I expect that one day someone will refactor some code and cause the function to be
(defn f [x]
(+ x *increment* *additional-increment*))
and neglect to update the test, and I would like to have the test fail even if *additional-increment* is zero.
This is of course a simplified example – in a large system, there can be lots of dynamic Vars, and they can get referenced through a long chain of function calls. The solution needs to work even if f calls g which calls h which references a Var. It would be great if it didn't claim that (with-out-str (prn "foo")) depends on *out*, but this is less important. If the code being analyzed calls eval or uses Java interop, of course all bets are off.
I can think of three categories of solutions:
Get the information from the compiler
I imagine the compiler does scan function definitions for the necessary information, because if I try to refer to a nonexistent Var, it throws:
user=> (defn g [x] (if true x (+ *foobar* x)))
CompilerException java.lang.RuntimeException: Unable to resolve symbol: *foobar* in this context, compiling:(NO_SOURCE_PATH:24)
Note that this happens at compile time, and regardless of whether the offending code will ever be executed. Thus the compiler should know what Vars are potentially referenced by the function, and I would like to have access to that information.
Parse the source code and walk the syntax tree, and record when a Var is referenced
Because code is data and all that. I suppose this means calling macroexpand and handling each Clojure primitive and every kind of syntax they take. This looks so much like a compilation phase that it would be great to be able to call parts of the compiler, or somehow add my own hooks to the compiler.
Instrument the Var mechanism, execute the test and see which Vars get accessed
Not as complete as the other methods (what if a Var is used in a branch of the code that my test fails to exercise?) but this would suffice. I imagine I would need to redefine def to produce something that acts like a Var but records its accesses somehow.
(1) Actually that particular function doesn't change if you rebind +; but in Clojure 1.2 you can bypass that optimization by making it (defn f [x] (+ x 0 *increment*)) and then you can have fun with (binding [+ -] (f 3)). In Clojure 1.3 attempting to rebind + throws an error.
Regarding your first point you could consider using the analyze library. With it you can quite easily figure out which dynamic vars are used in an expression:
user> (def ^:dynamic *increment* 3)
user> (def src '(defn f [x]
(+ x *increment*)))
user> (def env {:ns {:name 'user} :context :eval})
user> (->> (analyze-one env src)
expr-seq
(filter (op= :var))
(map :var)
(filter (comp :dynamic meta))
set)
#{#'user/*increment*}
I know that this doesn't answer your question, but wouldn't it be a lot less work to just provide two versions of a function where one version has no free variables, and the other version calls the first one with the appropriate top-level defines?
For example:
(def ^:dynamic *increment* 3)
(defn f
([x]
(f x *increment*))
([x y]
(+ x y)))
This way you can write all your tests against (f x y), which doesn't rely on any global state.
OK. I've been tinkering with Clojure and I continually run into the same problem. Let's take this little fragment of code:
(let [x 128]
(while (> x 1)
(do
(println x)
(def x (/ x 2)))))
Now I expect this to print out a sequence starting with 128 as so:
128
64
32
16
8
4
2
Instead, it's an infinite loop, printing 128 over and over. Clearly my intended side effect isn't working.
So how am I supposed to redefine the value of x in a loop like this? I realize this may not be Lisp like (I could use an anonymous function that recurses on it's self, perhaps), but if I don't figure out how to set variable like this, I'm going to go mad.
My other guess would be to use set!, but that gives "Invalid assignment target", since I'm not in a binding form.
Please, enlighten me on how this is supposed to work.
def defines a toplevel var, even if you use it in a function or inner loop of some code. What you get in let are not vars. Per the documentation for let:
Locals created with let are not variables. Once created their values never change!
(Emphasis not mine.) You don't need mutable state for your example here; you could use loop and recur.
(loop [x 128]
(when (> x 1)
(println x)
(recur (/ x 2))))
If you wanted to be fancy you could avoid the explicit loop entirely.
(let [xs (take-while #(> % 1) (iterate #(/ % 2) 128))]
(doseq [x xs] (println x)))
If you really wanted to use mutable state, an atom might work.
(let [x (atom 128)]
(while (> #x 1)
(println #x)
(swap! x #(/ %1 2))))
(You don't need a do; while wraps its body in an explicit one for you.) If you really, really wanted to do this with vars you'd have to do something horrible like this.
(with-local-vars [x 128]
(while (> (var-get x) 1)
(println (var-get x))
(var-set x (/ (var-get x) 2))))
But this is very ugly and it's not idiomatic Clojure at all. To use Clojure effectively you should try to stop thinking in terms of mutable state. It will definitely drive you crazy trying to write Clojure code in a non-functional style. After a while you may find it to be a pleasant surprise how seldom you actually need mutable variables.
Vars (that's what you get when you "def" something) aren't meant to be reassigned (but can be):
user=> (def k 1)
#'user/k
user=> k
1
There's nothing stopping you from doing:
user=> (def k 2)
#'user/k
user=> k
2
If you want a thread-local settable "place" you can use "binding" and "set!":
user=> (def j) ; this var is still unbound (no value)
#'user/j
user=> j
java.lang.IllegalStateException: Var user/j is unbound. (NO_SOURCE_FILE:0)
user=> (binding [j 0] j)
0
So then you can write a loop like this:
user=> (binding [j 0]
(while (< j 10)
(println j)
(set! j (inc j))))
0
1
2
3
4
5
6
7
8
9
nil
But I think this is pretty unidiomatic.
If you think that having mutable local variables in pure functions would be a nice convenient feature that does no harm, because the function still remains pure, you might be interested in this mailing list discussion where Rich Hickey explains his reasons for removing them from the language. Why not mutable locals?
Relevant part:
If locals were variables, i.e. mutable, then closures could close over
mutable state, and, given that closures can escape (without some extra
prohibition on same), the result would be thread-unsafe. And people
would certainly do so, e.g. closure-based pseudo-objects. The result
would be a huge hole in Clojure's approach.
Without mutable locals, people are forced to use recur, a functional
looping construct. While this may seem strange at first, it is just as
succinct as loops with mutation, and the resulting patterns can be
reused elsewhere in Clojure, i.e. recur, reduce, alter, commute etc
are all (logically) very similar. Even though I could detect and
prevent mutating closures from escaping, I decided to keep it this way
for consistency. Even in the smallest context, non-mutating loops are
easier to understand and debug than mutating ones. In any case, Vars
are available for use when appropriate.
The majority of the subsequent posts concerns implementing a with-local-vars macro ;)
You could more idiomatically use iterate and take-while instead,
user> (->> 128
(iterate #(/ % 2))
(take-while (partial < 1)))
(128 64 32 16 8 4 2)
user>