I've defined the following functions in Clojure.
; return the input unchanged
(defn same [x] x)
; Recursively call the function on the input N times
(defn recurse-n-times [input function n]
(if (= n 0)
input
(recurse-n-times (function input) function (- n 1))
)
)
Here are some outputs from my recursion function:
(recurse-n-times 0 inc 5) ; returns 5, as expected
(recurse-n-times 0 same 5) ; returns 0, as expected
(recurse-n-times 0 same 5000) ; StackOverflowError:
; clojure.lang.Numbers$LongOps.combine
; (Numbers.java:394)
I don't understand why I get a StackOverflowError. The last thing that recurse-n-times does is call itself, so I expect it to use tail recursion and not grow the stack at all.
I would expect this alternate definition to give a StackOverflowError:
(defn bad-recurse-n-times [input function n]
(if (= n 0)
input
(function (alt-recurse-n-times input function (- n 1)))
)
)
Why does recurse-n-times not use tail recursion?
This is a limitation of the JVM, not of Clojure. JVM doesn't support TCO.
Clojure offers a special form for this, recur
(defn recurse-n-times [input function n]
(if (= n 0)
input
(recur (function input) function (- n 1))))
(recurse-n-times 0 same 500000) ;; will work
recur form should appear at the tail position otherwise the Clojure compiler will complain about it.
Note that recur is the only non-stack-consuming looping construct in Clojure. There is no tail-call optimization and the use of self-calls for looping of unknown bounds is discouraged. recur is functional and its use in tail-position is verified by the compiler.
According to clojure.org
There is no tail-call optimization, use recur.
So you must use "recur" special form to do that.
Related
To preface this, I'm very new to Clojure. I was wondering why I'm getting a ClassCastExpection on this piece of code. I've looked at it and syntactically and logically it looks correct?
Clojure Code:
; (load-file "cje842asg1.clj")
(def lstnum '(76 85 71))
; 2a
(defn sum [list] (
(if (empty? list)
0
(+ (first list (sum (rest list))))
)
)
)
; if empty return zero, else add the first num in list and pass in the
; rest.
(sum lstnum)
Any help is appreciated.
The code has 2 separate errors.
The first is calling (first list (sum (rest list))) which is calling first with 2 arguments when you meant to make the second part the second argument to +.
The other one leading to the actual exception is the extra () around the function body. Note the ((if ...)) which means you are trying to call whatever the if returns as a function. In this case it is returning a number, leading to the class java.lang.Long cannot be cast to class clojure.lang.IFn error.
The corrected version would be
(defn sum [list]
(if (empty? list)
0
(+ (first list)
(sum (rest list)))))
Moving the arguments to + into separate lines makes it easier to read in this case (IMHO).
(defn factorial [n fact]
(if <= n 1)
fact
(factorial (- n 1) (* n fact)))
(defn fact [n]
(factorial (n 1)))
It looks like you're trying to write factorial using a parameter to carry the total, but your parentheses aren't quite right.
(factorial (n 1))
Because n is the first item in a list, it gets called as a function. But being a number, it can't be used that way.
To call the factorial function (with n as input and 1 as the initial total), you probably mean
(defn fact [n]
(factorial n 1))
There are additional problems in your factorial function.
(if <= n 1)
<= is a function, so it needs to be called when used as an argument to if
(if (<= n 1)
...
The recursive call to factorial is pretty much what you want for your solution, but there're some mismatched parentheses, here's what you probably meant
(defn factorial [n fact]
(if (<= n 1)
fact
(factorial (- n 1) (* n fact))))
However, there's a bit of correctness/idiomatic clojure slang that can be used, here's a slightly better way to do your full solution
(defn factorial [n total]
(if (<= n 1)
total
(recur (dec n) (* n total))))
(defn fact [n]
(factorial n 1))
Although, if you use the call stack to carry the total, you can do slightly better
(defn factorial [n]
(if (<= n 1)
1
(* n (factorial (dec n)))))
You could restructure this slightly to use recur, which would give you some slightly better performance, but I assume this is an academic exercise and you can look at other answers (such as Alan Thompson's answer for that).
You can see 2 examples showing of solving the factorial problem the using recursion compared to loop/recur in this question:
How to use tail recursion correctly?
Learning Clojure and trying to understand the implementation:
What's the difference from:
(def factorial
(fn [n]
(loop [cnt n acc 1]
(if (zero? cnt)
acc
(recur (dec cnt) (* acc cnt))
; in loop cnt will take the value (dec cnt)
; and acc will take the value (* acc cnt)
))))
and the following C-like pseudocode
function factorial (n)
for( cnt = n, acc = 1) {
if (cnt==0) return acc;
cnt = cnt-1;
acc = acc*cnt;
}
// in loop cnt will take the value (dec cnt)
// and acc will take the value (* acc cnt)
Are clojure's "loop" and "recur", forms specifically designed to code a simple imperative loop ?
(assuming pseudocode's "for" creates it's own scope, so cnt and acc exists only inside the loop)
Are Clojure's loop and recur forms specifically designed to code a simple imperative loop?
Yes.
In functional terms:
A loop is a degenerate form of recursion called tail-recursion.
The 'variables' are not modified in the body of the loop. Instead,
they are re-incarnated whenever the loop is re-entered.
Clojure's recur makes a tail-recursive call to the surrounding recursion point.
It re-uses the one stack frame, so working faster and avoiding stack
overflow.
It can only happen as the last thing to do in any call - in so-called tail position.
Instead of being stacked up, each successive recur call overwrites the last.
A recursion point is
a fn form, possibly disguised in defn or letfn OR
a loop form, which also binds/sets-up/initialises the
locals/variables.
So your factorial function could be re-written
(def factorial
(fn [n]
((fn fact [cnt acc]
(if (zero? cnt)
acc
(fact (dec cnt) (* acc cnt))))
n 1)))
... which is slower, and risks stack overflow.
Not every C/C++ loop translates smoothly. You can get trouble from nested loops where the inner loop modifies a variable in the outer one.
By the way, your factorial function
will cause integer overflow quite quickly. If you want to avoid
this, use 1.0 instead of 1 to get floating point (double)
arithmetic, or use *' instead of * to get Clojure's BigInt
arithmetic.
will loop endlessly on a negative argument.
A quick fix for the latter is
(def factorial
(fn [n]
(loop [cnt n acc 1]
(if (pos? cnt)
(recur (dec cnt) (* acc cnt))
acc))))
; 1
... though it would be better to return nil or Double.NEGATIVE_INFINITY.
One way to look at loop/recur is that it lets you write code that is functional, but where the underlying implementation ends up essentially being an imperative loop.
To see that it is functional, take your example
(def factorial
(fn [n]
(loop [cnt n acc 1]
(if (zero? cnt)
acc
(recur (dec cnt) (* acc cnt))))))
and rewrite it so that the loop form is broken out to a separate helper function:
(def factorial-helper
(fn [cnt acc]
(if (zero? cnt)
acc
(recur (dec cnt) (* acc cnt)))))
(def factorial'
(fn [n]
(factorial-helper n 1)))
Now you can see that the helper function is simply calling itself; you can replace recur with the function name:
(def factorial-helper
(fn [cnt acc]
(if (zero? cnt)
acc
(factorial-helper (dec cnt) (* acc cnt)))))
You can look at recur, when used in factorial-helper as simply making a recursive call, which is optimized by the underlying implementation.
I think an important idea is that it allows the underlying implementation to be an imperative loop, but your Clojure code still remains functional. In other words, it is not a construct that allows you to write imperative loops that involve arbitrary assignment. But, if you structure your functional code in this way, you can gain the performance benefit associated with an imperative loop.
One way to successfully transform an imperative loop to this form is to change the imperative assignments into expressions that are "assigned to" the argument parameters of the recursive call. But, of course, if you encounter an imperative loop that makes arbitrary assignments, you may not be able to translate it into this form. In this view, loop/recur is a much more constrained construct.
I'm trying to solve the Count a Sequence problem on 4Clojure, but I can't work out what's wrong with my use of recur:
fn [s] (
fn [t n] (
if (empty t)
n
(recur (rest t) (+ n 1))
) s 0
)
It gives the following exception:
java.lang.UnsupportedOperationException: Can only recur from tail position, compiling:(NO_SOURCE_PATH:0)
But to me it seems that the call to recur is in a tail position for the inner function. What am I missing?
Two problems:
Your parentheses are misplaced.
You are using empty where you want empty?.
Parentheses
The fn special form for defining a function takes the shape
(fn name? [params* ] exprs*) with the parentheses around it.
Another level of parentheses applies the function ((fn [n] (* n n))
3) => 9.
Using defn instead of fn for the moment, we get
(defn l [s]
((fn [t n] (if (empty? t) n (recur (rest t) (+ n 1))))
s 0))
Then, for example,
(l ())
; 0
and
(l [1 2 3])
; 3
#Thumbnail is right -- your code will work just fine if you fix the placement of your parentheses (most importantly, you need to add a ( before (fn [t n] ... and a corresponding ) after s 0, in order to actually return the result of calling that function (the one that takes t and n as arguments) on the values s and 0. Otherwise, you are returning the function itself.), and change empty to empty?.
If you wanted to simplify things a bit, you might consider using a loop/recur structure instead, like this:
(fn [s]
(loop [t s, n 0]
(if (empty? t)
n
(recur (rest t) (+ n 1)))))
This is one of those "Is there a built-in/better/idiomatic/clever way to do this?" questions.
I want a function--call it fn-pow--that will apply a function f to the result of applying f to an argument, then apply it to the result of applying it to its result, etc., n times. For example,
(fn-pow inc 0 3)
would be equivalent to
(inc (inc (inc 0)))
It's easy to do this with iterate:
(defn fn-pow-0
[f x n]
(nth (iterate f x) n))
but that creates and throws away an unnecessary lazy sequence.
It's not hard to write the function from scratch. Here is one version:
(defn fn-pow-1
[f x n]
(if (> n 0)
(recur f (f x) (dec n))
x))
I found this to be almost twice as fast as fn-pow-0, using Criterium on (fn-pow inc 0 10000000).
I don't consider the definition of fn-pow-1 to be unidiomatic, but fn-pow seems like something that might be a standard built-in function, or there may be some simple way to define it with a couple of higher-order functions in a clever arrangement. I haven't succeeded in discovering either. Am I missing something?
The built-in you are looking for is probably dotimes. I'll tell you why in a round-about fashion.
Time
What you are testing in your benchmark is mainly the overhead of a level of indirection. That (nth (iterate ...) n) is only twice as slow as what compiles to a loop when the body is a very fast function is rather surprising/encouraging. If f is a more costly function, the importance of that overhead diminishes. (Of course if your f is low-level and fast, then you should use a low-level loop construct.)
Say your function takes ~ 1 ms instead
(defn my-inc [x] (Thread/sleep 1) (inc x))
Then both of these will take about 1 second -- the difference is around 2% rather than 100%.
(bench (fn-pow-0 my-inc 0 1000))
(bench (fn-pow-1 my-inc 0 1000))
Space
The other concern is that iterate is creating an unnecessary sequence. But, if you are not holding onto the head, just doing an nth, then you aren't really creating a sequence per se but sequentially creating, using, and discarding LazySeq objects. In other words, you are using a constant amount of space, though generating garbage in proportion to n. However, unless your f is primitive or mutating its argument, then it is already producing garbage in proportion to n in producing its own intermediate results.
Reducing Garbage
An interesting compromise between fn-pow-0 and fn-pow-1 would be
(defn fn-pow-2 [f x n] (reduce (fn [x _] (f x)) x (range n)))
Since range objects know how to intelligently reduce themselves, this does not create additional garbage in proportion to n. It boils down to a loop as well. This is the reduce method of range:
public Object reduce(IFn f, Object start) {
Object ret = f.invoke(start,n);
for(int x = n+1;x < end;x++)
ret = f.invoke(ret, x);
return ret;
}
This was actually the fastest of the three (before adding primitive type-hints on n in the recur version, that is) with the slowed down my-inc.
Mutation
If you are iterating a function potentially expensive in time or space, such as matrix operations, then you may very well be wanting to use (in a contained manner) an f that mutates its argument to eliminate the garbage overhead. Since mutation is a side effect, and you want that side effect n times, dotimes is the natural choice.
For the sake of example, I'll use an atom as a stand-in, but imagine bashing on a mutable matrix instead.
(def my-x (atom 0))
(defn my-inc! [x] (Thread/sleep 1) (swap! x inc))
(defn fn-pow-3! [f! x n] (dotimes [i n] (f! x)))
That sounds just like composing functions n times.
(defn fn-pow [f p t]
((apply comp (repeat t f)) p))
Hmmm. I note that Ankur's version is around 10x slower than your original - possibly not the intent, no matter how idiomatic? :-)
Type hinting fn-pow-1 simply for the counter yields substantially faster results for me - around 3x faster.
(defn fn-pow-3 [f x ^long n]
(if (> n 0)
(recur f (f x) (dec n))
x))
This is around twice as slow as a version which uses inc directly, losing the variability (not hinting x to keep to the spirit of the test)...
(defn inc-pow [x ^long n]
(if (> n 0)
(recur (inc x) (dec n))
x))
I think that for any nontrivial f that fn-pow-3 is probably the best solution.
I haven't found a particularly "idiomatic" way of doing this as it does not feel like common use case outside of micro benchmarks (although would love to be contradicted).
Would be intrigued to hear of a real world example, if you have one?
To us benighted imperative programmers, a more general pattern is known as a while statement. We can capture it in a macro:
(defmacro while [bv ; binding vector
tf ; test form
recf ; recur form
retf ; return form
]
`(loop ~bv (if ~tf (recur ~#recf) ~retf)))
... in your case
(while [x 0, n 3] (pos? n)
[(inc x) (dec n)]
x)
; 3
I was hoping to type-hint the n, but it's illegal. Maybe it's
inferred.
Forgive me (re)using while.
This isn't quite right: it doesn't allow for computation prior to the recur-form.
We can adapt the macro to do things prior to the recur:
(defmacro while [bv ; binding vector
tf ; test form
bodyf ; body form
retf ; return form
]
(let [bodyf (vec bodyf)
recf (peek bodyf)
bodyf (seq (conj (pop bodyf) (cons `recur recf)))]
`(loop ~bv (if ~tf ~bodyf ~retf))))
For example
(while [x 0, n 3] (pos? n)
(let [x- (inc x) n- (dec n)] [x- n-])
x)
; 3
I find this quite expressive. YMMV.