See this example:
(let [x 1 y 2]
(match [x y]
[1 b] b
[a 2] a
:else nil))
;=> 2
I can't get my head around a few things:
Does 1 match x and gets bound to b?
Does 2 match y and gets bound to a?
Assuming I got the two points above right, why return a instead of b considering they both matched part of [x y]. Is it because it is the last clause?
Think of each pattern as a template to be matched to the input [x y] or [1 2].
The first pattern is [1 b] which matches the input because the first template item is a matching literal value 1, and the second template item is a binding that will hold any value in that position of the input, which happens to be 2 in this case. That b binding is accessible from the righthand side of the match clause, as if it were a let binding.
This example might demonstrate it more clearly:
(let [x 1 y 2]
(match [x y]
[1 b] [1 (inc b)] ;; recreate the input with (inc b)
[a 2] a ;; this never matches because prior match works
:else nil))
=> [1 3]
Does 2 match y and gets bound to a?
The pattern is a match, but it doesn't matter because the preceding pattern was already a match. If it were the successful match, a would be bound to 1.
Related
I am reading Living Clojure, and this example of reduce is throwing me off.
(reduce (fn [r x]
(+ r (* x x)))
[1 2 3])
[1 2 3] is the input to reduce, along with the anonymous function.
If each member of the vector is passed in, that would only fill in r or x parameters, where does the other parameter come from?
Is there a way to step through to watch the parameters and output change?
There's a description of the first argument on ClojureDocs, but I have to admit it's not really descriptive.
The function you pass as the first argument takes two parameters, the first one is total, the second one is current. If you call reduce with only two arguments, total in first iteration is the first item of the collection, while current in first iteration is the second item of the collection. If you pass three parameters, the second one is initial value that is passed as total in the first iteration, while the first item of the collection is passed as current in first iteration:
(reduce (fn [r x] (+ r x)) 0 [1 2 3])
would iterate like this:
(+ 0 1) ;; initial value and first item of the collection
(+ (+ 0 1) 2) ;; result and second item of the collection
(+ (+ (+ 0 1) 2) 3) ;; result and third item of the collection
while without initial value
(reduce (fn [r x] (+ r x)) [1 2 3])
would iterate like this:
(+ 1 2) ;; no initial value -> first and second item of the collection
(+ (+ 1 2) 3) ;; result and third item of the collection
You could as well just add a println to see each iteration's inputs:
(reduce
(fn [r x]
(do
(println (str "r = " r ", x = " x ", (* x x) = " (* x x) ", (+ r (* x x)) = " (+ r (* x x))))
(+ r (* x x))))
[1 2 3])
the result of running it in REPL is
r = 1, x = 2, (* x x) = 4, (+ r (* x x)) = 5
r = 5, x = 3, (* x x) = 9, (+ r (* x x)) = 14
14
I'm a Java and learning clojure.
What is exactly destructuring in clojure?
I can see this blog saying:
The simplest example of destructuring is assigning the values of a
vector.
user=> (def point [5 7])
#'user/point
user=> (let [[x y] point]
(println "x:" x "y:" y))
x: 5 y: 7
what he meant by assigning the values of a vector? Whats the real use of it?
Thanks in advance
point is a variable that contains a vector of values. [x y] is a vector of variable names.
When you assign point to [x y], destructuring means that the variables each get assigned the corresponding element in the value.
This is just a simpler way of writing:
(let [x (nth point 0) y (nth point 1)]
(println "x:" x "y:" y))
See Clojure let binding forms for another way to use destructuring.
It means making a picture of the structure of some data with symbols
((fn [[d [s [_ _]]]]
(apply str (concat (take 2 (name d)) (butlast (name s)) (drop 7 (name d))) ))
'(describing (structure (of data))))
=> "destructuring"
((fn [[d e _ _ _ _ _ i n g _ _ _ _ _ s t r u c t u r e & etc]]
[d e s t r u c t u r i n g]) "describing the structure of data")
=> [\d \e \s \t \r \u \c \t \u \r \i \n \g]
Paste those ^ examples into a REPL & play around with them to see how it works.
The term "Destructuring" sounds heavier than it is.
It's like visually matching shapes to shapes. For example:
(def nums [1 2 3 4 5 6])
(let [[a b c & others] nums]
;; do something
)
Imagine the effect of the let binding as:
1 2 3 4 5 6
| | | ( )
v v v v
[a b c & others]
;; Now we can use a, b, c, others, and of course nums,
;; inside the let binding:
user=> (let [[a b c & others] nums]
(println a)
(println b)
(println c)
(println others)
(println nums))
1
2
3
(4 5 6)
[1 2 3 4 5 6]
The goal is to concisely name items of a collection, for use inside the scope of a let binding or function (i.e. within a "lexical scope").
Why "concise"? Well, without destructuring, the let binding would look like this:
(let [a (nth nums 0) ;; or (first nums)
b (nth nums 1) ;; or (second nums)
c (nth nums 2)
others (drop 3 nums)]
;; do something
)
This illustrates the basic idea. There are many details (ifs and buts, and dos and don'ts), and it's worth reading further, in depth. Here are a few resources that explain more, with examples:
My personal favourite: Jay Fields's post on Clojure Destructuring:
http://blog.jayfields.com/2010/07/clojure-destructuring.html
A gentle introduction to destructuring, from Braveclojure:
http://www.braveclojure.com/do-things/#3_3_3__Destructuring
its used to name components of a data structure, and get their values.
Say you want to have a "person" structure. In java, you would go all the way to create a class with constructors, getters and setters for the various fields, such as name, age, height etc.
In Clojure you could skip the "ceremony" and simply have a vector with 3 slots, first for name, than for age and last for height. Now you could simply name these "components" and get their values, like so:
(def person ["Fred" 30 180])
(let [[name age height] person]
(println name age height)) ;; will print: Fred 30 180
p.s - there are better ways to make a "person" in clojure (such as records etc), this is just an example to understand what destructuring does.
Destructuring is a convenience feature which allows local bindings (not variables!) to be created easily by taking apart complex data structures (seq-ables like vectors, or associatives like hash-maps), as it is described here.
Take the following example:
(let [v [1 2 3 4 5 6]
v_0 (first v)
v_1 (nth v 1)
v_rest (drop 2 v)
m {:a 1 :b 2}
m_a (get m :a)
m_b (get m :b)
m_default (get m :c "DEFAULT")]
(println v, v_0, v_1, v_rest, m, m_a, m_b, m_default))
Then the above code can be simplified using destructuring bindings like the following:
(let [[v_0 v_1 & v_rest :as v]
[1 2 3 4 5 6]
{m_a :a m_b :b m_default :c :or {m_default "DEFAULT"} :as m}
{:a 1 :b 2}]
(println v, v_0, v_1, v_rest, m, m_a, m_b, m_default))
Destructuring patterns can be used in let bindings and function parameters (fn, defn, letfn, etc.), and also in macros to return let bindings containing such destructuring patterns.
One important usage to note is with the if-letand when-let macros. The if statement is always evaluated on the whole form, even if the destructured bindings themselves evaluate to nil:
(if-let [{:keys [a b]}
{:c 1 :d 2}]
(println a b)
(println "Not this one"))
Destructuring binds a pattern of names to a complex object by binding each name to the corresponding part of the object.
To bind to a sequence, you present a vector of names. For example ...
(let [[x y] (list 5 7)] ... )
... is equivalent to
(let [x 5, y 7] ... )
To bind to a map or to a vector by index lookup, you present a map of name-to-key pairs. For example ...
(let [{x 0, y 1} [5 7]] ... )
... is equivalent to both of the above.
As others have mentioned, you can find a full description of this powerful mechanism here.
The question doesn't really explain what I want to do but I couldn't think of anything else.
I have an empty map in the outer let function in a piece of code, and an integer array.
I want to iterate through the integer array, perform a simple task, and keep appending the resulting map to the variables in the outer variables.
(let [a {} ;outer variables
b {}]
(doseq [x [1 2 3]]
(let [r (merge a {x (* x x)}) ;I want to append this to a
s (merge b {x (+ x x)})] ;and this to b
(println (str "--a--" r "--b--" s)))))
But as soon as I get out of doseq, my a and b vars are still empty. I get that the scope of a and b doesn't extend outside of doseq for it to persist any changes done from within and that they are immutable.
How do I calculate the values of a and b in such cases, please? I tried to extract the functionality of doseq into another function and calling let with:
(let [a (do-that-function)])
etc but even then I couldn't figure out a way to keep track of all the modifications within doseq loop to then send back as a whole.
Am I approaching this in a wrong way?
Thanks
edit
Really, what I'm trying to do is this:
(let [a (doseq [x [1 2 3]] {x (* x x)})]
(println a))
but doseq returns nil so a is going to be nil :-s
All variables in clojure are immutable. If you need a mutable state you should use atoms or refs.
But in your case you can simply switch from doseq to for:
(let [a (for [x [1 2 3]] {x (* x x)})]
(println a))
Here is an example of solving your problem with atoms:
(let [a (atom {})
b (atom {})]
(doseq [x [1 2 3]]
(swap! a assoc x (* x x))
(swap! b assoc x (+ x x)))
(println "a:" #a)
(println "b:" #b))
But you should avoid using mutable state as far as possible:
(let [l [1 2 3]
a (zipmap l (map * l l))
b (zipmap l (map + l l))]
(println "a:" a)
(println "b:" b))
The trick is to think in terms of flows of data adding to existing data making new data, instead of changing past data. For your specific problem, where a data structure is being built, reduce is typically used:
(reduce (fn [result x] (assoc result x (* x x))) {} [1 2 3])
hehe, I just noticed that "reduce" might seem confusing given that it's building something, but the meaning is that a collection of things is "reduced" to one thing. In this case, we give reduce an empty map to begin with, which binds to result in the fn, and each successive mapping over the collection results in a new result, which we add to again with assoc.
You could also say:
(into {} (map (fn [x] [x (* x x)]) [1 2 3]))
In your question you wanted to make multiple things at once from a single collection. Here's one way to do that:
(reduce (fn [[a b] x] [(assoc a x (* x x)) (assoc b x (+ x x))]) [{} {}] [1 2 3])
Here we used destructuring syntax to refer to our two result structures - just make a picture of the data [with [vectors]]. Note that reduce is still only returning one thing - a vector in this case.
And, we could generalize that:
(defn xfn [n fs]
(reduce
(fn [results x] (map (fn [r f] (assoc r x (f x x))) results fs))
(repeat (count fs) {}) (range n)))
=> (xfn 4 [* + -])
({3 9, 2 4, 1 1, 0 0} {3 6, 2 4, 1 2, 0 0} {3 0, 2 0, 1 0, 0 0})
The result is a list of maps. And if you wanted to take intermediate steps in the building of these results, you could change reduce to reductions. Generally, map for transforming collections, reduce for building a single result from a collection.
I'm trying to implement the opposite of membero in clojure.core.logic, but it's returning two values instead of one. Otherwise, it works fine (returns nothing when the value is in the list, and something when it is not).
(defne nonmembero
"A relation where l is a collection, such that l does not contain x"
[x l]
([_ ()])
([_ [head]]
(!= x head))
([_ [head . tail]]
(!= x head)
(nonmembero x tail)))
Example runs:
user> (run* [x] (nonmembero 1 [2 3 4 5]))
(_0 _0)
user> (run* [x] (nonmembero 1 [2 3 1 4 5]))
()
You don't need the second pattern i.e the [_ [head]. This is causing a new branch in search space of core.logic engine and hence leads to the 2 output. The last pattern i.e [head . tail] is enough to handle the case where you have only one element in the list. Now your solution becomes:
(defne nonmembero
"A relation where l is a collection, such that l does not contain x"
[x l]
([_ ()])
([_ [head . tail]]
(!= x head)
(nonmembero x tail)))
Something is wrong with the code above. It finds a solution for the following
(run* [q](== q 1)(nonmembero q [1 2 3])) => (1)
The following gives the expected result
(run* [q](== q 1)(nonmembero2 q [1 2 3])) => ()
where nonmembero2 is
(defn nonmembero2
[x l]
(fresh [h t]
(conde
[(== l ())]
[(conso h t l)
(!= x h)
(nonmembero2 x t)])))
I need help with writing a 'sequence-maybe-m' (a monad that combines the behaviour of a sequence monad with a maybe monad).
The rule should be:
If any of the inputs are nil, then the whole expression fails.
Otherwise, evaluate the body like a sequence monad would do.
(domonad sequence-maybe-m [a [1 2 3] b [1 2 3]] (+ a b))
;; => (2 3 4 3 4 5 4 5 6)
(domonad sequence-maybe-m [a [1 2 3] b nil] (+ a b))
;; => nil
(domonad sequence-maybe-m [a [1 2 3] b (range a)] (+ a b))
;; => (1 2 3 3 4 5) same as 'for'
(domonad sequence-maybe-m [a [1 2 3] b [1 nil 3]] (+ a b))
;; => nil
It'll be a bonus if it is compatible with the clojure.algo.monads library:
(defmonad sequence-maybe-m
[m-result <...>
m-bind <...>
m-zero <...>
m-plus <...>
])
where <...> are functions.
; helper function for nil-ness
(defn nil-or-has-nil? [xs] (or (nil? xs) (some nil? xs)))
; the actual monad
(defmonad sequence-maybe-m
[m-result (fn [v] [v]) ; lift any value into a sequence
m-bind (fn [mv f] ; given a monadic value and a function
(if (nil-or-has-nil? mv) ; if any nil,
nil ; result in nil
(let [result (map f mv)] ; map over valid input seq
(if (some nil? result) ; if any nils result
nil ; return nil
(apply concat result))))) ; else flatten resulting seq
m-plus (fn [& mvs] ; given a sequence of mvs
(if (some nil-or-has-nil? mvs) ; if any nil,
nil ; result in nil
(apply concat mvs))) ; otherwise, join seqs
m-zero []]) ; empty seq is identity for concatenation
The only point really worth watching out for here is the second nil-or-has-nil? in the m-bind. The first is expected - passed a monadic value, m-bind has to determine whether it's nil-ish and should immediately result in nil. The second checks the results of the computation - if it failed (producing any nil), then the overall result must be nil (as opposed to, say, the empty list resulting from (apply concat [nil nil ...])).
The output of domonad must be a monadic value, in the case of sequence-m that means it must be a sequence. Asking for an output of nil breaks that and you do not have a monad.
What you are probably looking for is adding "maybe" to the sequence-monad directly using monadic transformers, quite easy to do and described here: http://clojuredocs.org/clojure_contrib/1.2.0/clojure.contrib.monads/maybe-t.
You will want to write
(def sequence-maybe-m (maybe-t sequence-m))
where maybe-t adds the "maybe" to the sequence monad. Using this will make
(domonad sequence-maybe-m [a [1 2 3] b [1 nil 3]] (+ a b))
yield
(2 nil 4 3 nil 5 4 nil 6)
which is valid output for a monad of this type. If you need to cancel out results that have nil in them, just use some nil? on the output of the monad to check them.
Binding nil to b as you ask for in your example
(domonad sequence-maybe-m [a [1 2 3] b nil] (+ a b))
does not make sense either, since nil is not a sequence. In the transformed monad, the return value would be the empty list (). It would be more appropriate to bind [nil] to b, then you would get (nil nil nil).
It helps to remember that monads are used to compose functions of the same signature and can themselves be part of such a composition, so they must yield monadic values (in this case, sequences) themselves and in their body any binding must also be with a monadic value.