I wish to add type data to a clojure vector by adding meta data. What do I need to add to this to achieve this:
(def r (ref [1 2 3]))
Note that I want to add the meta data to [1 2 3]. Is this even the right way of doing this? I mean, should I be adding meta-data to the vector [1 2 3] to "r"?
I think it should be added to 'r':
user=> (def r (ref [1 2 3] :meta {:type "vector"}))
#'user/r
user=> (meta r)
{:type "vector"}
Related
I am learning Clojure and was reading about doseq when I noticed an example like below on the official Clojure doc for doseq
(doseq [x [-1 0 1]
y [1 2 3]]
(prn (* x y)))
My confusion is with the expression [x [-1 0 1] y [1 2 3]].
Does this signify a binding expression? I tried some amount of google search but could not come across any documentation that describes such a form.
Could someone help me with understanding the various syntax representations for binding forms in Clojure?
This is a "binding form" in that it "binds" the values from the expression to the name x in turn. So it colloquially means an expression that binds names to values. This is part of "destructuring binding forms" which bind names to parts of a compound value such as a list or map.
The term "binding" instead of "setting" helps convey the difference between what this is doing and setting variables in some other programming languages. The name is attached to the value for the time it takes for the form inside the doseq to run, then the name is released to be attached to another value.
Clojure offers arbitrary structural binding to give names to any part of a value in most places in the language that assign names (bind symbols)
(doseq [[x1 x2] [[-1 -1] [0 0] [1 1]]
y [1 2 3]]
(prn (* x1 x2 y)))
is also a binding expression though it looks slightly deeper into the data and assigns names to two values per item in the first vector (and assumes there are two numbers in each of them) I'm very fond of this tutorial on destructuring/binding
It is like a nested for loop in Java. You can also do the nesting "manually":
(dotest
(newline)
(println "version 1")
(doseq [x [1 2]
y [:a :b :c]]
(println x y))
(newline)
(println "version 2")
(doseq [x [1 2]]
(doseq [y [:a :b :c]]
(println x y))))
with results:
version 1
1 :a
1 :b
1 :c
2 :a
2 :b
2 :c
version 2
1 :a
1 :b
1 :c
2 :a
2 :b
2 :c
Note that doseq always returns nil, and is only good for generating side-effects (like printing to the screen).
A for expression behaves similarly, but returns a (lazy) sequence of values (note we are generating a vector [x y] on each loop):
(newline)
(println "For generates a (lazy) sequence:"
(for [x [1 2]
y [:a :b :c]]
[x y]))
with result:
For generates a (lazy) sequence: ([1 :a] [1 :b] [1 :c] [2 :a] [2 :b] [2 :c])
I have collection of lists and I want to apply "reduce +" for each list in collection. I think I should combine "apply", "map" and "reduce +", but I can't understand how.
Example:
[[1 2 3] [4 5 3] [2 5 1]] => [6 12 8]
No need for apply. map and reduce will work fine:
(map (partial reduce +) [[1 2 3] [4 5 3] [2 5 1]])
map will call the function on each member of the list and partial simply creates a 'curried' version of reduce that expects one parameter. it could also be written like #(reduce + %) or (fn [lst] (reduce + lst))
Update
You could actually use apply in place of reduce here as well (just not both):
(map (partial apply +) [[1 2 3] [4 5 3] [2 5 1]])
Further Update
If you have any performance concerns, see the comments on this answer for some great tips by #AlexMiller
I was wondering the best way to accomplish this:
Pass along metadata important for the pipeline, but not actually part of the value
Here's what I have:
; Attach the metadata
^{:doc "How obj works!"} [1 2 3]
; [1 2 3]
; ensure that it's attached
(meta ^{:doc "How obj works!"} [1 2 3])
; {:doc "How obj works!"}
; map over the values
(map inc ^{:doc "How obj works!"} [1 2 3])
; [2 3 4]
; try and get the metadata after the map
(meta (map inc ^{:doc "How obj works!"} [1 2 3]))
; nil
I'm pretty sure I know why this is happening, but I'd like to know if there's a good way to do this, or if there's a better way to approach this problem.
Regarding a better way, there probably is. If I had an object substantial enough to require a metadata docstring explaining how it works, I think I would define records or types, and maybe a protocol.
Without knowing what you're doing or why, however, I have no informed opinion on the matter.
If you are certain you want to map a function and preserve metadata, you could try something along the outline of the following:
(defn meta-preserving-map
[f & cs]
(let [data (apply merge (map meta cs))]
(with-meta (apply map f cs) data)))
I am totally new to clojure (started learning yesterday) and functional programming so please excuse my ignorance. I've been trying to read a lot of the clojure documentation, but much of it is totally over my head.
I'm trying to iterate over an ArrayMap of this set up:
{city1 ([[0 0] [0 1] [1 1] [1 0]]), city2 ([[3 3] [3 4] [4 4] [4 3]]), city3 ([[10 10] [10 11] [11 11] [11 10]])}
(^hopefully that syntax is correct, that is what it looks like my terminal is printing)
where the city name is mapped to a vector of vectors that define the points that make up that city's borders. I need to compare all of these points with an outside point in order to determine if the outside point is in one of these cities and if so which city it is in.
I'm using the Ray Casting Algorithm detailed here to determine if an outside point is within a vector of vectors.
Maps actually implement the clojure.lang.ISeq interface which means that you can use all the higher-level sequence operations on them. The single elements are pairs of the form [key value], so, to find the first element that matches a predicate in-city? you could e.g. use some:
(some
(fn [[city-name city-points]] ;; the current entry of the map
(when (in-city? the-other-point city-points) ;; check the borders
city-name)) ;; return the name of a matching city
cities)
You might also use keep to find all elements that match the predicate but I guess there is no overlap between cities in your example.
Update: Let's back off a little bit, since working with sequences is fun. I'm not gonna dive into all the sequence types and just use vectors ([1 2 3 ...]) for examples.
Okay, for a start, let's access our vector:
(first [1 2 3]) ;; => 1
(rest [1 2 3]) ;; => [2 3]
(last [1 2 3]) ;; => 3
(nth [1 2 3] 1) ;; => 2
The great thing about functional programming is, that functions are just values which you can pass to other functions. For example, you might want to apply a function (let's say "add 2 to a number") to each element in a sequence. This can be done via map:
(map
(fn [x]
(+ x 2))
[1 2 3])
;; => [3 4 5]
If you haven't seen it yet, there is a shorthand for function values where % is the first parameter, %2 is the second, and so on:
(map #(+ % 2) [1 2 3]) ;; => [3 4 5]
This is concise and useful and you'll probably see it a lot in the wild. Of course, if your function has a name or is stored in a var (e.g. by using defn) you can use it directly:
(map pos? [-1 0 1]) ;; => [false false true]
Using the predicate like this does not make a lot of sense since you lose the actual values that produce the boolean result. How about the following?
(filter pos? [-1 0 1]) ;; => [1]
(remove pos? [-1 0 1]) ;; => [-1 0]
This selects or discards the values matching your predicate. Here, you should be able to see the connection to your city-border example: You want to find all the cities in a map that include a given point p. But maps are not sequences, are they? Indeed they are:
(seq {:a 0 :b 1}) ;; => [[:a 0] [:b 1]]
Oh my, the possibilities!
(map first {:a 0 :b 1}) ;; => [:a :b]
(filter #(pos? (second %)) {:a 0 :b 1}) ;; => [[:b 1]]
filter retrieves all the matching cities (and their coordinates) but since you are only interested in the names - which are stored as the first element of every pair - you have to extract it from every element, similarly to the following (simpler) example:
(map first (filter #(pos? (second %)) {:a 0 :b 1}))
:: => [:b]
There actually is a function that combines map and filter. It's called keep and return every non-nil value its predicate produces. You can thus check the first element of every pair and then return the second:
(keep
(fn [pair]
(when (pos? (second pair))
(first pair)))
{:a 0 b 1})
;; => [:b]
Everytime you see yourself using a lot of firsts and seconds, maybe a few rests inbetween, you should think of destructuring. It helps you access parts of values in an easy way and I'll not go into detail here but it can be used with sequences quite intuitively:
(keep
(fn [[a b]] ;; instead of the name 'pair' we give the value's shape!
(when (pos? b)
a))
{:a 0 :b 1})
;; => [:b]
If you're only interested in the first result you can, of course, directly access it and write something like (first (keep ...)). But, since this is a pretty common use case, you get some offered to you by Clojure. It's like keep but will not look beyond the first match. Let's dive into your city example whose solution should begin to make sense by now:
(some
(fn [[city-name city-points]]
(when (in-city? p city-points)
city-name))
all-cities)
So, I hope this can be useful to you.
How to add two collections efficiently in clojure ?
I tried following one. I want to know is there any other method efficient than this.
(reduce #(conj %1 %2) collection01 collection02)
It depends on what you want to achieve. If what you want in the result is a collection of specified type, that contains all element of given collections, then into is appropriate: (into coll1 coll2) returns collection of type (type coll1) with elements from coll1 and coll2.
On the other hand, if you just want to iterate over many collections (i.e. create a sequence of elements in the collections) then it is more efficient to use concat:
user> (concat [1 2 3] (list 4 5 6))
(1 2 3 4 5 6)
use into:
user> (into [1 2 3] [4 5 6])
[1 2 3 4 5 6]
user> (doc into)
-------------------------
clojure.core/into
([to from])
Returns a new coll consisting of to-coll with all of the items of
from-coll conjoined.
nil