recur should be called in the tail position and I assume that it effectively acts as non-recursive quasi-loop.
Is expr-1 or 2 regarded in the rightful tail position but none of expr-3 till 8 in the following mimic block structures? Otherwise, how to reason and identify it before resort to trail and error?
(defn foo [x]
(if cond-expr-1
(recur expr-1)
(recur expr-2)))
(defn bar [x]
(if cond-expr-2
(fn-1 (recur expr-3))
(fn-2 (recur expr-4))))
(defn baz [x]
(if cond-expr-3
(if cond-expr-4
(recur expr-5)
(recur expr-6))
(if cond-expr-5
(recur expr-7)
(recur expr-8))))
An expression is in tail position if there is nothing else to be evaluated in the current function following that expression. In your case, all the recur invocations in foo and baz are in tail position and thus both functions will compile fine.
In bar, however, neither of the recur invocations will be allowed because neither of expr-3 or expr-4 are in tail position. There are function calls which uses the result of each recur invocation as an argument - that is, the function call logically follows the recur invocation, and thus recur is not in tail position.
This is not to say that you can't write bar to make a recursive invocation of itself, but you have to code it explicitly, as in:
(defn bar [x]
(if cond-expr-2
(fn-1 (bar expr-3))
(fn-2 (bar expr-4))))
This is absolutely allowed, BUT these recursive invocations of bar will consume stack space which means that if the function calls itself recursively enough times you'll run out of stack space. recur (and tail recursion in general) is valuable because it doesn't involve making a function call in the traditional sense - instead, (speaking logically here) the function argument on the stack is replaced with the new argument and the code jumps back to the beginning of the function, so no stack space is used. Of course, this means that the original argument in the first call to the function is lost.
Other versions of Lisp do not use the recur keyword. When these versions of Lisp find that a function is calling itself recursively they make the same "tail position" determination which Clojure makes and if they find that the call is in tail position they perform the same "replace-the-argument-and-jump" logic Clojure does, while if they find that the call is not in tail position they emit code to perform a "real" recursive call, rather than failing the compilation. Clojure's advantage is that it makes it very obvious to the developer if a call will be compiled as a tail-recursive call (branch) or not.
In the case of expr-3 and expr-4, it is the argument of a function, and that is why it is not in tail position.
Calling recur is basically like a goto or return statement, both of which cannot be used inside a function argument list.
Since the if expression is not a function (it is a "special form"), there is no problem as with a function arg list.
Here is a comparison between loop/recur and a more imperative approach using while:
(ns tst.demo.core
(:use tupelo.core tupelo.test))
(defn fib-recur
[arg]
(assert (and (int? arg) (pos? arg)))
; initialize state vars
(loop [N arg
result 1]
(if (zero? N)
result
; compute next state vars
(let [N-next (dec N)
result-next (* result N)]
(recur N-next result-next))))) ; jump to top of loop with next state vars
(defn fib-while
[arg]
(assert (and (int? arg) (pos? arg)))
; initialize state vars
(let [state (atom {:N arg
:result 1})]
(while (pos? (:N #state)) ; must use newest state value for N in test
; compute next state vars
(let [N (:N #state)
result (:result #state)
state-next {:N (dec N)
:result (* result N)}]
(reset! state state-next))) ; save new state & jump to top of loop
(:result #state)))
(dotest
(is= 120 (fib-recur 5))
(is= 120 (fib-while 5)))
Related
I have a small function used for debugging:
(set! *warn-on-reflection* true)
(defn debug [x] (doto x (->> println :>)))
When I call my function in a loop, I get the following reflection warning:
(loop [i 5] (when (pos? i) (recur (debug (dec i)))))
form-init14269737395101875093.clj:1 recur arg for primitive local: i is not matching primitive, had: Object, needed: long
Auto-boxing loop arg: i
I want to solve the reflection warning. How can I make my function "inherit" the type information from the parameter without explicitly specifying it or replacing it with a macro?
Here is a way that works:
(loop [i (Integer. 5)]
(when (pos? i)
(recur (debug (dec i)))))
with a warning-free result:
lein test tst.demo.core
4
3
2
1
0
It looks like using just plain 5 causes the compiler to use a primitive, which can't be type hinted. Explicitly creating an Integer object sidesteps the problem. I also tried (int 5) which didn't work.
Is there a reason you want to turn on reflection warnings? I normally never use them, especially for debugging.
Update
Note that if you wrap the code in a function like so:
(defn stuff
[arg]
(loop [i arg]
(when (pos? i)
(recur (debug (dec i))))))
there is no problem calling (stuff 5) since function args must always be passed as objects (via autoboxing if necessary).
the problem is that the return type of debug can't be deduced.
this is usually solved with type hints
in your case the following should do the trick:
(defn debug ^long [x] (doto x (->> println :>)))
user> (loop [i 5] (when (pos? i) (recur (debug (dec i)))))
4
3
2
1
0
nil
If, for whatever the reason, you do not want to use a macro, you may want to have a look at definline which seems to preserve type information:
(definline debug2 [x] (doto x (->> println :>)))
The call below, for instance, does not result in a reflection warning:
(.add (debug2 (ArrayList.)) 5)
My initial thought would have been to use a Java class with overloaded methods to achieve something along these lines, of which one method would take a generic argument T and return a T. In addition to this generic method, you would have had to overload that method for the few primitive types because generics only work with boxed values AFAIK. You could then reuse the class below for your debugging purposes:
import clojure.lang.IFn;
public class PassThrough {
private IFn _fn;
public PassThrough(IFn fn) {
_fn = fn;
}
public <T> T invoke(T x) {
_fn.invoke(x);
return x;
}
public long invoke(long x) {
_fn.invoke(x);
return x;
}
public double invoke(double x) {
_fn.invoke(x);
return x;
}
}
This will not work for reference types, though, because of type erasure. So if I would do something like this, I would still get a warning:
(defn debug [x] (doto x (->> println :>)))
(def pt-debug (PassThrough. debug))
(.add (.invoke ^PassThrough pt-debug (ArrayList.)) 9) ;; <-- Reflection warning here when calling .add
I have read the following document and the example, but still doesn't get what it really means. I understand alts!!, but not alt!!.Anybody show an example easy to understand?
https://clojure.github.io/core.async/#clojure.core.async/alt!!
I have also ready the following link
In Clojure (core.async) what's the difference between alts and alt?
update: The example is in the doc is:
(alt!
[c t] ([val ch] (foo ch val))
x ([v] v)
[[out val]] :wrote
:default 42)
for the second line of
[c t] ([val ch] (foo ch val))
channel-op of [c t] means a channel c and an value t: put value t on channel c.
result-expr of ([val ch] (foo ch val)) means bidding [val ch] for the operation, but since it's a list, [val ch] should be evaluate as a function, and (foo ch val) will be as the parameter passed to function of [val ch]. but what does it mean for function of [val ch] with parameter of (foo ch val) ?
[c t] ([val ch] (foo ch val))
There are some cases where a list doesn't mean "evaluate as a function". For example:
(ns com.foo.bar
(:require …))
In the above code, there is no function called :require being called.
Another example of lists being used for something other than function application is letfn:
(letfn [(foo [x] (+ (bar 1) x))
(bar [x] (+ 2 x))]
(+ (foo 5) (bar 7)))
As you can see above, letfn has two lists, one starting with the symbol foo, and one starting with the symbol bar, and neither of these lists is a traditional function call. Instead, letfn is defining two new functions, one with the name foo, and the other with the name bar. The rest of the expression is treated as a "body" in which to use those functions.
but what does it mean for function of [val ch] with parameter of (foo ch val) ?
Similar to letfn, alt defines a value named val and a channel named ch, and then the rest of the expression ((foo ch val)) is treated as a "body" in which to use those two names.
Explanation of alt!/alt!!:
I find it easiest to think of alt! and alt!! as being somewhat like cond, except instead of testing conditions to choose a body to execute, it waits on channels to choose a body to execute. Each clause consists of two parts, just like cond – the first part (the "channel op") is used to specify a channel that alt! should wait on, and the second part (the "result expr") specifies what should happen if that channel delivers a value first.
Since you probably want to access the value delivered by the channel or the channel itself when this happens, the result expr gives you the opportunity to bind both the value and the channel to symbols, and a body of code to execute with those bindings. Thus, the following clause…
[c t]
([val ch]
(foo ch val))
…means:
One of the channel operations that this call to alt! should block on is an attempt to take from either of two channels, c or t. If either of those send a value before any other channel op in this call to alt!, then execute (foo ch val) with val bound to the value taken from the channel that first delivered a value, and with ch bound to the channel that delivered val (which will be either c or t).
and the following clause…
[[out input-val]]
([val ch]
(bar ch val))
…means:
One of the channel operations that this call to alt! should block on is an attempt to put input-val onto a channel called out. If that succeeds before any other channel op in this call to alt!, then execute (bar ch val) with val bound to input-val and ch bound to out (the channel that successfully received the value).
Altogether, these two clauses would be written as:
(alt!
[c t] ; "Takes" can be a single channel instead of vectors.
([val ch]
(foo ch val))
[[out input-val]] ; "Puts" must be nested vectors.
([val ch]
(bar ch val)))
If I do this:
(eval (let [f (fn [& _] 10)]
`(~f nil)))
It returns 10 as expected.
Although if I do this:
(eval (let [f (constantly 10)]
`(~f nil)))
It throws an exception:
IllegalArgumentException No matching ctor found for
class clojure.core$constantly$fn__... clojure.lang.Reflector.invokeConstructor
Since both are equivalent why is the code with constantly not working?
This question has two answers, to really get it.
First, to clarify why your eval form is not giving you the expected result in the second case, note that f has been assigned to be equal to the function (fn [& _] 10). This means when that form is evaluated, the function object is again evaluated--probably not what you had in mind.
tl;dr: f is evaluted when it is bound, and again (with ill-defined results) when the form you create is eval'd.
The reason why one (the anonymous function) works, while the other fails means we have to look at some of the internals of the evaluation process.
When Clojure evaluates an object expression (like the expression formed by a function object), it uses the following method, in clojure.lang.Compiler$ObjExpr
public Object eval() {
if(isDeftype())
return null;
try
{
return getCompiledClass().newInstance();
}
catch(Exception e)
{
throw Util.sneakyThrow(e);
}
}
Try this at the REPL:
Start with an anonymous function:
user=> (fn [& _] 10)
#<user$eval141$fn__142 user$eval141$fn__142#2b2a5dd1>
user=> (.getClass *1)
user$eval141$fn__142
user=> (.newInstance *1)
#<user$eval141$fn__142 user$eval141$fn__142#ee7a10e> ; different instance
user=> (*1)
10
Note that newInstance on Class calls that class' nullary constructor -- one that takes no arguments.
Now try a function that closes over some values
user=> (let [x 10] #(+ x 1))
#<user$eval151$fn__152 user$eval151$fn__152#3a565388>
user=> (.getClass *1)
user$eval151$fn__152
user=> (.newInstance *1)
InstantiationException user$eval151$fn__152 [...]
Since the upvalues of a closure are set at construction, this kind of function class has no nullary constructor, and making a new one with no context fails.
Finally, look at the source of constantly
user=> (source constantly)
(defn constantly
"Returns a function that takes any number of arguments and returns x."
{:added "1.0"
:static true}
[x] (fn [& args] x))
The function returned by constantly closes over x so the compiler won't be able to eval this kind of function.
tl;dr (again): Functions with no upvalues can be evaluated in this way and produce a new instance of the same function. Functions with upvalues can't be evaluated like this.
I am doing the closure tutorial at http://clojurescriptkoans.com and I am stuck here: http://clojurescriptkoans.com/#functions/9
It looks like this
Higher-order functions take function arguments
(= 25 ( _ (fn [n] (* n n))))
I am supposed to fill in something at the underscore to make the expression true. I have no clue what to do.
The syntax simply consists of binding the function, and then calling it.
Since this is an exercise, I will show a similar situation rather than showing the exercise's solution:
user> ((fn [f] (f "abc")) (fn [s] (str s s s)))
"abcabcabc"
here I bind the argument of the first function to f, and call f with the argument "abc".
or you can use the short-hand notation:
#(%1 5)
Higher order functions takes functions as arguments.
Defining two functions
user=> (defn multiply [n] (* n n))
#'user/multiply
user=> (defn add [n] (+ n n))
#'user/add
Defining higher order function
user=> (defn highorderfn [fn number] (fn number))
#'user/highorderfn
Calling the higher order function
user=> (highorderfn multiply 5)
25
user=> (highorderfn add 5)
10
I want to repeatedly apply some function to some state until a condition holds true.
Function f takes a state, modifies it and returns it. Apply f again to the returned state and so on.
I think this would work.
(first (filter pred (iterate f x)))
But it's a bit ugly. Plus memory consumption is not ideal since iterator would be forced to evaluate and keep intermediate states until the state on which pred holds true is returned, at which point intermediate states should be garbage collected.
I know you can write a simple recursive function:
(loop [f x p] (if (p x) x (recur f (f x) p))
But I'm looking for a core library function (or some combination of functions) that does the same thing with the same memory efficiency.
What you really want is take-while:
take-while
function
Usage: (take-while pred coll)
Returns a lazy sequence of successive items from coll while
(pred item) returns true. pred must be free of side-effects.
EDIT
A way to use higher order functions to achieve the result you want might be to wrap your function into something to be consumed by trampoline, namely a function that will either return the final result or another function which will execute the next step. Here's the code:
(defn iterable [f] ; wraps your function
(fn step [pred x] ; returns a new function which will accept the predicate
(let [y (f x)] ; calculate the current step result
(if (pred y) ; recursion stop condition
(fn [] (step pred y)) ; then: return a new fn for trampoline, operates on y
y)))) ; else: return a value to exit the trampoline
The iterative execution would go as follows:
(trampoline (iterable dec) pos? 10)
Not sure what you mean by iterator - you're using it as if it were iterate, and I just want to be sure that's what you mean. At any rate, your solution looks fine to me and not at all ugly. And memory is not an issue either: iterate is free to throw away intermediate results whenever it's convenient because you aren't keeping any references to them, just calling filter on it in a "streaming" way.
I think you should just make your loop a simple recursive function:
(defn do-until [f x p]
(if (p x) x (recur f (f x) p)))
(do-until inc 0 #(> % 10)) ; => 11
How about drop-while
(first (drop-while (comp not pred) (iterate f x))
I don't think there is a core function that does this exactly and efficiently. Hence I would do this with loop/recur as follows:
(loop [x initial-value]
(if (pred x) x (recur (f x))))
Loop/recur is very efficient since it requires no additional storage and is implemented as a simple loop in the JVM.
If you're going to do this a lot, then you can always encapsulate the pattern in a macro.
Sounds like you want the while macro.
http://richhickey.github.com/clojure/clojure.core-api.html#clojure.core/while
Usage: (while test & body)
Repeatedly executes body while test expression is true. Presumes
some side-effect will cause test to become false/nil. Returns nil
In a slightly different use case the for macro supports :when and :while options too.
http://richhickey.github.com/clojure/clojure.core-api.html#clojure.core/for
Usage: (for seq-exprs body-expr)
List comprehension. Takes a vector of one or more
binding-form/collection-expr pairs, each followed by zero or more
modifiers, and yields a lazy sequence of evaluations of expr.
Collections are iterated in a nested fashion, rightmost fastest,
and nested coll-exprs can refer to bindings created in prior
binding-forms. Supported modifiers are: :let [binding-form expr ...],
:while test, :when test.
(take 100 (for [x (range 100000000) y (range 1000000) :while (< y x)] [x y]))