What is the idiomatic way to pop a PersistentQueue in a ref? - concurrency

Given a PersistentQueue in a ref:
(def pq (ref clojure.lang.PersistentQueue/EMPTY))
What is the idiomatic way to pop the queue and get the result?
My best attempt for your critique:
(defn qpop [queue-ref]
(dosync
(let [item (peek #queue-ref)]
(alter queue-ref pop)
item))
alter returns the in-transaction value of the queue which is popped already, so you can't just do the alter by itself.

I can't think of something more idiomatic short of abstracting the body of your dosync away.
However if you are in for a stunt, you can try the off-by-one hack: always consider the head of the PQ as garbage (it contains the previously popped item). It follows that you can rewrite qpop:
(defn qpop [queue-ref]
(peek (alter queue-ref pop))
It incurs adding special checks for emptiness (in particular when you conj). It also means keeping a reference to the item around for longer than it should (however if you look at the impl of PQ you'll see that by itsef it may keep references to popped items for too long, so liveness is already murky).
I used this hack here.

Your dosync body could be simplified using Common Lisp's prog1 macro, although core Clojure seems to lack it. There is a straightforward implementation on the Google group, along with some discussion on how you can make it a function (instead of a macro) in Clojure.

Related

How to solve "stateful problems" in Clojure?

I'm new to clojure and I'm having trouble to understand some concepts, specially pure functions and immutability.
One thing that I still can't comprehend is how you solve a problem like this in clojure:
A simple console application with a login method, where the user can't try to login more than 3 times in a 1 minute interval.
In C# for example I could add the UserId and a timestamp to a collection every time the user tries to login, then I would check if there has been more 3 than attempts in the last minute.
How would I do that in Clojure considering that I can't alter my collection ?
This is not a pratical question (although some code examples would be welcomed), I want to understand how you approach a problem like this.
You don't alter objects in most cases, you create new versions of the old objects:
(loop [attempt-dates []]
(if (login-is-correct)
(login)
(recur (conj attempt-dates (current-date-stamp)))))
In this case I'm using loop. Whatever I give to recur will be passed to the next iteration of loop. I'm creating a new list that contains the new stamp when I write (conj attempt-dates (current-date-stamp)), then that new list is passed to the next iteration of loop.
This is how it's done in most cases. Instead of thinking about altering the object, think about creating a transformed copy of the object and passing the copy along.
If you really truly do need mutable state though, you can use a mutable atom to hold an immutable state:
(def mut-state (atom []))
(swap! mut-state conj 1)
(println #mut-state) ; Prints [1]
[] is still immutable here, the new version is just replacing the old version in the mutable atom container.
Unless you're needing to communicate with UI callbacks or something similar though, you usually don't actually need mutability. Practice using loop/recur and reduce instead.

Save state on clojure

I'm starting on functional programming now and I'm getting very crazy of working without variables.
Every tutorial that I read says that it isn't cool redefine a variable but I don't know how to solve my actual problem without saving the state on a variable.
For example: I'm working on a API and I want to keep the values throught the requests. Lets say that I have a end-point that add a person, and I have an list of persons, I would like to redefine or alter the value of my persons list adding the new person. How can I do this?
Is there ok to use var-set, alter-var-root or conj!?
(for the api i'm using compojure-api and each person would be a Hash)
Clojure differentiates values from identity. You can use atoms to manage the state in your compojure application.
(def persons (atom [])) ;; init persons as empty vector
(swap! persons #(conj % {:name "John Doe"})) ;; append new value
You can find more in docs:
https://clojure.org/reference/atoms
https://clojure.org/reference/data_structures
https://clojuredocs.org/clojure.core/atom
You'll likely need a mutable state somewhere in a large application, but one isn't necessary in all cases.
I'm not familiar with compojure, but here's a small example using immutability that might be able to give you a better idea:
(loop [requests []
people []
(let [request (receive-request)]
; Use requests/people
; Then loop again with updated lists
(recur (conj requests request)
(conj people (make-person request))))])
I'm using hypothetical receive-request and make-person functions here.
The loop creates a couple bindings, and updates them at each recur. This is an easy way to "redefine a variable". This is comparable to pure recursion, where you don't mutate the end result at any point, you just change what value gets passed onto the next iteration.
Of course, this is super simple, and impractical since you're just receiving one request at a time. If you're receiving requests from multiple threads at the same time, this would be a justifiable case for an atom:
(defn listen [result-atom]
(Thread.
(fn []
(while true ; Infinite listener for simplicity
(let [request (receive-request)]
(swap! result-atom #(conj % (make-person request))))))))
(defn listen-all []
(let [result-atom (atom [])]
(listen result-atom)
(listen result-atom)))
; result-atom now holds an updating list of people that you can do stuff with
swap! mutates the atom by conjoining onto the list it holds. The list inside the atom isn't mutated, it was just replaced by a modified version of itself. Anyone holding onto a reference to the old list of people would be unaffected by the call to swap!.
A better approach would be to use a library like core/async, but that's getting away from the question.
The point is, you may need to use a mutable variable somewhere, but the need for them is a lot less than you're used to. In most cases, almost everything can be done using immutability like in the first example.

IndexedSeq VS. PersistentVector

Can somebody explain me, the difference between 'IndexedSeq' and 'PersistentVector'?
I bumped into this, when updating a vector in my data structure via 'rest'. Here's a REPL excerpt that shows the transformation.
=> (def xs [1 2 3])
...
(type xs)
cljs.core/PersistentVector
=> (def xs2 (rest xs))
...
(type xs2)
cljs.core/IndexedSeq
I'm holding a list in an app-state atom, which needs to be shifted once in a while, so the first item must disappear. Would be really cool, if anybody could give me a hint about which data structure might be preferable here in terms of performance.
Sometimes elements get pushed to the end of the list as well, so I guess it's a LIFO mechanism that I'm creating here.
From your last paragraph, it sounds like you're using this as a stack. Taken together, pop, peek, and conj form a stack interface that can be used with either lists or vectors (working on the front of a list or the end of a vector). I would use those.
If you're just using those functions, I don't think there should be any significant performance differences (all three functions should be constant time).
looking at the superinterfaces here: http://static.javadoc.io/org.clojure/clojure/1.7.0/clojure/lang/IndexedSeq.html
I can guess, it is not the most efficient thing here, since it is just a seq, with no guaranteed constant-time access to the nth member. To ensure the vector semantics you should probably use subvec to remove the first element.
In general, if you don't do random access to elements, in terms of performance it should be enough to use concat to add element to the end (as it produces a lazy sequence, won't consume the whole collection, and should be done in a constant time) and rest to remove the first element (as it is also done in a constant time), to make FIFO stack (which is what you do). (it's not the best variant still, since it may lead to stack owerflow, if you do alot of push without realizing the sequence.
But sure it's better to use vectors. So the combination of conj , first, and subvec should be your choice.

Filter, then map? Or just use a for loop?

I keep running into situations where I need to filter a collection of maps by some function, and then pull out one value from each of the resulting maps to make my final collection.
I often use this basic structure:
(map :key (filter some-predicate coll))
It occurred to me that this basically accomplishes the same thing as a for loop:
(for [x coll :when (some-predicate x)] (:key x))
Is one way more efficient than the other? I would think the for version would be more efficient since we only go through the collection once.. Is this accurate?
Neither is significantly different.
Both of these return an unrealized lazy sequence where each time an item is read it is computed. The first one does not traverse the list twice, it instead creates one lazy sequence which that produces items that match the filter and is then immediately consumed (still lazily) by the map function. So in this first case you have one lazy sequence consuming items from another lazy sequence lazily. The call to for on the other hand produces a single lazy-seq with a lot of logic in each step.
You can see the code that the for example expands into with:
(pprint (macroexpand-1 '(for [x coll :when (some-predicate x)] (:key x))))
On the whole the performance will be very similar with the second method perhaps producing slightly less garbage so the only way for you to decide between these on the basis of performance will be benchmarking. On the basis of style, I choose the first one because it is shorter, though I might choose to write it with the thread-last macro if there where more stages.
(->> coll
(filter some-predicate)
(take some-limit)
(map :key))
Though this basically comes down to personal style

recursive function for finding dependencies

I have a collection of maps. Given any map, I want to find all the maps it depends on. Any map will have immediate dependencies. Each one of the immediate dependencies will in turn have their own dependencies, and so and so forth.
I am having trouble writing a recursive function. The code below gives a stackoverflow error. (The algorithm is not efficient anyway - I would appreciate help in cleaning it).
Below is my implementation -
find-deps takes a map and returns a coll of maps: the immediate dependencies of the map.
(find-deps [m]) => coll
The function below -
Checks if direct-deps, the immediate deps, is empty, as the base condition.
If not, it maps find-deps on all the immediate deps. This is the step
which is causing the problem.
Usually in recursive functions we are able to narrow down the initial input, but here my input keeps on increasing !
(defn find-all-deps
([m]
(find-all-deps m []))
([m all-deps]
(let [direct-deps (find-deps m)]
(if-not (seq direct-deps)
all-deps
(map #(find-all-deps % (concat all-deps %)) direct-deps)))))
When working with directed graphs, it's often useful to ensure that you don't visit a node in the graph twice. This problem seems a lot like many graph traversal problems out there, and your solution is very close to a normal depth-first traversal, you just need to not follow cycles (or not allow them in the input). One way to start would be to ensure that a dependency is not in the graph before you visit it again. unfortunately map is poorly suited to this, because each element in the list you are mapping over can't know about the dependencies in other elements of th same list. reduce is a better fit here because you are looking for a single answer.
...
(if-not (seq direct-deps)
all-deps
(reduce (fn [result this-dep]
(if-not (contains? result this-dep)
(find-all-deps this-dep (conj result this-dep))
result)
direct-deps
#{}) ;; use a set to prevent duplicates.