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)))
Related
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)))
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.
Say I want to make a Clojure macro that does the following:
If x is a list calling the function "bar"
return :foobar
else
return x as a string
However, bar is not defined; rather, it is only used internally in the macro, like so:
(foo (bar))
:foobar
(foo 1)
"1"
One could do something like this:
(defmacro foo [x]
(if (and (coll? x) (= (first x) 'bar))
:foobar
(str x)))
This works great for the (bar) case, as well as for literals. However, symbols do not work as intended, giving the symbol name instead of its associated value:
user=> (def y 2)
#'user/y
user=> (foo y)
"y"
One could call the eval function on x before passing it to str, but this causes problem when using the function in let:
user=> (let [a 3 b (foo a)] b)
java.lang.UnsupportedOperationException: Can't eval locals (NO_SOURCE_FILE:89)
Presumably, the problem has to do with symbol resolution, so maybe we try to work something out with syntax-quote:
(defmacro foo [x]
`(if (and (coll? '~x) (= (first '~x) '~'bar))
:foobar
(str ~x)))
Now, the problem is with (foo (bar)), as this expands the else clause to (clojure.core/str (bar)), which throws an exception, as bar is not defined. I then tried doing some shenanigans with eval:
(defmacro foo [x]
`(if (and (coll? '~x) (= (first '~x) '~'bar))
:foobar
(eval '(str ~x))))
But this doesn't work with let bindings again:
user=> (let [a 1 b (foo a)] b)
java.lang.Exception: Unable to resolve symbol: a in this context (NO_SOURCE_FILE:153)
So I'm really at a loss here. It seems as though fixing one problem breaks another. Is there a better, simpler way of making this macro such that it works in the following cases:
In let bindings
With (bar)
With symbols
P.S. If anybody is curious as to why I want to do this, I'm working on a DSL for Yahoo's YQL service and I want to be able to do things like (select (table :t) ...), but I need to be able to pass in symbols, as well as literals.
I believe this should work.
(defmacro foo [x]
(if (and (coll? x) (= (first x) 'bar))
:foobar
`(str ~x)))
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]))
Clojure is awesome, we all know this, but that's not the point. I'm wondering what the idiomatic way of creating and managing higher-order functions in a Haskell-like way is. In Clojure I can do the following:
(defn sum [a b] (+ a b))
But (sum 1) doesn't return a function: it causes an error. Of course, you can do something like this:
(defn sum
([a] (partial + a))
([a b] (+ a b)))
In this case:
user=> (sum 1)
#<core$partial$fn__3678 clojure.core$partial$fn__3678#1acaf0ed>
user=> ((sum 1) 2)
3
But it doesn't seem like the right way to proceed. Any ideas?
I'm not talking about implementing the sum function, I'm talking at a higher level of abstraction. Are there any idiomatic patterns to follow? Some macro? Is the best way defining a macro or are there alternative solutions?
Someone has already implememented this on the Clojure group. You can specify how many args a function has, and it will curry itself for you until it gets that many.
The reason this doesn't happen by default in Clojure is that we prefer variadic functions to auto-curried functions, I suppose.
I've played a bit with the functions suggested by amalloy. I don't like the explicit specification of the number of argument to curry on. So I've created my custom macro. This is the old way to specific an high order function:
(defn-decorated old-sum
[(curry* 3)]
[a b c]
(+ a b c))
This is my new macro:
(defmacro defn-ho
[fn-name & defn-stuff]
(let [number-of-args (count (first defn-stuff))]
`(defn-decorated ~fn-name [(curry* ~number-of-args)] ~#defn-stuff)))
And this is the new implicit way:
(defn-ho new-sum [a b c] (+ a b c))
As you can see there is no trace of (curry) and other stuff, just define your currified function as before.
Guys, what do you think? Ideas? Suggestions?
Bye!
Alfedo
Edit: I've modified the macro according the amalloy issue about docstring. This is the updated version:
(defmacro defhigh
"Like the original defn-decorated, but the number of argument to curry on
is implicit."
[fn-name & defn-stuff]
(let [[fst snd] (take 2 defn-stuff)
num-of-args (if (string? fst) (count snd) (count fst))]
`(defn-decorated ~fn-name [(curry* ~num-of-args)] ~#defn-stuff)))
I don't like the if statement inside the second binding. Any ideas about making it more succint?
This will allow you to do what you want:
(defn curry
([f len] (curry f len []))
([f len applied]
(fn [& more]
(let [args (concat applied (if (= 0 (count more)) [nil] more))]
(if (< (count args) len)
(curry f len args)
(apply f args))))))
Here's how to use it:
(def add (curry + 2)) ; read: curry plus to 2 positions
((add 10) 1) ; => 11
The conditional with the [nil] is meant to ensure that every application ensures some forward progress to the curried state. There's a long explanation behind it but I have found it useful. If you don't like this bit, you could set args as:
[args (concat applied more)]
Unlike JavaScript we have no way of knowing the arity of the passed function and so you must specify the length you expect. This makes a lot of sense in Clojure[Script] where a function may have multiple arities.