How to understand this example of cat? - clojure

There is an example of cat in clojuredocs.com
(into [] (comp cat cat (map inc)) [[[1] [2]] [[3] [4]]])
As I know, comp applies fn left to right but above example seem to be applied right to left. How can I read it?

Short answer: comp-ing transducers runs them basically left-to-right.
From above docs:
Transducers compose with ordinary function composition. A transducer performs its operation before deciding whether and how many times to call the transducer it wraps. The recommended way to compose transducers is with the existing comp function:
(def xf
(comp
(filter odd?)
(map inc)
(take 5)))
The transducer xf is a transformation stack that will be applied by a process to a series of input elements. Each function in the stack is performed before the operation it wraps. Composition of the transformer runs right-to-left but builds a transformation stack that runs left-to-right (filtering happens before mapping in this example).
As a mnemonic, remember that the ordering of transducer functions in comp is the same order as sequence transformations in ->>. The transformation above is equivalent to the sequence transformation:
(->> coll
(filter odd?)
(map inc)
(take 5))

The "secret" is in comp function, which applies functions right to left, but for transducers it is left to right.
Since you are transducing, (comp cat cat (map inc)) is kinda like
(fn [xs] (map inc (sequence cat (sequence cat xs)))) (note, there is no version of cat that takes a coll)

Related

map-indexed alternative for reducers

Is there a map-indexed alternative for clojure.core.reducers? I would like something that would work lazily like r/map (without constructing new sequence).
I suspect that what you really want to use is a transducer, since map-indexed has a 1-arity version (as does map, filter, and many other core functions) that returns a transducer. Transducers are composable, and do not create an intermediate sequence. Here is a short example:
(def xf (comp
(map-indexed (fn [i value] [i value]))
(filter (fn [[i value]] (odd? i)))
(map second)))
This says: generate an indexed vector using map-indexed, filter out only the vectors whose index is odd, and get the second element. It's a long-winded way of saying (filter odd? collection) but it's only for example purposes.
You can use this with into:
(into [] xf "ThisIsATest")
=> [\h \s \s \T \s]
or you can use the transduce function and apply str to the result:
(transduce xf str "ThisIsATest")
=> "hssTs"

How to print each elements of a hash map list using map function in clojure?

