In Clojure we see the following examples of using map:
(map inc [1 2 3 4 5])
;;=> (2 3 4 5 6)
We observe that map takes a function and applies it to each element in a collection.
In Clojure we see the following example of using juxt:
((juxt inc dec) 2)
;=>[3 1]
We observe that juxt takes a data structure and applies each function to it.
My question is: Is juxt the opposite of map?
(In that you map a data structure over a collection of functions instead of the other way around)
I don't think you can call juxt the opposite of map. Juxt composes a number of functions into one function that produces a sequence of the result of applying each of the functions to its argument(s).
I guess juxt could be (should be?) expressed using a map
(defn juxt [& funs] (fn [& args] (map #(apply % args)) funs))
Related
I'm learning Clojure and started by copying the functionality of a Python program that would create genomic sequences by following an (extremely simple) Hidden Markov model.
In the beginning I stuck with my known way of serial programming and used the def keyword a lot, thus solving the problem with tons of side effects, kicking almost every concept of Clojure right in the butt. (although it worked as supposed)
Then I tried to convert it to a more functional way, using loop, recur, atom and so on. Now when I run I get an ArityException, but I can't read the error message in a way that shows me even which function throws it.
(defn create-model [name pA pC pG pT pSwitch]
; converts propabilities to cumulative prop's and returns a char
(with-meta
(fn []
(let [x (rand)]
(if (<= x pA)
\A
(if (<= x (+ pA pC))
\C
(if (<= x (+ pA pC pG))
\G
\T))))) ; the function object
{:p-switch pSwitch :name name})) ; the metadata, used to change model
(defn create-genome [n]
; adds random chars from a model to a string and switches models randomly
(let [models [(create-model "std" 0.25 0.25 0.25 0.25 0.02) ; standard model, equal props
(create-model "cpg" 0.1 0.4 0.4 0.1 0.04)] ; cpg model
islands (atom 0) ; island counter
m (atom 0)] ; model index
(loop [result (str)]
(let [model (nth models #m)]
(when (< (rand) (:p-switch (meta model))) ; random says "switch model!"
; (swap! m #(mod (inc #m) 2)) ; swap model used in next iteration
(swap! m #(mod (inc %) 2)) ; EDIT: correction
(if (= #m 1) ; on switch to model 1, increase island counter
; (swap! islands #(inc #islands)))) ; EDIT: my try, with error
(swap! islands inc)))) ; EDIT: correction
(if (< (count result) n) ; repeat until result reaches length n
(recur (format "%s%c" result (model)))
result)))))
Running it works, but calling (create-genome 1000) leads to
ArityException Wrong number of args (1) passed to: user/create-genome/fn--772 clojure.lang.AFn.throwArity (AFn.java:429)
My questions:
(obviously) what am I doing wrong?
how exactly do I have to understand the error message?
Information I'd be glad to receive
how can the code be improved (in a way a clojure-newb can understand)? Also different paradigms - I'm grateful for suggestions.
Why do I need to put pound-signs # before the forms I use in changing the atoms' states? I saw this in an example, the function wouldn't evaluate without it, but I don't understand :)
Since you asked for ways to improve, here's one approach I often find myself going to : Can I abstract this loop into a higher order pattern?
In this case, your loop is picking characters at random - this can be modelled as calling a fn of no arguments that returns a character - and then accumulating them together until it has enough of them. This fits very naturally into repeatedly, which takes functions like that and makes lazy sequences of their results to whatever length you want.
Then, because you have the entire sequence of characters all together, you can join them into a string a little more efficiently than repeated formats - clojure.string/join should fit nicely, or you could apply str over it.
Here's my attempt at such a code shape - I tried to also make it fairly data-driven and that may have resulted in it being a bit arcane, so bear with me:
(defn make-generator
"Takes a probability distribution, in the form of a map
from values to the desired likelihood of that value appearing in the output.
Normalizes the probabilities and returns a nullary producer fn with that distribution."
[p-distribution]
(let[sum-probs (reduce + (vals p-distribution))
normalized (reduce #(update-in %1 [%2] / sum-probs) p-distribution (keys p-distribution) )]
(fn [] (reduce
#(if (< %1 (val %2)) (reduced (key %2)) (- %1 (val %2)))
(rand)
normalized))))
(defn markov-chain
"Takes a series of states, returns a producer fn.
Each call, the process changes to the next state in the series with probability :p-switch,
and produces a value from the :producer of the current state."
[states]
(let[cur-state (atom (first states))
next-states (atom (cycle states))]
(fn []
(when (< (rand) (:p-switch #cur-state))
(reset! cur-state (first #next-states))
(swap! next-states rest))
((:producer #cur-state)))))
(def my-states [{:p-switch 0.02 :producer (make-generator {\A 1 \C 1 \G 1 \T 1}) :name "std"}
{:p-switch 0.04 :producer (make-generator {\A 1 \C 4 \G 4 \T 1}) :name "cpg"}])
(defn create-genome [n]
(->> my-states
markov-chain
(repeatedly n)
clojure.string/join))
To hopefully explain a little of the complexity:
The let in make-generator is just making sure the probabilities sum to 1.
make-generator makes heavy use of another higher-order looping pattern, namely reduce. This essentially takes a function of 2 values and threads a collection through it. (reduce + [4 5 2 9]) is like (((4 + 5) + 2) + 9). I chiefly use it to do a similar thing to your nested ifs in create-model, but without naming how many values are in the probability distribution.
markov-chain makes two atoms, cur-state to hold the current state and next-states, which holds an infinite sequence (from cycle) of the next states to switch to. This is to work like your m and models, but for arbitrary numbers of states.
I then use when to check if the random state switch should occur, and if it does perform the two side effects I need to keep the state atoms up to date. Then I just call the :producer of #cur-state with no arguments and return that.
Now obviously, you don't have to do this exactly this way, but looking for those patterns certainly does tend to help me.
If you want to go even more functional, you could also consider moving to a design where your generators take a state (with seeded random number generator) and return a value plus a new state. This "state monad" approach would make it possible to be fully declarative, which this design isn't.
Ok, it's a long shot, but it looks like your atom-updating functions:
#(mod (inc #m) 2)
and
#(inc #islands)
are of 0-arity, and they should be of arity at least 1.
This leads to the answer to your last question: the #(body) form is a shortcut for (fn [...] (body)). So it creates an anonymous function.
Now the trick is that if body contains % or %x where x is a number, the position where it appears will be substituted for the referece to the created function's argument number x (or the first argument if it's only %).
In your case that body doesn't contain references to the function arguments, so #() creates an anonymous function that takes no arguments, which is not what swap! expects.
So swap tries to pass an argument to something that doesn't expect it and boom!, you get an ArityException.
What you really needed in those cases was:
(swap! m #(mod (inc %) 2)) ; will swap value of m to (mod (inc current-value-of-m) 2) internally
and
(swap! islands inc) ; will swap value of islands to (inc current-value-of-islands) internally
respectively
Your mistake has to do with what you asked about the hashtag macro #.
#(+ %1 %2) is shorthand for (fn [x y] (+ x y)). It can be without arguments too: #(+ 1 1). That's how you are using it. The error you are getting is because swap! needs a function that accepts a parameter. What it does is pass the atom's current value to your function. If you don't care about its state, use reset!: (reset! an-atom (+ 1 1)). That will fix your error.
Correction:
I just took a second look at your code and realised that you are actually using working on the atoms' states. So what you want to do is this:
(swap! m #(mod (inc %) 2)) instead of (swap! m #(mod (inc #m) 2)).
As far as style goes, you are doing good. I write my functions differently every day of the week, so maybe I'm not one to give advice on that.
I am currently completing chapter 7 of the htdp book and am trying to create
an instance of the spider structure:
#lang racket
;; spider-structure: structure -> ???
;; defines a spider structure with two parameters: legs and volume
(define-struct spider (legs volume))
;; spidercheck: lambda -> num
;; creates a spider check function and determines volume based on legs
(define spidercheck
(lambda (legs)
(cond
((<= legs 4) 800)
((> legs 4) 1000))))
(define a-spider
(make-spider 4
(spidercheck ...
My problem is that I want to pass the number from (make-spider 4) to the spidercheck function within the a-spider function. I have tried (spider-legs a-spider) but of course it says it is used before its definition. Any help is appreciated.
Thanks!
A simplistic solution would be to call make-spider and spidercheck with the same parameter, let's say the number 2:
(define spiderman (make-spider 2 (spidercheck 2)))
A more interesting alternative would be to define a new function that enforces the restriction that the same n, the number of legs, is passed as parameter for both make-spider and spider check:
(define a-spider
(lambda (n)
(make-spider n (spidercheck n))))
Now, whenever you want to create a spider you can specify just the number of legs as parameter, and let spidercheck take care of calculating the volume. Also notice that you can simplify the above snippet even more, using the define syntax that makes the lambda implicit:
(define (a-spider n)
(make-spider n (spidercheck n)))
Either way, to create a new spider (for instance, with 8 legs) do this:
(define charlotte (a-spider 8))
Try using let and reusing the number 4 that way.
I'm not too sure how the book is handling spiders but you might need this pattern:
(define a-spider
(let ([a-legs 4])
(make-spider a-legs (spidercheck a-legs))))
This answer is inferior to Oscar's as it hardcodes the number of legs a spider has. But it does show one way to reference a value multiple times.
I read a lot of documentation about Clojure (and shall need to read it again) and read several Clojure questions here on SO to get a "feel" of the language. Besides a few tiny functions in elisp I've never written in any Lisp language before. I wrote my first project Euler solution in Clojure and before going further I'd like to better understand something about map and reduce.
Using a lambda, I ended up with the following (to sum all multiple of either 3 or 5 or both between 1 and 1000 inclusive):
(reduce + (map #(if (or (= 0 (mod %1 3)) (= 0 (mod %1 5))) %1 0) (range 1 1000)))
I put it on one line because I wrote it on the REPL (and it gives the correct solution).
Without the lambda, I wrote this:
(defn val [x] (if (or (= 0 (mod x 3)) (= 0 (mod x 5))) x 0))
And then I compute the solution doing this:
(reduce + (map val (range 1 1000)))
In both cases, my question concerns what the map should return, before doing the reduce. After doing the map I noticed I ended up with a list looking like this: (0 0 3 0 5 6 ...).
I tried removing the '0' at the end of the val definition but then I received a list made of (nil nil 3 nil 5 6 etc.). I don't know if the nil are an issue or not. I figured out that I was going to sum while doing a fold-left anyway so that the zero weren't really an issue.
But still: what's a sensible map to return? (0 0 3 0 5 6 ...) or (nil nil 3 nil 5 6...) or (3 5 6 ...) (how would I go about this last one?) or something else?
Should I "filter out" the zeroes / nils and if so how?
I know I'm asking a basic question but map/reduce is obviously something I'll be using a lot so any help is welcome.
It sounds like you already have an intuative undestanding of the need to seperate mapping concerns form the reducing It's perfectly natural to have data produced by map that is not used by the reduce. infact using the fact that zero is the identity value for addition make this even more elegant.
mappings job is to produce the new data (in this case 3 5 or "ignore")
reduces job is to decide what to include and to produce the final result.
what you started with is idiomatic clojure and there is no need to complicate it any more,
so this next example is just to illustrate the point of having map decide what to include:
(reduce #(if-not (zero? %1) (+ %1 %2) %2) (map val (range 10)))
in this contrived example the reduce function ignores the zeros. In typical real world code if the idea was as simple as filtering out some value then people tend to just use the filter function
(reduce + (filter #(not (zero? %)) (map val (range 10))))
you can also just start with filter and skip the map:
(reduce + (filter #(or (zero? (rem % 3)) (zero? (rem % 5))) (range 10)))
The watchword is clarity.
Use filter, not map. Then you don't have to choose a null
value that you later have to decide not to act on.
Naming the filtering/mapping function can help. Do so with let
or letfn, not defn, unless you have use for the function elsewhere.
Acting on this advice brings us to ...
(let [divides-by-3-or-5? (fn [n] (or (zero? (mod n 3)) (zero? (mod n 5))))]
(reduce + (filter divides-by-3-or-5? (range 1 1000))))
You may want to stop here for now.
This reads well, but the divides-by-3-or-5? function sticks in the throat. Change the factors and we need a completely new function. And that repeated phrase (zero? (mod n ...)) jars. So ...
We want a function, that - given a list (or other collection) of possible factors - tells us whether any of them apply to a given number. In other words, we want
a function of a collection of numbers - the possible factors - ...
that returns a function of one number - the candidate - ...
that tells us whether the candidate is divisible by any of the possible factors.
One such function is
(fn [ns] (fn [n] (some (fn [x] (zero? (mod n x))) ns)))
... which we can employ thus
(let [divides-by-any? (fn [ns] (fn [n] (some (fn [x] (zero? (mod n x))) ns)))]
(reduce + (filter (divides-by-any? [3 5]) (range 1 1000))))
Notes
This "improvement" has made the program a little slower.
divides-by-any? might prove useful enough to be promoted to a
defn.
If the operation were critical, you could consider stripping out
redundant factors. For example [2 3 6] could be reduced to [6].
If the operation were really critical, and the factors were supplied
as constants, you could consider creating the filter function with a
macro that went back to using or.
This is a bit of a shaggy-dog story, but it recounts the thoughts prompted by the problem you refer to.
In your case I would use keep instead of map. It is similar to map except that it keeps only the non-nil values.
Whilst learning Clojure, I've spent ages trying to make sense of monads - what they are and how we can use them.... with not too much success. However, I found an excellent 'Monads for Dummies' Video Series - http://vimeo.com/20717301 - by Brian Marik for Clojure
So far, my understanding of monads is that it is sort of like a macro in that it allows a set of statements to be written in a form that is easy to read - but monads are much more formalised. My observations are limited to two examples:
1. The Identity Monad (or the 'let' monad) taken from http://onclojure.com/2009/03/05/a-monad-tutorial-for-clojure-programmers-part-1/
The form that we wish to write is:
(let [a 1
b (inc a)]
(* a b))
and the corresponding monad is
(domonad identity-m
[a 1
b (inc a)]
(* a b))
2. The Sequence Monad (or the 'for' monad) taken from http://onclojure.com/2009/03/06/a-monad-tutorial-for-clojure-programmers-part-2/
The form we wish to write is:
(for [a (range 5)
b (range a)]
(* a b))
and the corresponding monad is
(domonad sequence-m
[a (range 5)
b (range a)]
(* a b))
Monad Definitions in Clojure
Looking at the source, using clojure monads library - https://github.com/clojure/algo.monads:
user=>(use 'clojure.algo.monads)
nil
indentity monad:
user=> (source identity-m)
(defmonad identity-m
[m-result identity
m-bind (fn m-result-id [mv f]
(f mv))
])
sequence monad:
user=> (source sequence-m)
(defmonad sequence-m
[m-result (fn m-result-sequence [v]
(list v))
m-bind (fn m-bind-sequence [mv f]
(flatten* (map f mv)))
m-zero (list)
m-plus (fn m-plus-sequence [& mvs]
(flatten* mvs))
])
So my conclusion is that a monad is some sort of a generalised higher-order function that takes in an input-function and input-values, adds its own control logic and spits out a 'thing' that can be used in a 'domonad' block.
Question 1
So finally, to the questions: I want to learn how to write a monad and say I want to write a 'map monad' that imitates the 'map' form in clojure:
(domonad map-m
[a [1 2 3 4 5]
b [5 6 7 8 9]]
(+ a b))
Should be equivalent to
(map + [1 2 3 4 5] [5 6 7 8 9])
and return the values
[6 8 10 12 14]
If I look at the source, it should give me something similar to identity-m and sequence-m:
user=> (source map-m)
(defmonad map-m
[m-result ...
m-bind ...
m-zero ...
m-plus ...
])
Question 2
I also want to be able to define 'reduce-m' such that I can write:
(domonad reduce-m
[a [1 2 3 4 5]]
(* a))
this could potentially give me 1 x 2 x 3 x 4 x 5 = 120 or
(domonad reduce-m
[a [1 2 3 4 5]
b [1 2 3 4 5]]
(+ a b))
will give me (1+2+3+4+5) + (1+2+3+4+5) = 30
Finally
Would I also be able to write a 'juxt monad' that imitates the juxt function but instead of passing in values for binding, I pass in a set of functions. :
(domonad juxt-m
[a #(+ % 1)
b #(* % 2)]
'([1 2 3 4 5] b a) )
gives
[ [2 2] [4 3] [6 4] [8 5] [9 6] ]
Potentially, I could do all of those things with macros so I don't really know how useful these 'monads' will be or if they are even considered 'monads'... With all the resources on the internet, It seems to me that if I wanted to learn Monads properly, I have to learn Haskell and right now, learning another syntactic form is just too hard. I think I found some links that maybe relevant but it is too cryptic for me
Please can someone shed some light!
Your examples are not monads. A monad represents composable computational steps. In the trivial identity monad, the computational step is just an expression evaluation.
In the maybe monad, a step is an expression that may succeed or fail.
In the sequence monad, a step is an expression that produces a variable number of results (the elements of the sequence).
In the writer monad, a computational step is a combination of expression evaluation and log output. In the state monad, a computational step involves accessing and/or modifying a piece of mutable state.
In all these cases, the monad plumbery takes care of correctly combining steps. The m-result function packages a "plain" value to fit into the monadic computation scheme, and the m-bind function feeds the result of one computational step into the next computational step.
In (map + a b), there are no computational steps to be combined. There is no notion of order. It's just nested expression evaluation. Same for reduce.
Your questions are not a type of monads. They seems more like a syntactic sugar and that you can accomplish using macros and I won't even suggest you do that because map, reduce etc are simple functions and there is no need to make their interface complex.
The reason these cases are not monads because moands are sort of amplified values which wrap normal values. In map and reduce case the vector that you use doesn't needs to be amplified to allow it to work in map or reduce.
It would be helpful for you to try macroexpand on the domoand expressions.
For ex: the sequence monad example should expand to something like:
(bind (result (range 5))
(fn [a]
(bind (result (range a))
(fn [b] (* a b))
)))
Where the bind and result are functions defined in the sequence monad m-bind and m-result.
So basically the vector expression(s) after the domand get nested and the expression(s) after the vector are used as it is in above case the (* a b) is called as it is (just that the a and b values are provided by the monad). In your example of map monad the vector expressions are supposed to be as it is and the last expression (+ a b) should somehow mean (map + a b) which is not what a monad is supposed to do.
I found some really good monads resources:
http://www.clojure.net/tags.html#monads-ref (Jim Duey's Monads Guide, which really goes into the nitty gritty monad definitions)
http://homepages.inf.ed.ac.uk/wadler/topics/monads.html#marktoberdorf (A whole load of papers on monads)
http://vimeo.com/17207564 (A talk on category theory, which I half followed)
So from Jim's Guide - http://www.clojure.net/2012/02/06/Legalities/ - he gives three axioms for definition of 'bind-m' and 'reduce-m' functions:
Identity
The first Monad Law can be written as
(m-bind (m-result x) f) is equal to (f x)
What this means is that whatever m-result does to x to make it into a monadic value, m-bind undoes before applying f to x. So with regards to m-bind, m-result is sort of like an identity function. Or in category theory terminology, its unit. Which is why sometimes you’ll see it named ‘unit’.
Reverse Identity The second Monad Law can be written as
(m-bind mv m-result) is equal to mv where mv is a monadic value.
This law is something like a complement to the first law. It basically ensures that m-result is a monadic function and that whatever m-bind does to a monadic value to extract a value, m-result undoes to create a monadic value.
Associativity
The third Monad Law can be written as
(m-bind (m-bind mv f) g) is equal to (m-bind mv (fn [x] (m-bind (f x) g)))
where f and g are monadic functions and mv is a monadic value.
What this law is saying is that it doesnt matter whether the f is applied to mv and then g is applied to the result, or whether a new monadic function is created out of a composition of f and g which is then applied to mv. In either order, the resulting value is the same monadic value. Stated another way, m-bind is left and right associative.
In http://www.clojure.net/2012/02/04/Sets-not-lists/ he gives an monad that takes sets as inputs instead of taking lists. Will work through all the examples...
Learning clojure, trying to create a lazy infinite sequence of all prime numbers.
I'm aware that there are more efficient algorithms; I'm doing the following more as a POC/lesson than as the ideal solution.
I have a function that, given a sequence of primes, tells me what the next prime is:
(next-prime [2 3 5]) ; result: 7
My lazy sequence must therefore pass itself to this function, then take the result and add that to itself.
My first attempt:
(def lazy-primes
(lazy-cat [2 3 5] (find-next-prime lazy-primes)))
..which results in an IllegalArgumentException: Don't know how to create ISeq from: java.lang.Integer
My second attempt:
(def lazy-primes
(lazy-cat [2 3 5] [(find-next-prime lazy-primes)]))
..which gives me [2 3 5 7] when asked for 10 elements.
Attempt 3:
(def lazy-primes
(lazy-cat [2 3 5]
(conj lazy-primes (find-next-prime lazy-primes))))
(take 10 lazy-primes) ; result: (2 3 5 7 2 3 5 7 2 3)
All of these seem like they should work (or at least, should work given that the preceding didn't work). Why am I getting the bogus output for each case?
Reasons why your initial attempts don't work:
(find-next-prime lazy-primes) returns an integer but lazy-cat needs a sequence
[(find-next-prime lazy-primes)] creates a vector (and is hence seqable) but it only gets evaluated once when it is first accessed
conj is adding new primes to the start of the sequence (since lazy-cat and hence lazy-primes returns a sequence)... which is probably not what you want! It's also possibly confusing find-next-prime depending on how that is implemented, and there might be a few subtle issues around chunked sequences as well.....
You might instead want to use something like:
(defn seq-fn [builder-fn num ss]
(cons
(builder-fn (take num ss))
(lazy-seq (seq-fn builder-fn (inc num) ss))))
(def lazy-primes
(lazy-cat [2 3 5] (seq-fn next-prime 3 lazy-primes)))
A bit complicated, but basically what I'm doing is using the higher-order helper function to provide a closure over a set of parameters that includes the number of primes created so far, so that it can generate the next prime incrementally at each step.
p.s. as I'm sure you are aware there are faster algorithms for generating primes! I'm assuming that this is intended primarily as an exercise in Clojure and the use of lazy sequences, in which case all well and good! But if you really care about generating lots of primes I'd recommend taking a look at the Sieve of Atkin
Alternatively, you could use iterate: the built-in function that lazily takes the output of a function and applies that to the function again
clojure.core/iterate
([f x])
Returns a lazy sequence of x, (f x), (f (f x)) etc.
f must be free of side-effects
in order for you to make it work, the next-prime function should concatenate its result to its input, and return the concatenation.
Then you can just call (take 100 (iterate list-primes [1])) to get a list of the first 100
primes.
With your next-prime function you can generate a lazy sequence of all primes with the following snippet of code:
(def primes (map peek (iterate #(conj % (next-prime %)) [2])))
The combination you are looking for is concat + lazy-seq + local fn.
Take a look at the implementation of Erathostenes' Sieve in the Clojure Contrib libraries: https://github.com/richhickey/clojure-contrib/blob/78ee9b3e64c5ac6082fb223fc79292175e8e4f0c/src/main/clojure/clojure/contrib/lazy_seqs.clj#L66
One more word, though: this implementation uses a more sophisticated algorithm for the Sieve in a functional language.
Another implementation for Clojure can be found in Rosetta code. However, I don't like that one as it uses atoms, which you don't need for the solution of this algo in Clojure.