NullPointerException after simple clojure program - clojure

I am working on learning clojure, and have run into a NullPointerException that seems to have nothing to do with my code. The program runs to completion before producing the error. The code:
; solves the collatz conjecture
; return one step in the sequence
(defn collatz-step [n]
(if (= (rem n 2) 0)
(/ n 2)
(+ 1 (* 3 n))))
; recurse over all numbers
(defn collatz [n]
(if (= n 1)
(println "All done!")
((println (format "N = %d" n))
(collatz (collatz-step n)))))
; get input and run it
(println "Enter a positive number:")
(collatz (read-string (read-line)))
Is there something I'm missing?

when this line runs:
((println (format "N = %d" n))
(collatz (collatz-step n)))
the println and colatz will finish leving the form like this:
(return-value-of-println return-value-of-collatz)
println returns nil yielding:
(nil return-value-of-collatz)
which is a function call to the function nil resulting in an NPE
take out the extra ()
Clojure does not have tail call elimination, so changing your recursive call to collatz to recur will keep it from blowing the stack on large values of n

Related

clojure Atom example codes: why the difference between let and def?

I read the doc https://clojure.org/reference/atoms and triy the codes about Fibonacci.
According the outputs below, in test 3, it takes as short as expected, using def. But in test 2,it take quite long time, using let instead of def to redefine fib. I wonder why let does NOT work as the same way as def?
(defn fib "original fib function" [n]
(if (<= n 1)
n
(+ (fib (dec n)) (fib (- n 2)))))
(defn memorize [f]
(let [mem (atom {})]
(fn [& args]
(if-let [e (find #mem args)]
(val e)
(let [ret (apply f args)]
(swap! mem assoc args ret)
ret)))))
(deftest test-memorize
(testing "test memoize 1 - using fib"
(println "test 1")
(is (> (time (fib 35)) 0)))
(testing "test memoize 2 - uising `(let [fib (memorize fib)])"
(println "test 2")
(let [fib (memorize fib)]
(is (> (time (fib 35)) 0))))
(testing "test memoize 3 - using `(def fib (memorize fib))"
(println "test 3")
(def fib (memorize fib))
(is (> (time (fib 35)) 0)))
The outputs:
$ lein test :only app.model-test/test-memorize
lein test app.model-test
test 1
"Elapsed time: 1418.226187 msecs"
test 2
"Elapsed time: 1391.479784 msecs"
test 3
"Elapsed time: 0.215439 msecs"
Ran 1 tests containing 3 assertions.
0 failures, 0 errors.
... why let does NOT work as the same way as def? ... Because they serve different purposes.
def creates, or updates the value of, a global var. It does not creat a local binding. (Compare to Racket where define is used at the top level to create global bindings and within functions for local bindings.) https://clojure.org/reference/special_forms#def
let creates local bindings. https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/let
(testing "test memoize 3 - using `(def fib (memorize fib))"
(println "test 3")
(def fib (memorize fib))
(is (> (time (fib 35)) 0)))
Is redefining the global value of fib to be the value returned by memorize fib. When the called with (fib 35) the memorize code will call what used to be named fib. That, original, fib calls, by name, fib which is now the memoized version, of fib to calculate fib 34. The calculation of fib 34 calls fib to calculate fib 33. So when (fib 34) returns and (fib 35) calls (fib 33), but that value is cached already. The recursive implementation of fib creates a tree of computation. By redefining fib at the top to inject memoization the work, on the first call to (fib 35) is trimming the tree to a single branch.
For let to do the same thing would require Clojure to use dynamic scope instead of lexical scope.
Some ways to observe that fib is being redefined at the top. After running you tests, (doc fib) and see that your documentation string is not there. Because fib is no longer defined as the function you wrote.
Swap the order of the let and def tests. Then let will be getting the memoized fib.
If you define fib using fn as such:
(def fib (fn fib [n]
(if (<= n 1)
n (+ (fib (dec n))
(fib (- n 2))))))
The call to fib inside will always go to itself, because it is using the local binding for fib from the fn form.
As Shannon Severance already answered. def creates a global var. let creates a local binding.
Which effect has this difference on your function?
Case 2 (let):
You create a new function (a memoized version of fib) and bind it locally to the name fib. Then you call fib. fib calls fib recursively, but inside defn fib ... fib refers to the globally defined fib, which is not memoized. So effectively, there is no caching.
(testing "test memoize 2 - uising `(let [fib (memorize fib)])"
(println "test 2")
(let [fib (memorize fib)] ;-> new memoized version of fib, which is bound to the name fib
(is (> (time (fib 35)) 0)))); but it is only available inside the let block
Effect on defn fib:
(defn fib "original fib function" [n]
(if (<= n 1)
n
(+ (fib (dec n)) (fib (- n 2))))) ;-> calls fib, but fib refers to the globally defined fib, which is not memoized
Case 3 (def):
You create a memoized version of fib, then you globally redeclare fib's value to be the new memoized version. You call fib. Fib calls itself, but now it refers to the new defined version, which is memoized.
(def fib (memorize fib)) ; -> you create a new global fn fib, which is memoized
(is (> (time (fib 35)) 0))
Effect on defn fib:
(defn fib "original fib function" [n]
(if (<= n 1)
n
(+ (fib (dec n)) (fib (- n 2))))) ; -> now, the memoized version of fib is called

Why recursive function is not memoized

Hello I can't wrap my head around this problem:
(defn integrate
"Finding the definite integral from 0 to stop"
([f dx]
(let [itg (memoize
(fn [itg stop n]
(if (<= n 0)
0
(+ (let [b (* n dx) a (- b dx)]
(println "[DEBUG] stop = " stop " and n =" n)
(* (- b a) (/ (+ (f a) (f b)) 2))
)
(itg itg stop (dec n))))))
itg (partial itg itg)]
(fn [x] (itg x (quot x dx))))))
(time ((integrate (fn [x] (* x x)) 0.1) 5))
(time ((integrate (fn [x] (* x x)) 0.1) 5))
I expect that the 2nd time I call this function, it should hit the memoized result, but it just recalculates the whole integral the second time and prints the DEBUG messages all over again.
Why this happens? How to fix this?
Two problems. 1) Each call to integrate creates a fresh memoized function, so a second call to integrate won't reuse any results computed by the first call. 2) One of the parameters to the memoized function is itself a function. It is not true that (= (fn []) (fn [])), so the memo might not match as often as you hope.
You can find a good write-up on this issue here: https://quanttype.net/posts/2020-09-20-local-memoized-recursive-functions.html

Factorial iterative illegal argument - clojure

(defn fac [n]
(def result 1)
(loop [i n c 1]
(if (<= c 5)
result
(recur (* c i) (inc c))
)
)
(println result)
)
(fac 5)
Error:Exception in thread "main" java.lang.IllegalArgumentException: loop requires a vector for its binding.
I am trying to write a function that evaluates a numbers factorial. Where is my mistake? It gives me 1 as answer
At first sight:
Don't use a def inside a defn.
The REPL will print the result of evaluating a function. Use it.
This gets us to
(defn fac [n]
(loop [i n c 1]
(if (<= c 5)
result
(recur (* c i) (inc c)))))
... which doesn't compile, because result is floating.
There are a few corrections required:
Return i, not result.
Start i at 1, not n.
Turn the test around: > instead of <=.
We end up with
(defn fac [n]
(loop [i 1, c 1]
(if (> c n)
i
(recur (* c i) (inc c)))))
... which works:
(fac 5)
=> 120
Edited to correct one-off error and improve explanation.

Integer overflow using lazy sequences in Clojure

I'm just learning to use lazy sequences in Clojure, and I'm not sure what I'm doing wrong in the following code:
(defn sum [seqn]
(reduce + seqn))
(defn fib
([] (concat [0 1] (fib 0 1)))
([a b] (lazy-seq (cons (+ a b) (fib b (+ a b))))))
(defn up-to [n seqn]
(filter (fn [x] (< x n)) seqn))
(sum (up-to 100 (fib))) => ArithmeticException integer overflow clojure.lang.Numbers.throwIntOverflow (Numbers.java:1388)
The numbers being summed shouldn't be larger than 100, so what is causing the integer overflow?
Filtering an infinite seq produces an infinite seq and reducing over this causes filter to keep looking for another matching item even after the predicate stops returning true.
Replace filter with take-while. The infinite sequence generated by (fib) will cause filter to run forever, but before that it will break due to the ArithmeticException you're experiencing. take-while will stop further evaluation of the list after the (fn [x] (< x n)) predicate evaluates to false.
(defn up-to [n seqn]
(take-while (fn [x] (< x n)) seqn))
(sum (up-to 100 (fib))) ;; => 232
starting with clojure 1.3.0 numbers don't auto-promote to bigInt/bigDecimal.
to fix this use +' instead
your 100th fibinachi number is too large for an integer
user> (nth (fib) 100)
354224848179261915075N

Mutually recursive definitions in Clojure

How do I do mutually recursive definitions in Clojure?
Here is a code in Scala to find prime numbers which uses recursive definitions:
val odds: Stream[Int] = cons(3, odds map { _ + 2 })
val primes: Stream[Int] = cons(2, odds filter isPrime)
def primeDivisors(n: Int) =
primes takeWhile { _ <= Math.ceil(Math.sqrt(n))} filter { n % _ == 0 }
def isPrime(n: Int) = primeDivisors(n) isEmpty
primes take 10
I translated this to Clojure:
(def odds (iterate #(+ % 2) 3))
(def primes (cons 2 (filter is-prime odds)))
(defn prime-divisors [n]
(filter #(zero? (mod n %))
(take-while #(<= % (Math/ceil (Math/sqrt n)))
primes)))
(defn is-prime [n] (empty? (prime-divisors n)))
(take 10 primes)
But writing the definitions in the Clojure REPL one by one gives
java.lang.Exception: Unable to resolve symbol: is-prime in this context (NO_SOURCE_FILE:8)
after I write (def primes (cons 2 (filter is-prime odds))).
Is there a way to do mutually recursive definitions in Clojure?
You need to (declare is-prime) before the first time you reference it.
This is referred to as a "forward declaration".
Greg's answer is correct. However you have to rearrange your code: (def odds ...) (declare primes) (defn prime-divisors ...) (defn prime? ...) (def primes ...). This should do the trick.
The problem is, that the definition of primes is not a function. It is executed immediately and hence tries to dereference the prime? Var which is not bound, yet. Hence the exception. Re-arranging should take care of that.
(Disclaimer: I haven't checked that the code works with the re-arrangement.)
And I think prime? is broken. (prime? 2) should give false, no?