Never thought would say that, but coming from c++, I miss sometimes something like the c++-standard in Clojure. Let's take for example max-key (or min-key for that matter):
(doc max-key)
;=clojure.core/max-key
;=([k x] [k x y] [k x y & more])
;=Returns the x for which (k x), a number, is greatest.
Hm, what if there are several items with the same key? Clojuredocs hasn't more information on that. But experiments show:
(max-key count [1] [2])
;=[2]
(max-key count [1] [2] [3])
;=[3]
It seems, as if always the last element with the maximal key-value is returned.
But is it true? How can I be certain?
Since it is not specified, there is no guarantee. You should not depend on this behavior.
Certainly you could find out what will happen with the current implementation simply by reading it:
(defn max-key
"Returns the x for which (k x), a number, is greatest."
{:added "1.0"
:static true}
([k x] x)
([k x y] (if (> (k x) (k y)) x y))
([k x y & more]
(reduce1 #(max-key k %1 %2) (max-key k x y) more)))
It is clearly right-biased, so as implemented now you will get the rightmost element among all those that qualify. But again, because there is no guarantee, and any future version of Clojure may change this behavior.
ClojureDocs has a link to the source code (top right corner) so you can see the details and predict what will happen in any specific case. However, when more than one answer is available it is generally unspecified which item will be returned. Also, it can change with future versions of Clojure (which has happened before).
So, if you need a specific outcome (first, last, or something else) you may need to write a wrapper function to enforce the desired behavior in the event of ambiguous inputs.
Related
Here is an example where calling identity changes the returned value, which seems to me to indicate that the docstring "Returns its argument." isn't entirely true:
(let [x Double/NaN] (identical? x x)) ;=> false
(let [x (identity Double/NaN)] (identical? x x)) ;=> true
Is this expected? Or is it a bug with the identity function somehow?
You appear to have found an edge case involving identity, identical?, and primitive vs object equality. Note that in Java, java.lang.Double/NaN is a primitive:
public static final double NaN
But identical compares Java Objects:
; clojure.core
(defn identical?
"Tests if 2 arguments are the same object"
{:inline (fn [x y] `(. clojure.lang.Util identical ~x ~y))
:inline-arities #{2}
:added "1.0"}
([x y] (clojure.lang.Util/identical x y)))
// clojure/lang/Util.java
static public boolean identical(Object k1, Object k2){
return k1 == k2;
}
Try this trick to force the NaN into a Double object instead of an unboxed primitive:
tupelo.core=> (let [x (Double. Double/NaN)]
(spyxx x)
(identical? x x))
x => java.lang.Double->NaN
true
I suspect that autoboxing of the primitive NaN which may/may not occur with different use-cases is the cause of the differences you are seeing.
To add a little color to Alan's answer on boxing:
You may want to look into the == function, which is implemented this way:
public boolean equiv(Number x, Number y){
return x.doubleValue() == y.doubleValue();
}
This performs a primitive comparison of two actual doubles. Your example, with ==:
(let [x (identity Double/NaN)] (== x x))
=> false
(let [x (identity Double/POSITIVE_INFINITY)] (== x x))
=> true
What's going on? Why is NaN == NaN false? Well, a primitive comparison using == should actually return false for NaN. It's strangely specified this way in IEEE 754 and Java behaves this way. It's the only "number" which, when compared to itself, does not equal itself.
As an aside, to see how object equality can be a strange thing in Java, see this:
(identical? 127 127)
=> true
(identical? 128 128)
=> false
This is because java caches the first 2^8 unsigned ints, so the 127s being compared are the same object in the first example, but the 128s in the second example are different objects. So, there are some gotchas to be aware of with checking for equality!
But the main takeaway here is: identity is working as it should! Just be careful when comparing things, as the notion of "equality" is not so straightforward!
Does identity "return its argument"?
It depends what you mean by the argument.
If it is the evaluated expression in the function call form, then not always.
If it is what the body of the function sees on the stack upon entry, then yes, it does.
The anomaly arises because of the way that Clojure calls functions.
Clojure functions are objects that comply with the IFn
interface.
A Clojure function call translates into one of the many invoke
methods - overloaded for arity - of the function object.
All of the invoke methods have Object parameters.
The upshot of all this is that every Clojure function call translates its every argument into some kind of Object - an identity operation except on primitives, which are wrapped in the corresponding Java class: long into Long, and so on.
So even the identity function, essentially (defn identity [x] x), does not return a primitive argument. It can't, because it never sees it.
For example, let's consider the expression
(inc 3)
The number 3 is surely a long. What type is (inc 3)? Let's ask Clojure:
(type (inc 3))
=> java.lang.Long
... a boxed Long object.
Hang on, are we sure that 3 is a primitive long?:
(type 3)
=> java.lang.Long
Aaaaaaagh! It's boxed too!
Not necessarily! You can't tell, because by the time the body of type sees 3, it is boxed, whether or not it was so to the reader/compiler. The Clojure documentation is silent on the point. It just says that numeric literals are generally represented as per Java.
So - in general - it's the evaluation mechanism, not a particular function (such as identity) that's responsible for boxing primitive arguments. This is auto-boxing.
What your example shows is that primitives are held as such, un-boxed, at least in let forms:
(let [x 1.0] (identical? x x)) ;=> false
(let [x (identity 1.0)] (identical? x x)) ;=> true
The fact that identical? is able to distinguish between the two boxings of 1.0 shows that it is held as a primitive double. (I've used an ordinary double, just to show that the behaviour is nothing to do with the special value Double/NaN).
Now let's try putting the number in a var:
(def x 1.0)
(identical? x x) ;=> true
(let [x (identity x)] (identical? x x)) ;=> true
It's boxed.
While we're here, auto-boxing is idempotent:
(identical? x (identity x)) ;=> true
The above adds little to what Alan Thompson's and Josh's answers and Alan Malloy's and Lee's comments comprise. I just felt they had hooked and played the fish, without actually landing it.
SPOILER ALERT: This question refers to a 4clojure.com question. If you're a Clojure newbie like me, you probably want to try it by yourself first.
I answered this question (#68) successfully, but only after making a mistake which I'm still not sure why is wrong.
Here's the question:
(= __
(loop [x 5
result []]
(if (> x 0)
(recur (dec x) (conj result (+ 2 x)))
result)))
My initial answer was [6 5 4 3 2] while the accepted answer is [7 6 5 4 3].
I don't totally grok it, because (dec x) precedes (conj result (+ 2 x)), and they're both equally nested in the loop. I'd thought that because the decrement seems to happen before the conjoin, the result vector would begin with a decremented x plus two. But it's not happening that way. This is clearly something very basic, but perhaps someone might explain it what's going on?
Thanks.
Variables in clojure and immutable (mostly, anyway). (dec x) does not actually decrease x in the current scope. It returns the result of (dec x), which is then used as an argument to recur, which you can treat as another call of the loop "function". So x is not changed in this scope. (conj result (+ 2 x)) uses the same variable x with the same old value.
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.
I have a question regarding nested doseq loops. In the start function, once I find an answer I set the atom to true, so that the outer loop validation with :while fails. However it seems that it doesn't break it, and the loops keep on going. What's wrong with it?
I am also quite confused with the usage of atoms, refs, agents (Why do they have different names for the update functions when then the mechanism is almost the same?) etc.
Is it okay to use an atom in this situation as a flag? Obviously I need a a variable like object to store a state.
(def pentagonal-list (map (fn [a] (/ (* a (dec (* 3 a))) 2)) (iterate inc 1)))
(def found (atom false))
(defn pentagonal? [a]
(let [y (/ (inc (Math/sqrt (inc (* 24 a)))) 6)
x (mod (* 10 y) 10)]
(if (zero? x)
true
false)))
(defn both-pent? [a b]
(let [sum (+ b a)
diff (- a b)]
(if (and (pentagonal? sum) (pentagonal? diff))
true
false)))
(defn start []
(doseq [x pentagonal-list :while (false? #found)]
(doseq [y pentagonal-list :while (<= y x)]
(if (both-pent? x y)
(do
(reset! found true)
(println (- x y)))))))
Even once the atom is set to true, your version can't stop running until the inner doseq finishes (until y > x). It will terminate the outer loop once the inner loop finishes though. It does terminate eventually when I run it. Not sure what you're seeing.
You don't need two doseqs to do this. One doseq can handle two seqs at once.
user> (doseq [x (range 0 2) y (range 3 6)] (prn [x y]))
[0 3]
[0 4]
[0 5]
[1 3]
[1 4]
[1 5]
(The same is true of for.) There is no mechanism for "breaking out" of nested doseqs that I know of, except throw/catch, but that's rather un-idiomatic. You don't need atoms or doseq for this at all though.
(def answers (filter (fn [[x y]] (both-pent? x y))
(for [x pentagonal-list
y pentagonal-list :while (<= y x)]
[x y])))
Your code is very imperative in style. "Loop over these lists, then test the values, then print something, then stop looping." Using atoms for control like this is not very idiomatic in Clojure.
A more functional way is to take a seq (pentagonal-list) and wrap it in functions that turn it into other seqs until you get a seq that gives you what you want. First I use for to turn two copies of this seqs into one seq of pairs where y <= x. Then I use filter to turn that seq into one that filters out the values we don't care about.
filter and for are lazy, so this will stop running once it finds the first valid value, if one is all you want. This returns the two numbers you want, and then you can subtract them.
(apply - (first answers))
Or you can further wrap the function in another map to calculate the differences for you.
(def answers2 (map #(apply - %) answers))
(first answers2)
There are some advantages to programming functionally in this way. The seq is cached (if you hold onto the head like I do here), so once a value is calculated, it remembers it and you can access it instantly from then on. Your version can't be run again without resetting the atom, and then would have to re-calculate everything. With my version you can (take 5 answers) to get the first 5 results, or map over the result to do other things if you want. You can doseq over it and print the values. Etc. etc.
I'm sure there are other (maybe better) ways to do this still without using an atom. You should usually avoid mutating references unless it's 100% necessary in Clojure.
The function names for altering atoms/agents/refs are different probably because the mechanics are not the same. Refs are synchronous and coordinated via transactions. Agents are asynchronous. Atoms are synchronous and uncoordinated. They all kind of "change a reference", and probably some kind of super-function or macro could wrap them all in one name, but that would obscure the fact that they're doing drastically different things under the hood. Explaining the differences fully is probably beyond the scope of an SO post to explain, but http://clojure.org fully explains all of the nuances of the differences.
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>