How to iterate a range of numbers in Clojure? - clojure

I wrote a simple python function for my friend to tell why a number is now a prime:
def why_not_prime(n):
if n==2:
print(n, "is a prime.")
for i in range(2,n):
if n%i == 0:
print(n, "is not a prime because it could be divided by", i,".")
break
else:
print(n, "is a prime.")
break
I try to convert it to Clojure, but I couldn't find the way. I've no idea how to handle the for i in range(2,n). What's the usual way to do it?

In Clojure, there's really no universal answer to this as it's decided by why you want to iterate through those numbers.
You might want to produce some value for each of the numbers and then collect them in a list, in which case you want to use map or for. You might want to "summarize" them in some way (like adding them all together) in which case you'd want to use something like reduce.
In this case you want a special kind of summary; you want to know if there is some value in the range which is "appropriate" (in this case a divisor of n). There is a core function for this kind of use case called some, but it needs a function to tell it what is an "appropriate" value. There's no base function which does all we want, but we can just create one.
(defn why-not-prime [n]
(let[checker (fn [divisor] ;; A local function under the name checker, with one argument
(if (= 0 (mod n divisor));; If that argument is a divisor of n
divisor ;;then return it
false)) ;; otherwise return false - this value wasn't "appropriate"
witness (some checker (range 2 n))] ;; witness will be the first value that satisfies checker
;if there isn't such a value, witness is nil
(if witness
(str n " is composite because it can be divided by " witness)
(str n " is prime."))))
Now, this redefines your problem slightly, in that it doesn't print any message, but only return a string containing one. This is a more idiomatic formulation in a functional language where you usually defer side effects like printing as long as you can. If you want it to print, you can just wrap the entire function body with a println.

Related

what is the equivalent of += operator in clojure

what is the most correct way to translate this c++ code to clojure?
Code sample: if((J%2) == 0) {det += src[0][J]*calcDet( min, ord-1)};}
With the C++ code the value of det is being changed. Here a new value for det is being returned:
(fn [calcDet src ord min det J]
(if (zero? (mod J 2))
(+ det (* (nth (nth src 0) J)
(calcDet min (dec ord))))
det))
It is most correct to be removing mutability from your code.
J and det seem to be the only variables that are changing, so I've put them together as the last two args. You might want to reduce over values of J, where det is the accumulator, in which case use partial to get a function that leaves the last two args yet to be provided.
Alternatively you could iterate over a similar function, generating a lazy list of new states, where each state is [J det].
There is no equivalent to += in Clojure.
Well, the expression being computed that you want to add to det looks like this:
(* (get-in src [0 J]) (calcDet min (dec ord)))
Your if, assuming that there is no else, looks like this:
(when (even? J)
... do something)
And an if with an else branch looks like:
(if (even? J)
... do something
... otherwise, do something else)
To add numbers, you do:
(+ 1 2 3)
However, when it comes to += ...
To think clojurically means to think about evaluating expressions. Values are not changeable. Instead of changing det, what do you really want to do? Well, you want to calculate some value to add to whatever value you have currently bound to the name det. Then, you can either bind that result to a name, or feed it into another expression. No state, just evaluating expressions.
That being said, without larger context it's pointless to think of an "equivalent," because the whole approach to the problem would be different.
Looping, indexed arrays, and in-place mutation are all features of your code snippet. While these are consistent with modern hardware architecture (aka, "computer speak"), they are sometimes not consistent with the way our human brains naturally approach problems. So a level of abstraction on top of this often allows us to "zoom out" and look at the problem as a whole, where we often find a neater solution, if given tools to do so.
So, without knowing the context of this code, there is no "equivalent," at least not an idiomatic one. I specifically did not mention atoms, which are one of clojure's mechanisms to keep and mutate state, as they are certainly not applicable for this bit of code.

conj not updating vector inside of loop

