I am not understand why instead of normal list I recive (clojure.core/seq).
My code
(defn del-list [arg-list lvl] (do
(cond
(= lvl 1) (remove seq? arg-list)
:else (map #(if (seq? %)
(del-list % (- lvl 1))
%
) arg-list)
)
))
(println (del-list `(1 2 3 `(1 2 `(1 2 3) 3) 1 2 3) 2))
;result=> (1 2 3 (clojure.core/seq) 1 2 3)
Why is this happening? I don't know how valid search this, all links from google point me to documentation about seq and seq?.
Like #ClojureMostly says in the comments, don't use bacticks, use a single quote. Also don't nest them, one is enough.
So, calling your function like this:
(println (del-list '(1 2 3 (1 2 (1 2 3) 3) 1 2 3) 2))
Will solve your immediate problem.
Going into a bit more depth, there are some differencences between single quote (just called quote) and backtick (called syntax quote).
In quoting something, you say that you want just the data structure, that it shouldn't be evaluated as code. In clojure, code is data, so (+ 1 2) is a list with a symbol and two numbers which, when evaluated as code, evals to 3. So, (+ 1 2) => 3 and '(+ 1 2) => (+ 1 2).
Syntax quote is similar, but it looks up the namespaces of things and you can unquote stuff inside. This makes it useful for writing macros.
;; Looks up the namespaces of symbols to avoid the problem of variable capture
`(+ 1 2) ;=> (clojure.core/+ 1 2)
;; You can unquote parts of the expression.
;; ~ is unquote ~# is unqoute splicing
;; That should give you the vocabulary to google this.
`(+ 1 2 3 ~(* 2 2)) ;=> (clojure.core/+ 1 2 3 4)
Nested quotes are never what you want. (Unless you alternate quoting and unquoting, and even then it's usually confusing)
In clojure you'd usually represent sequential things as vectors [1 2 3] (O(n) random access, grows at the end), unless you specifically want some property of a linked list for your data. (Like representing a stack, as lists efficiently add and remove the first element.)
(defn del-list [arg-list lvl]
;; You don't need the do, there's an implicit do in many special forms
;; like let, fn and defn
;; Also you only had one thing in your do, in that case it doesn't do anything
;; There's only one condition, so I'd use if instead of cond
(if (= lvl 1)
;; And, like someone mentioned in the comments,
;; what you probably want is sequential? instead of seq?
(remove sequential? arg-list)
(map #(if (sequential? %)
(del-list % (dec lvl)) ; dec stands for decrement
%)
arg-list)))
;; This works
(println (del-list '(1 2 3 (1 2 (1 2 3) 3) 1 2 3) 2))
;; But this is more idiomatic (modulo specific reasons to prefer lists)
(println (del-list [1 2 3 [1 2 [1 2 3] 3] 1 2 3] 2))
;; If you change map to mapv, and wrap remove with vec it will return vectors
(defn del-vec [arg-vec lvl]
(if (= lvl 1)
(vec (remove sequential? arg-vec))
(mapv #(if (sequential? %)
(del-vec % (dec lvl)) ; dec stands for decrement
%)
arg-vec)))
(println (del-vec [1 2 3 [1 2 [1 2 3] 3] 1 2 3] 2))
;; But most of the time you don't care about the specific type of sequential things
As for your actual question, why does clojure.core/seq appear, I have no idea. That's not how you use quoting, so it has never come up.
Related
I am new to clojure
I am trying to find whether a vector in clojure has consecutive elements:
in python its simple using numpy
(np.diff(np.sort(np.array(numbers))))
But I am lost trying to find similar methods:
My strategy was to
subtract a vector with itself
make it a set and see if it contains first element as 1 and the length of set is 1
for example
(def x `(5 7 3 6 4))
Output would be (1 1 1 1)
I am confused how to work on this.
Try something like this:
(defn diff [vals]
(map - (next vals) vals))
This returns a list of differences between each pair of consecutive elements are equal. It works because next simply offsets the sequence of values by one element.
Example usage:
(diff [1 2 2 3])
=> (1 0 1)
To test whether consecutive numbers exist, you simply need to check for the presence of the value 1 in this list.
Following your idea of getting the differences, after sorting you can use partition to get all the consecutive pairs and than use map to get all the differences. (Here it seemed more natural to get the reverse of the numpy diff, so the check is that every element is -1 instead of 1.)
(defn contains-consecutive? [xs]
(let [sorted (sort xs)
differences (map #(apply - %) (partition 2 1 sorted))]
(every? #(= -1 %) differences)))
user> (contains-consecutive? [])
true
user> (contains-consecutive? [1])
true
user> (contains-consecutive? [1 3 2])
true
user> (contains-consecutive? [1 3 4])
false
user> (contains-consecutive? '(5 7 3 6 4))
true
Clojure has a built-in dedupe function so an easy (but not particularly fast) answer is to dedupe and compare equals.
(defn consecutive?
[coll]
(not= coll (dedupe coll)))
(consecutive? [1 2 2 3]) ;; true
(consecutive? [1 2 3]) ;; false
Please see this list of documentation, especially the Clojure CheatSheet. You are looking for the function partition. You can use it like this:
(ns tst.demo.core
(:use tupelo.test))
(defn pair-delta
[pair]
(let [[a b] pair]
(- b a)))
(defn consectives?
[v]
(let [pairs (partition 2 1 (sort v))
deltas (mapv pair-delta pairs)
result (= #{1} (set deltas))]
result))
(dotest
(let [pos [1 2 3 6 5 4]
neg [1 2 3 6 5 ]]
(is= true (consectives? pos))
(is= false (consectives? neg))))
The template project shows how I like to set up a project, and includes my favorite helper functions.
I'm learning Clojure. To see if I could do something outlandish compared to Python, I did:
> (+ 2 2)
4
> (def + -)
#'sandbox6693/+
> (+ 2 2)
0
Which surprisingly worked, however I can't figure out how to get + to add again after the definition above. Is there a way to do so?
As #Russell said, you're just shadowing the clojure.core/+ with user/+.
What would i do for experimenting with clojure, is to just establish some local binding (again shadowing the core + with your +, but keeping the changes inside the binding scope, not to make a mess):
user> (let [+ -]
(+ 1 2 3))
-4
user> (+ 1 2 3)
6
But in general there are special ways to do what you want (to change the value of the var, execute some code in the scope where the var is changed, and then automatically restore it's value):
first one is to use binding (https://clojuredocs.org/clojure.core/binding) the problem is it only works for special dynamic vars, so it's not really applicable in your case, since + is not dynamic
the second one, is to use with-redefs (https://clojuredocs.org/clojure.core/with-redefs) which is closer to what you need, but there is one problem there:
user> (with-redefs [+ -]
(+ 1))
-1 ;; as expected
user> (with-redefs [+ -]
(+ 1 2 3))
6 ;; unexpected!
the second example fails, because the compiler inlines + function, when there are more than one arg passed to it and replaces it with add function call)
Also, for some purely educational purpose you can make a macro, that would generally redefine everything you need, saving the old value, and restoring it after block evaluation:
user> (defmacro redefine [old new & body]
`(let [v# ~old]
(def ~old ~new)
(let [res# (do ~#body)]
(def ~old v#)
res#)))
#'user/redefine
user> (redefine
+ -
(+ 1 2 3))
-4
user> (+ 1 2 3)
6
user> #'+
#'user/+
user> (redefine
+ *
(+ 1 2 4))
8
user> (redefine
+ *
(+ 1 2 4))
8
user> (+ 1 2 4)
7
I don't think you're removing the clojure.core function +, just shadowing it in your namespace.
You can get it back by redeffing + to be the function in clojure.core by referencing it including the namespace:
user=> (def + -)
#'user/+
user=> (+ 2 2)
0
user=> (def + clojure.core/+)
#'user/+
user=> (+ 2 2)
4
But.... why?!
I am doing a project for class and I stumbled upon some code that has proved useful, though I am not sure how the line below "reads". I understand the result of what it does, but not how it does it.
(remove #(some (partial = %) '(1 2 3 4)) '(1 2 3 5 6 7))
What it does is removes the values from the second set that are in the first if possible. So given two set P and V it finds P / V.
I guess I am looking for an English language sentence of what is happening?
Edit: Title. Also I do understand what remove does, given some predicate such as pos? it returns a lazy sequence of items that equate to true when the predicate is applied.
What I specifically do not understand is how #(some (partial = %)) evaluates to a predicate.
#(some (partial = %) '(1 2 3 4))
...is syntax sugar for...
(fn [x] (some (partial = x) '(1 2 3 4))
...so, calling
(#(some (partial = %) '(1 2 3 4)) 5)
...runs...
(some (partial = 5) '(1 2 3 4))
...thus, running (partial = 5) against every entry in '(1 2 3 4) until it finds a match -- thus: (= 5 1), (= 5 2), etc -- and returning nil when no match is returned.
nil is falsey. Thus, any sequence element for which no match exists will return false, and be retained by remove, whereas for anything with which a match exists, the predicate will return true and be removed.
Obviously, creating a lambda function for every item in one of your sequences and evaluating those functions against content of another sequence is extremely inefficient compared to real set arithmetic. Thus, this code shouldn't be used in any case where the number of items might be nontrivial.
Instead:
(clojure.set/difference
#{1 2 3 4 5 6 7}
#{1 2 3 4})
...would be the efficient and idiomatic approach. If you're starting with a list rather than a set literal, that might be replaced with (clojure.set/difference (into #{} list-a) (into #{} list-b)) or (clojure.set/difference (set list-a) (set list-b)).
Please help me get off the ground with Clojure. I've searched and read, but all I see is how to add the number 1 using the function inc.
I'm trying to understand the very basics of map. All I want to do is to add the value 5 to each element in a collection. I've tried a number of different approaches, but nothing comes close. Here is one pathetic incomplete attempt:
(map (+ 5 ???) [0 1 2])
This must be childishly simple, but not for a non-functional programmer like me.
Thanks.
The first argument to map is the function you want to apply to each element in the input sequence. You could create a function and supply it:
(defn plus5 [x] (+ 5 x))
(map plus5 [0 1 2])
if you don't want to declare a named function you could create an anonymous one inline e.g.
(map (fn [x] (+ 5 x)) [0 1 2])
and you can shorten the function definition to:
(map #(+ 5 %) [0 1 2])
(+ 5 ???) is an expression, not a function.
(defn foo [x] (+ 5 x)) is a named function.
(fn [x] (+ 5 x)) is an anonymous function.
#(+ 5 %) is a faster way of writing an anonymous function.
These lines do what you want:
(map foo [0 1 2])
(map (fn [x] (+ 5 x)) [0 1 2])
(map #(+ 5 %) [0 1 2])
I find this site helpful sometimes, when looking at a language I've never seen before. If you search for "function," you'll find a whole section on how to define them. There are also six examples in the official Clojure docs for map. This is for Scala, but here's another answer on SO that explains map and reduce (left fold) pretty well.
Use partial application (see partial) to create a function that adds 5 to its argument:
(partial + 5)
You can try it yourself:
user> ((partial + 5) 10)
;; => 15
Now map it over your list:
user> (map (partial + 5) [0 1 2])
;; => [5 6 7]
I know I can do the following in Common Lisp:
CL-USER> (let ((my-list nil))
(dotimes (i 5)
(setf my-list (cons i my-list)))
my-list)
(4 3 2 1 0)
How do I do this in Clojure? In particular, how do I do this without having a setf in Clojure?
My personal translation of what you are doing in Common Lisp would Clojurewise be:
(into (list) (range 5))
which results in:
(4 3 2 1 0)
A little explanation:
The function into conjoins all elements to a collection, here a new list, created with (list), from some other collection, here the range 0 .. 4. The behavior of conj differs per data structure. For a list, conj behaves as cons: it puts an element at the head of a list and returns that as a new list. So what is does is this:
(cons 4 (cons 3 (cons 2 (cons 1 (cons 0 (list))))))
which is similar to what you are doing in Common Lisp. The difference in Clojure is that we are returning new lists all the time, instead of altering one list. Mutation is only used when really needed in Clojure.
Of course you can also get this list right away, but this is probably not what you wanted to know:
(range 4 -1 -1)
or
(reverse (range 5))
or... the shortest version I can come up with:
'(4 3 2 1 0)
;-).
Augh the way to do this in Clojure is to not do it: Clojure hates mutable state (it's available, but using it for every little thing is discouraged). Instead, notice the pattern: you're really computing (cons 4 (cons 3 (cons 2 (cons 1 (cons 0 nil))))). That looks an awful lot like a reduce (or a fold, if you prefer). So, (reduce (fn [acc x] (cons x acc)) nil (range 5)), which yields the answer you were looking for.
Clojure bans mutation of local variables for the sake of thread safety, but it is still possible to write loops even without mutation. In each run of the loop you want to my-list to have a different value, but this can be achieved with recursion as well:
(let [step (fn [i my-list]
(if (< i 5)
my-list
(recur (inc i) (cons i my-list))))]
(step 0 nil))
Clojure also has a way to "just do the looping" without making a new function, namely loop. It looks like a let, but you can also jump to beginning of its body, update the bindings, and run the body again with recur.
(loop [i 0
my-list nil]
(if (< i 5)
my-list
(recur (inc i) (cons i my-list))))
"Updating" parameters with a recursive tail call can look very similar to mutating a variable but there is one important difference: when you type my-list in your Clojure code, its meaning will always always the value of my-list. If a nested function closes over my-list and the loop continues to the next iteration, the nested function will always see the value that my-list had when the nested function was created. A local variable can always be replaced with its value, and the variable you have after making a recursive call is in a sense a different variable.
(The Clojure compiler performs an optimization so that no extra space is needed for this "new variable": When a variable needs to be remembered its value is copied and when recur is called the old variable is reused.)
For this I would use range with the manually set step:
(range 4 (dec 0) -1) ; => (4 3 2 1 0)
dec decreases the end step with 1, so that we get value 0 out.
user=> (range 5)
(0 1 2 3 4)
user=> (take 5 (iterate inc 0))
(0 1 2 3 4)
user=> (for [x [-1 0 1 2 3]]
(inc x)) ; just to make it clear what's going on
(0 1 2 3 4)
setf is state mutation. Clojure has very specific opinions about that, and provides the tools for it if you need it. You don't in the above case.
(let [my-list (atom ())]
(dotimes [i 5]
(reset! my-list (cons i #my-list)))
#my-list)
(def ^:dynamic my-list nil);need ^:dynamic in clojure 1.3
(binding [my-list ()]
(dotimes [i 5]
(set! my-list (cons i my-list)))
my-list)
This is the pattern I was looking for:
(loop [result [] x 5]
(if (zero? x)
result
(recur (conj result x) (dec x))))
I found the answer in Programming Clojure (Second Edition) by Stuart Halloway and Aaron Bedra.