I am constructing a list of hash maps which is then passed to another function. When I try to print each hash maps from the list using map it is not working. I am able to print the full list or get the first element etc.
(defn m [a]
(println a)
(map #(println %) a))
The following works from the repl only.
(m (map #(hash-map :a %) [1 2 3]))
But from the program that I load using load-file it is not working. I am seeing the a but not its individual elements. What's wrong?
In Clojure tranform functions return a lazy sequence. So, (map #(println %) a) return a lazy sequence. When consumed, the map action is applied and only then the print-side effect is visible.
If the purpose of the function is to have a side effect, like printing, you need to eagerly evaluate the transformation. The functions dorun and doall
(def a [1 2 3])
(dorun (map #(println %) a))
; returns nil
(doall (map #(println %) a))
; returns the collection
If you actually don't want to map, but only have a side effect, you can use doseq. It is intended to 'iterate' to do side effects:
(def a [1 2 3])
(doseq [i a]
(println i))
If your goal is simply to call an existing function on every item in a collection in order, ignoring the returned values, then you should use run!:
(run! println [1 2 3])
;; 1
;; 2
;; 3
;;=> nil
In some more complicated cases it may be preferable to use doseq as #Gamlor suggests, but in this case, doseq only adds boilerplate.
I recommend to use tail recursion:
(defn printList [a]
(let [head (first a)
tail (rest a)]
(when (not (nil? head))
(println head)
(printList tail))))

clojure: filtering a vector of maps by keys existence and values

I have a vector of maps like this one
(def map1
[{:name "name1"
:field "xxx"}
{:name "name2"
:requires {"element1" 1}}
{:name "name3"
:consumes {"element2" 1 "element3" 4}}])
I'm trying to define a functions that takes in a map like {"element1" 1 "element3" 6} (ie: with n fields, or {}) and fiters the maps in map1, returning only the ones that either have no requires and consumes, or have a lower number associated to them than the one associated with that key in the provided map (if the provided map doesn't have any key like that, it's not returned)
but I'm failing to grasp how to approach the maps recursive loop and filtering
(defn getV [node nodes]
(defn filterType [type nodes]
(filter (fn [x] (if (contains? x type)
false ; filter for key values here
true)) nodes))
(filterType :requires (filterType :consumes nodes)))
There's two ways to look at problems like this: from the outside in or from the inside out. Naming things carefully can really help when working with nested structures. For example, calling a vector of maps map1 may be adding to the confusion.
Starting from the outside, you need a predicate function for filtering the list. This function will take a map as a parameter and will be used by a filter function.
(defn comparisons [m]
...)
(filter comparisons map1)
I'm not sure I understand the comparisons precisely, but there seems to be at least two flavors. The first is looking for maps that do not have :requires or :consumes keys.
(defn no-requires-or-consumes [m]
...)
(defn all-keys-higher-than-values [m]
...)
(defn comparisons [m]
(some #(% m) [no-requires-or-consumes all-keys-higher-than-values]))
Then it's a matter of defining the individual comparison functions
(defn no-requires-or-consumes [m]
(and (not (:requires m)) (not (:consumes m))))
The second is more complicated. It operates on one or two inner maps but the behaviour is the same in both cases so the real implementation can be pushed down another level.
(defn all-keys-higher-than-values [m]
(every? keys-higher-than-values [(:requires m) (:consumes m)]))
The crux of the comparison is looking at the number in the key part of the map vs the value. Pushing the details down a level gives:
(defn keys-higher-than-values [m]
(every? #(>= (number-from-key %) (get m %)) (keys m)))
Note: I chose >= here so that the second entry in the sample data will pass.
That leaves only pulling the number of of key string. how to do that can be found at In Clojure how can I convert a String to a number?
(defn number-from-key [s]
(read-string (re-find #"\d+" s)))
Stringing all these together and running against the example data returns the first and second entries.
Putting everything together:
(defn no-requires-or-consumes [m]
(and (not (:requires m)) (not (:consumes m))))
(defn number-from-key [s]
(read-string (re-find #"\d+" s)))
(defn all-keys-higher-than-values [m]
(every? keys-higher-than-values [(:requires m) (:consumes m)]))
(defn keys-higher-than-values [m]
(every? #(>= (number-from-key %) (get m %)) (keys m)))
(defn comparisons [m]
(some #(% m) [no-requires-or-consumes all-keys-higher-than-values]))
(filter comparisons map1)

clojure: (apply fn coll) vs (apply #(apply fn %&) coll)

I am working my way through labrepl and I saw some code that follows this pattern:
;; Pattern
(apply #(apply f %&) coll)
;; Concrete example
user=> (apply #(apply + %&) [1 2 3 4])
10
This seems to be equivalent to this pattern:
;; Pattern
(apply f coll)
;; Concrete example
user=> (apply + [1 2 3 4])
10
Are these patterns equivalent? If not, what's the difference and when would you use one over the other?
I took the former pattern from the step function in the cellular-automata lab of labrepl:
(defn step
"Advance the automation by one step, updating all cells."
[board]
(doall
(map (fn [window]
(apply #(apply map brians-brain-rules %&)
(doall (map torus-window window))))
(torus-window board))))
Update: I added a concrete example of each pattern to help make the question clearer.
No, there is no difference. There is no reason to write the longer form; I can only assume it was arrived at by gradual changes to code that made sense at one time.
Essentially, both forms accomplish the same thing and are more or less the same. Each provides a way to introduce an anonymous function.
Using #(... is a Clojure reader shorthand for an anonymous function. It is kind of equivalent to (fn [arg1 & args]... , but you cannot embed one #(... anonymous function inside another, and arguments are expressed as % %2... or %1 %2... rather than with vector binding (fn [arg & args].
Both are methods to express an anonymous function. #(... is used for simpler functions, and (fn... is used for more detailed functions.
#(... tends to make things look a little neater.

Is it possible to set a common binding for all implementations in a multi-signature function?

(This is a question regarding style. I am aware this can be done with a bunch of conditionals, multimethods, etc.)
In the following function, null-vector is defined on each implementation. How can I set it once for the entire function? In general, is it possible to set a common binding to all implementations?
A closure won't work, since it null-vector needs an "argument", but I suppose I could partial it. However, that would still need computation of the size parameter. I'd like to avoid repeating code, obviously.
(defn path
"Returns a lazy sequence of vectors representing a monotonic path
walked over coll in n-dimensional space, where n is the cardinality
of coll's alphabet."
([coll]
(let [alphabet (set coll)
cardinality (count alphabet)
alpha-map (apply hash-map (interleave alphabet (range cardinality)))
null-vector (vec (repeat cardinality 0))]
(path coll null-vector alpha-map)))
([coll alpha-map]
(let [null-vector (vec (repeat (count (keys alpha-map)) 0))]
(path coll null-vector alpha-map)))
([coll origin alpha-map]
(let [null-vector (vec (repeat (count origin) 0))
unit-vector #(assoc null-vector (alpha-map %) 1)
sum-vectors #(vec (map + %1 %2))]
(reductions sum-vectors origin (map unit-vector coll)))))
I would create a "private" helper function:
(defn- null-copy-vector [coll]
(vec (repeat (count coll) 0)))
and then just call it in each branch of the function:
(defn path
"Returns a lazy sequence of vectors representing a monotonic path
walked over coll in n-dimensional space, where n is the cardinality
of coll's alphabet."
([coll]
(let [alphabet (set coll)
alpha-map (zipmap alphabet (iterate inc 0)) ;; note 1
null-vector (null-copy-vector alphabet)]
(path coll null-vector alpha-map null-vector)))
([coll alpha-map]
(let [null-vector (null-copy-vector alpha-map)] ;; note 2
(path coll null-vector alpha-map null-vector)))
([coll origin alpha-map]
(path coll origin alpha-map (null-copy-vector origin)))
([coll origin alpha-map null-vector]
(let [unit-vector #(assoc null-vector (alpha-map %) 1)
sum-vectors #(vec (map + %1 %2))]
(reductions sum-vectors origin (map unit-vector coll)))))
It may be this isn't satisfying to you because null-copy-vector isn't "inside" the overall function here, but I think this is pretty idiomatic. On a function that did not take multiple arities, I might use letfn to separate out an "internal" function but that won't work here.
Breaking things up like this also lets you a) reuse the basic building block functions elsewhere and b) lets you test in smaller chunks. You might want to skip the defn- and just use defn to make testing easier (although it is possible to test defn- with a bit more work).
I also broke out a new 4-arg form that takes the null-vector as the last arg, letting you pass it in directly if you know it so that you can avoid re-creating it from an already null vector. If you wanted to hide that 4-arg form, you could pull it into a separate defn- helper function.
Unrelated notes:
I modified your first branch to a simpler (imho) impl using zipmap and an infinite sequence.
Instead of (count (keys map)), just doing (count map) is sufficient (the count here is inside your helper function).