I'm trying to teach myself clojure. This is just supposed to be a simple function that takes a value and adds each of its preceding values together and returns the sum of those values.
The problem is that while in the loop function, numbers isn't modified with conj like I would expect it to be - numbers just stays an empty vector. Why is that?
(defn sum
[number]
(do (def numbers (vector))
(loop [iteration number]
(if (> iteration 0)
(conj numbers iteration)
(recur (dec iteration))))
(map + numbers)))
A few hints (not an answer):
Don't use do.
Use let, not def, inside a function.
Use the result returned by conj, or it does nothing.
Pass the result back through the recur.
Besides, your sum function ignores its number argument.
I think you're getting confused between number (the number of things you want to add) and numbers (the things themselves). Remember,
vectors (and other data structures) know how long they are; and
they are often, as in what follows, quickly and concisely dealt with as
sequences, using first and rest instead of indexing.
The code pattern you are searching for is so common that it's been captured in a standard higher order function called reduce. You can get the effect you want by ...
(defn sum [coll] (reduce + coll))
or
(def sum (partial reduce +))
For example,
(sum (range 10))
;45
Somewhat off-topic:
If I were you, and I once was, I'd go through some of the fine clojure tutorials available on the web, with a REPL to hand. You could start looking here or here. Enjoy!
Your function does not work fro three main reasons :
you assumed that conj will update the value of variable numbers (but in fact it returns a copy of it bound to another name)
you used loop/recur pattern like in classical imperative style (it does not work the same)
Bad use of map
Thumbnail gave the idiomatic answer but here are correct use of your pattern :
(defn sum
[number]
(loop [iteration number
numbers []]
(if (<= iteration 0)
(reduce + numbers)
(recur (dec iteration) (conj numbers iteration)))))
The loop/recur pattern executes its body with updated values passed by recur.
Recur updates values listed after the loop. Here, while iteration is strictly positive, recur is executed. However, when iteration reaches 0, (reduce + numbers) (actual sum) is executed on the result of multiple recursions and so the recursion ends.

How to properly use "iterate" and "partial" in Clojure?

