I have the following function
(defn fun [a b] (str a b))
(fun "1" "2") ;; --> "12"
Thanks to (partial) I can turn it into (fun b) and have a fixed a
(def fun2 (partial fun "1"))
(fun2 "2") ;; --> "12"
Does clojure have something like (partial-right) or a way to rearrange the arguments of a function so that instead of having a fixed a I can have a fixed b and hence have the function (fun a)?
Thanks
(defn partial-right [f & args1]
(fn [& args2]
(apply f (concat args2 args1))))
But ask yourself...why isn't this already part of the standard library? Is it perhaps that other people have wandered this way and it turned out badly?
For your particular example you could go with multi arity:
(defn fun
([a b] (str a b))
([a] (str a "1")))
Related
Following is the Clojure code:
(reduce (fn [r x] (if (nil? x) r (conj r x)))
[]
[:mouse nil :duck nil :lory nil])
In REPL, it evaluates to [:mouse :duck :lory].
My question is, how is the code evaluating?
According to me, r is [] and x is [:mouse nil :duck nil :lory nil]. nil? x is false as so it evaluates to (conj r x). But x is a vector, not an element so how it will add an element to the empty vector r in conj? I don't know but I am wrong somewhere in my approach. The output is the animals' name vector without nil values.
Can anyone please explain me the execution of code. Thanks.
Your problem appears to be understanding how reduce works. I'd like to refer you to the source code, but it simply maps onto a Java implementation, so I have to fake it.
The kind of reduce you are doing - supplying the initial value - might have been coded as follows:
(defn reduce [f init coll]
(loop [acc init, tail coll]
(if (seq tail)
(recur (f acc (first tail)) (rest tail))
acc)))
As you can see, it works through the sequence coll, applying the function f to acc and the first value in the sequence, to generate a new acc. When there is no more sequence, it returns acc.
How does this apply to your example? The reducing function ...
(fn [r x] (if (nil? x) r (conj r x)))
... ignores nil xs but conjs anything else onto the end of the accumulating vector r. Your code is more or less equivalent to ...
(remove nil? [:mouse nil :duck nil :lory nil])
=> (:mouse :duck :lory)
... except you get a lazy sequence instead of a vector.
Courtesy of FredOverflow's Clojure Transducers from the ground up you can wrap the reducing fn in this logging function to print the different arguments (r and x) to every step:
(defn logging [f]
(fn [& args]
(prn args)
(apply f args)))
(reduce (logging (fn [r x] (if (nil? x) r (conj r x))))
[]
[:mouse nil :duck nil :lory nil])
user=> ([] :mouse) ([:mouse] nil) ([:mouse] :duck) ([:mouse :duck] nil) ([:mouse :duck] :lory) ([:mouse :duck :lory] nil)
So only the keywords are added (not nils), starting with []. At the end [:mouse :duck :lory] is returned.
I am currently working on an assignment to come up with a solution for a simple "compression/ encoding" algorithm.
Objective is to compress subsequent identical letters in a string: "AABBBCCCC" --> "2A3B4C"
Although there are several (and possibly more elegant) approaches to this solution, I got stuck trying to derive a single reduce function that counts subsequent appearances of the same letter, building up the output array:
(reduce (fn [[a counter seq] b]
(if (= a b) [b (inc counter) seq] ([b 0 (conj(conj seq b )counter)] )))
[ "" 0 [] ]
"AABBBCCCC")
However, trouble starts already with my destructuring attempt of the reducer function which should be of type:
fn [[char int []] char] -> [char int []]
I could already figure out there is another solution to the problem using the identity macro. However, I still would like to get the reducer working.
Any suggestion and help is much appreciated!
the reduce variant could be something like this:
(defn process [s]
(->> (reduce (fn [[res counter a] b]
(if (= a b)
[res (inc counter) b]
[(conj res counter a) 1 b]))
[[] 0 nil]
s)
(apply conj)
(drop 2)
(apply str)))
user> (process "AABBCCCCC")
;;=> "2A2B5C"
though i would probably go with clojure's sequence functions:
(->> "AABBCCCC"
(eduction (partition-by identity)
(mapcat (juxt count first)))
(apply str))
;;=> "2A2B4C"
I was just wondering if there are any advantages/disadvantages to choose one over the other, or if it is purely just a design choice for a project's scope/workflow?
Scenario 1 : Using var and eval
(defn fun1 [x] (prn (* x x)))
(defn fun2 [y] (#'fun1 y))
(eval (fun2 2))
4
nil
Scenario 2 : Creating a sequential chaining of function calls
(defn fun1 [x] (prn (* x x)))
(defn fun3 [y] (fun1 y))
(fun3 2)
4
nil
I really appreciate your responses, Thanks in advance!
In Scenario 1, I believe you meant to do this:
(defn fun1 [x] (prn (* x x)))
(defn fun2 [y] (#'fun1 y))
(fun2 2)
It is almost never necessary (nor desirable) to use eval
For more detail on the difference between these Scenario 1 & 2, please see this question.
I'm not sure this is the best place to post, but why doesn't 2) work? Doesn't the threading macro pass the result of seq into (map str)?
;; 1
(map str (seq (str (* 8 8)))) -> ("6" "4")
;; 2
(defn a [x y]
(-> (* x y)
str
seq
(map str)))
(a 8 8) -> Don't know how to create ISeq from: clojure.core$str
You're using the thread-first macro, which inserts each form as the second item of the next, like this:
(-> (* x y) str seq (map str))
(-> (str (* x y)) seq (map str))
(-> (seq (str (* x y))) (map str))
(map (seq (str (* x y))) str)
What you want is the thread-last macro:
(defn a [x y]
(->> (* x y) str seq (map str)))
(a 8 8) ;=> ("6" "4")
as Elogent points out the macro is putting the arguments in the wrong place. In general when working with macros (and especially writing them) it helps to know about macroexpand-1 and combine it with clojure.pprint/pprint to get a clear view of what is actually running:
user> (clojure.pprint/pprint
(macroexpand-1
'(-> (* x y)
str
seq
(map str))))
(map (seq (str (* x y))) str)
nil
Which we can see doesn't quite look right. So next we fiddle with it until it expands to what we expect:
user> (clojure.pprint/pprint
(macroexpand-1
'(->> (* x y)
str
seq
(map str))))
(map str (seq (str (* x y))))
nil
There are a variety of threading macros to help with situations like this, especially as-> which lets you give an explicit name to the threaded value when you need to thread functions that alternate using the first and last argument for the important input:
user> (as-> (* 7 42) x
(str x)
(seq x)
(map str x))
("2" "9" "4")
Here is an alternative that is good to know (it's read from right to left):
(defn a [x y]
((comp (partial map str) seq str *)
x y))
This might be useful in contexts where you want to separate the transformations to apply, from the data they're applied to (I would welcome criticism on the subject 😃).
You might also consider using the it-> threading form from the Tupelo library, which is designed to avoid thread-first vs thread-last worries. Consider this code:
(ns clj.core
(:use tupelo.core))
(defn a [x y]
(it-> (* x y)
(str it)
(seq it)
(map str it)))
(spyx (a 8 8))
(defn -main [] )
Which produces:
(a 8 8) => ("6" "4")
The it-> macro uses the placeholder it to explicitly choose where to place the result of each successive form. This is an easy way to simplify code and avoid this type of error.
I've started learning core.logic and I'm totally lost. I am trying to write a core.logic relation which refactors an expression, renaming symbols. I want a relation that returns for a given expression, list of symbols and a list of symbols to rename those symbols:
(defn rename [exp from to]...
the expression with all the symbols in from becoming the corresponding one in to:
e.g. (rename '(defn multiply [x y] (* x y)) [x y] [a b])
returns (defn multiply [a b] (* a b))
but it needs to be aware of scope,
so (rename '(defn q [x] ((fn [x] (* x 5)) x)) [x] [a])
would return (defn q [a] ((fn [x] (* x 5)) a))
I don't know where to start solving this - any hints would be greatly appreciated!
This problem is more suitable for FP as it is just a tree traversal and replace operation, where as LP is more about specifying constrains and asking all possible solution around those constrains for a specific input. But if you really want to do this logical way, I tried something that does try to do it LP way but it doesn't handle a lot of cases and is just a starting point.
(defrel replace-with a b)
(fact replace-with 'x 'a)
(fact replace-with 'y 'b)
(defn replace [a b]
(conde
[(replace-with a b)]
[(== a b)]))
(defn replace-list [from to]
(conde
[(== from []) (== to [])]
[(fresh [f t f-rest t-rest]
(resto from f-rest)
(resto to t-rest)
(firsto from f) (firsto to t)
(conda [(replace-list f t)]
[(replace f t)])
(replace-list f-rest t-rest))]))
(first (run 1 [q]
(fresh [from]
(== from '(defn multiply [x y] (* x y)))
(replace-list from q))))
==> (defn multiply (a b) (* a b))