Most reference to iterate are for operators, and all the applications on functions are so confusing that I still don't get how to use iterate in my code, and what partial is.
I am doing a programming homework, trying to use Newton's method to get square root for a number n. That is, with guess as the initial approximation, keep computing new approximations by computing the average of the approximation and n/approximation. Continue until the difference between the two most recent approximations is less than epsilon.
I am trying to do the approximation part first, I believe that is something I need to use iterate and partial. And later the epsilon is something I need to use "take"?
Here is the code I have for approximation without the epsilon:
(defn sqrt [n guess]
(iterate (partial sqrt n) (/ (+ n (/ n guess)) 2)))
This code does not work properly though, when I enter (sqrt 2 2), it gives me (3/2 user=> ClassCastException clojure.lang.Cons cannot be cast to java.lang.Number clojure.lang.Numbers.divide (Numbers.java:155).
I guess this is the part I need to iterate over and over again? Could someone please give me some hints? Again, this is a homework problem, so please do not provide me direct solution to the entire problem, I need some ideas and explanations that I can learn from.
partial takes a function and at least one parameter for that function and returns a new function that expects the rest of the parameters.
(def take-five (partial take 5))
(take-five [1 2 3 4 5 6 7 8 9 10])
;=> (1 2 3 4 5)
iterate generates an infinite sequence by taking two parameters: a function and a seed value. The seed value is used as the first element in the generated list and the second is computed by applying the function to the seed, the second value is used as the input for the function to get the third value and so on.
(take-five (iterate inc 0))
;=> (0 1 2 3 4)
ClojureDocs offers good documentation on both functions: http://clojuredocs.org/clojure_core/clojure.core/iterate and http://clojuredocs.org/clojure_core/clojure.core/partial.
So, #ponzao explained quite well what iterate and partial do, and #yonki made the point that you don't really need it. If you like to explore some more seq functions it's probably a good idea to try it anyways (although the overhead from lazy sequences might result in a somewhat not ideal performance).
Hints:
(iterate #(sqrt n %) initial-approximation) will give you a seq of approximations.
you can use partition to create pairs of subsequent approximations.
discard everything not fulfilling the epsilon condition using drop-while
get result.
It's probably quite rewarding to solve this using sequences since you get in contact with a lot of useful seq functions.
Note: There is a full solution somewhere in the edit history of this answer. Sorry for that, didn't fully get the "homework" part.
I think you're missing the point. You don't need iterate neither partial too.
If you need to execute some computation till condition is fulfilled you can use easy to understand loop/recur instruction. loop/recur can be understood as: do some computation, check if condition is fulfilled, if yes return computed value, if not repeat computation.
Since you don't want entire solution, only an advice where to go, have a proper look on loop/recur and everything gonna be all right.
#noisesmith made good point. reduce is not for computing till condition is fullfiled, but may be useful when performing some computation with limited number of steps.

Is there a smart way to validate function input in Clojure?

I'm writing a simple DiceRoller application and I've created the primary function, however I'm wondering if there is a "smart" way to validate function inputs in Clojure rather than using branching conditionals to validate input? My function is below with a sample test, I would have to also test if n is not a number with another if or an or and it feels messy.
Also if anyone can point out a smarter way to do this function I would appreciate any feedback, this is my first attempt at trying to program functionally
(ns DiceRoller)
(defn roll
"rolls a specified number of n sided dice "
([] (roll 1 6))
([number] (roll number 6))
([number n]
(if-not number? number (throw (IllegalArgumentException. (str "incorrect input, integers only"))))
(take number (repeatedly #(+ (rand-int n) 1)))
)
)
Sure there is - you can use a :pre assertion for that.
(defn some-fun [x]
{:pre [(number? x)]}
(foo x))
Now you'll get AssertionError Assert failed: (number? x) if you pass the function a non-numeric argument x.
Checking whether the input is a number is kind of useless as #amalloy already pointed out, but there are lots of totally valid precondition (and postcondition for that matter) checks that you might want to apply to your function. You can see some more details on the subject here and here.
Mostly the Clojure attitude is "just assume you got the right thing". In this case, if you took out your check entirely, the user would get basically the same exception eventually. But if you really wanted to do this, you should do it correctly! Right now your code throws an exception on every input, because you're missing parens around (number? number).

How do you return from a function early in Clojure?

Common Lisp has return-from; is there any sort of return in Clojure for when you want to return early from a function?
When you need to bail out of a computation early, you need a way to do that, not an argument from purists. Usually you need it when you're reducing a big collection and a certain value indicates that there's no point in further processing the collection. To that end, the ever-practical Clojure provides the reduced function.
A simple example to illustrate is that when multiplying a sequence of numbers, if you encounter a zero, you already know that the final result will be zero, so you don't need to look at the rest of the sequence. Here's how you code that with reduced:
(defn product [nums]
(reduce #(if (zero? %2)
(reduced 0.0)
(* %1 %2))
1.0
nums))
reduced wraps the value you give it in a sentinel data structure so that reduce knows to stop reading from the collection and simply return the reduced value right now. Hey, it's pure-functional, even!
You can see what's going on if you wrap the above if in a do with a (println %1 %2):
user=> (product [21.0 22.0 0.0 23.0 24.0 25.0 26.0])
1.0 21.0
21.0 22.0
462.0 0.0
0.0
user=> (product [21.0 22.0 23.0 24.0 25.0 26.0])
1.0 21.0
21.0 22.0
462.0 23.0
10626.0 24.0
255024.0 25.0
6375600.0 26.0
1.657656E8
There isn't any explicit return statement in clojure. You could hack something together using a catch/throw combination if you want to, but since clojure is much more functional than common lisp, the chances you actually need an early return right in the middle of some nested block is much smaller than in CL. The only 'good' reason I can see for return statements is when you're dealing with mutable objects in a way that's not idiomatic in clojure.
I wouldn't go as far as saying that it's never useful, but I think in Clojure, if your algorithm needs a return statement, it's a major code smell.
Unless you're writing some really funky code, the only reason you'd ever want to return early is if some condition is met. But since functions always return the result of the last form evaluated, if is already this function — just put the value that you want to return in the body of the if and it will return that value if the condition is met.
I'm no expert in Clojure, but it seems it does not have those construct to try to be more functional. Take a look at what Stuart Halloway says here:
Common Lisp also supports a return-from macro to "return" from the
middle of a function. This encourages an imperative style of
programming, which Clojure discourages.
However, you can solve the same problems in a different way. Here is
the return-from example, rewritten in a functional style so that no
return-from is needed:
(defn pair-with-product-greater-than [n]
(take 1 (for [i (range 10) j (range 10) :when (> (* i j) n)] [i j])))
That is, use lazy sequences and returning values based on conditions.
As an alternative you could use cond . And if on some conditions you would need to evaluate multiple expressions use do.
Here is an example:
(defn fact [x]
(cond
(< x 0) (do (println (str x " is negative number"))
(throw (IllegalArgumentException. "x should be 0 or higher")))
(<= x 1) 1
:else (* x (fact (- x 1)))))
The if option already given is probably the best choice, and note since maps are easy, you can always return {:error "blah"} in the error condition, and{result: x} in the valid condition.
There isn't a return statement in Clojure. Even if you choose not to execute some code using a flow construct such as if or when, the function will always return something, in these cases nil. The only way out is to throw an exception, but even then it will either bubble all the way up and kill your thread, or be caught by a function - which will return a value.
In short, no. If this is a real problem for you then you can get around it with
"the maybe monad" Monads have a high intellectual overhead so for many cases clojurians tend to avoid the "if failed return" style of programming.
It helps to break the function up into smaller functions to reduce the friction from this.