I've a clojure program in which two function recursively call each other:
(defn f1
...
(f2 ...)
)
(defn f2
...
(f1 ...)
)
The compiler is giving an error in f1. It's saying that f2 isn't defined. Is there a way to declare a function in clojure. I can verify that the recursion actually terminates.
Literally declare:
(declare f2)
(defn f1 []
(f2))
(defn f2 []
(f1))
there is also a letfn form for (possibly) mutually recursive functions:
user=> (letfn [(f1 [x] (if (< x 10) (f2 x) x))
(f2 [x] (f1 (inc x)))]
(f2 0))
;;=> 10
update
if you then need these functions globally, you can always use def inside letfn. As for me i find this approach to be a bit cleaner, than declare (especially for mutually recursive ones):
user> (letfn [(f1 [x] (if (< x 10) (f2 x) x))
(f2 [x] (f1 (inc x)))]
(def f1 f1)
(def f2 f2))
#'user/f2
user> (f2 0)
;;=> 10
Related
Suppose I want to apply the parameter p1 and p2 to a list of function calls:
(defn some-func []
(let [p1 a p2 b]
(f1 p1 p2)
(f2 p1 p2)
(f3 p1 p2)
...
))
What's a good and concise way of doing this?
Assuming you want just side-effects, I'd use doseq to force the calls;
iterate the functions you want to call. e.g.
user=> (doseq [f [println println println]] (f 1))
1
1
1
nil
You may want to review the Clojure CheatSheet. The function juxt can do what you want.
Beware, though, juxt is somewhat obscure and can make it hard to read your code.
You can use for or map, both of which return a clojure.lang.LazySeq. Small working example:
(defn f1 [x y] (+ x y))
(defn f2 [x y] (- x y))
(defn f3 [x y] (* x 1))
;; Method 1 - for
(for [f [f1 f2 f3]]
(f 10 5))
;; => (15 5 50)
;; Method 2 - map
(map #(% 10 5) [f1 f2 f3])
;; => (15 5 50)
One of my favorite ways to test the power of a language I'm learning is to try and implement various fixed-point combinators. Since I'm learning Clojure (though I'm not new to lisps), I did the same for it.
First, a little "testable" code, factorial:
(def !'
"un-fixed factorial function"
(fn [f]
(fn [n]
(if (zero? n)
1
(* n (f (dec n)))))))
(defn !
"factorial"
[n]
(if (zero? n)
1
(apply * (map inc (range n)))))
For any combinator c I implement, I want to verify that ((c !') n) is equal to (! n).
We start with the traditional Y:
(defn Y
"pure lazy Y combinator => stack overflow"
[f]
(let [A (fn [x] (f (x x)))]
(A A)))
But of course Clojure is not nearly so lazy as that, so we pivot to Z:
(defn Z
"strict fixed-point combinator"
[f]
(let [A (fn [x] (f (fn [v] ((x x) v))))]
(A A)))
And indeed, it holds that (= ((Z !') n) (! n)).
Now comes my issue: I cannot get either of U or the Turing combinator (theta-v) to work correctly. I suspect with U it's a language limit, while with theta-v I'm more inclined to believe it's a misread of Wikipedia's notation:
(defn U
"the U combinator => broken???"
[f]
(f f))
(defn theta-v
"Turing fixed-point combinator by-value"
[f]
(let [A (fn [x] (fn [y] (y (fn [z] ((x x) y) z))))]
(A A)))
A sample REPL experience:
((U !') 5)
;=> Execution error (ClassCastException) at fix/!'$fn (fix.clj:55).
;=> fix$_BANG__SINGLEQUOTE_$fn__180 cannot be cast to java.lang.Number
((theta-v !') 5)
;=> Execution error (ClassCastException) at fix/theta-v$A$fn (fix.clj:36).
;=> java.lang.Long cannot be cast to clojure.lang.IFn
Can anyone explain
Why these implementations of U and theta-v are not working; and
How to fix them?
Your definition of theta-v is wrong for two reasons. The first is pretty obvious: you accept f as a parameter and then ignore it. A more faithful translation would be to use def style, as you have for your other functions:
(def theta-v
"Turing fixed-point combinator by-value"
(let [A (fn [x] (fn [y] (y (fn [z] ((x x) y) z))))]
(A A)))
The second reason is a bit sneakier: you translated λz.xxyz to (fn [z] ((x x) y) z), remembering that lisps need more parentheses to denote function calls that are implicit in lambda-calculus notation. However, you missed one set: just as x x y z would have meant "evaluate x twice, then y once, then finally return z", what you wrote means "evaluate ((x x) y), then throw away that result and return z". Adding the extra set of parentheses yields a working theta-v:
(def theta-v
"Turing fixed-point combinator by-value"
(let [A (fn [x] (fn [y] (y (fn [z] (((x x) y) z)))))]
(A A)))
and we can demonstrate that it works by calculating some factorials:
user> (map (theta-v !') (range 10))
(1 1 2 6 24 120 720 5040 40320 362880)
As for U: to use the U combinator, functions being combined must change how they self-call, meaning you would need to rewrite !' as well:
(def U [f] (f f))
(def ! (U (fn [f]
(fn [n]
(if (zero? n)
1
(* n ((f f) (dec n))))))))
Note that I have changed (f (dec n)) to ((f f) (dec n)).
I like my code to have a "top-down" structure, and that means I want to do exactly the opposite from what is natural in Clojure: functions being defined before they are used. This shouldn't be a problem, though, because I could theoretically declare all my functions first, and just go on and enjoy life. But it seems in practice declare cannot solve every single problem, and I would like to understand what is exactly the reason the following code does not work.
I have two functions, and I want to define a third by composing the two. The following three pieces of code accomplish this:
1
(defn f [x] (* x 3))
(defn g [x] (+ x 5))
(defn mycomp [x] (f (g x)))
(println (mycomp 10))
2
(defn f [x] (* x 3))
(defn g [x] (+ x 5))
(def mycomp (comp f g))
3
(declare f g)
(defn mycomp [x] (f (g x)))
(defn f [x] (* x 3))
(defn g [x] (+ x 5))
But what I would really like to write is
(declare f g)
(def mycomp (comp f g))
(defn f [x] (* x 3))
(defn g [x] (+ x 5))
And that gives me
Exception in thread "main" java.lang.IllegalStateException: Attempting to call unbound fn: #'user/g,
That would mean forward declaring works for many situations, but there are still some cases I can't just declare all my functions and write the code in any way and in whatever order I like. What is the reason for this error? What does forward declaring really allows me to do, and what are the situations I must have the function already defined, such as for using comp in this case? How can I tell when the definition is strictly necessary?
You can accomplish your goal if you take advantage of Clojure's (poorly documented) var behavior:
(declare f g)
(def mycomp (comp #'f #'g))
(defn f [x] (* x 3))
(defn g [x] (+ x 5))
(mycomp 10) => 45
Note that the syntax #'f is just shorthand (technically a "reader macro") that translates into (var f). So you could write this directly:
(def mycomp (comp (var f) (var g)))
and get the same result.
Please see this answer for a more detailed answer on the (mostly hidden) interaction between a Clojure symbol, such as f, and the (anonymous) Clojure var that the symbol points to, namely either #'f or (var f). The var, in turn, then points to a value (such as your function (fn [x] (* x 3)).
When you write an expression like (f 10), there is a 2-step indirection at work. First, the symbol f is "evaluated" to find the associated var, then the var is "evaluated" to find the associated function. Most Clojure users are not really aware that this 2-step process exists, and nearly all of the time we can pretend that there is a direct connection between the symbol f and the function value (fn [x] (* x 3)).
The specific reason your original code doesn't work is that
(declare f g)
creates 2 "empty" vars. Just as (def x) creates an association between the symbol x and an empty var, that is what your declare does. Thus, when the comp function tries to extract the values from f and g, there is nothing present: the vars exist but they are empty.
P.S.
There is an exception to the above. If you have a let form or similar, there is no var involved:
(let [x 5
y (* 2 x) ]
y)
;=> 10
In the let form, there is no var present. Instead, the compiler makes a direct connection between a symbol and its associated value; i.e. x => 5 and y => 10.
I think Alan's answer addresses your questions very well. Your third example works because you aren't passing the functions as arguments to mycomp. I'd reconsider trying to define things in "reverse" order because it works against the basic language design, requires more code, and might be harder for others to understand.
But... just for laughs and to demonstrate what's possible with Clojure macros, here's an alternative (worse) implementation of comp that works for your preferred syntax, without dealing directly in vars:
(defn- comp-fn-arity [variadic? args f & fs] ;; emits a ([x] (f (g x)) like form
(let [args-vec (if variadic?
(into (vec (butlast args)) ['& (last args)])
(apply vector args))
body (reduce #(list %2 %1)
(if variadic?
(apply list 'apply (last fs) args)
(apply list (last fs) args))
(reverse (cons f (butlast fs))))]
`(~args-vec ~body)))
(defmacro momp
([] identity)
([f] f)
([f & fs]
(let [num-arities 5
args-syms (repeatedly num-arities gensym)]
`(fn ~#(map #(apply comp-fn-arity (= % (dec num-arities)) (take % args-syms) f fs)
(range num-arities))))))
This will emit something kinda like comp's implementation:
(macroexpand '(momp f g))
=>
(fn*
([] (f (g)))
([G__1713] (f (g G__1713)))
([G__1713 G__1714] (f (g G__1713 G__1714)))
([G__1713 G__1714 G__1715] (f (g G__1713 G__1714 G__1715)))
([G__1713 G__1714 G__1715 & G__1716] (f (apply g G__1713 G__1714 G__1715 G__1716))))
This works because your (unbound) functions aren't being passed as values to another function; during compilation the macro expands "in place" as if you'd written the composing function by hand, as in your third example.
(declare f g)
(def mycomp (momp f g))
(defn f [x] (* x 3))
(defn g [x] (+ x 5))
(mycomp 10) ;; => 45
(apply (momp vec reverse list) (range 10)) ;; => [9 8 7 6 5 4 3 2 1 0]
This won't work in some other cases, e.g. ((momp - dec) 1) fails because dec gets inlined and doesn't have a 0-arg arity to match the macro's 0-arg arity. Again, this is just for the sake of example and I wouldn't recommend it.
I would like to compose functions of the following type:
; input is a value x and the return value is a vector.
(defn f [x] [x *whatever*])
In order to compose such functions I use such a monad:
(require '[clojure.algo.monads :as m])
(m/defmonad example-m
[m-result (fn [v] v)
m-bind (fn [[v k] f]
(f v) )])
Using the following 2 example functions,
(defn f1 [s] [(inc s) :f1])
(defn f2 [s] [(* 2 s) :f2])
evaluating the monad returns the correct value:
(m/domonad example-m [x1 [4 1]
x2 (f1 x1)
x3 (f2 x2)
] x3) ; => [10 :f2]
However, I am interested to evaluate the following expression:
(m/domonad example-m [x1 [4 1]
x2 (f1 x1)
x3 (f2 x2)
] [x1 x2 x3]) ; => [4 5 10]
I was expecting [[4 1] [5 :f1] [10 :f2]]
Can I use the monad to solve this problem or do I need to fallback to a macro?
EDIT:
I have analyzed the source of the problem in a bit more detail. The monad library expands the code above into:
(m-bind [4 1]
(fn [x1]
(m-bind (f1 x1)
(fn [x2]
(m-bind (f2 x2)
(fn [x3]
(m-result [x1 x2 x3])))))))
This shows that the variables x1, x2, x3 cannot be monadic values but must be the 'real' values. Hence the behavior.
A quick modification of m-bind
(defn m-bind [[v k ] f]
[(f v) k])
yields [[[[4 5 10] :f2] :f1] 1]. I guess the solution is in the m-result function which has to unwrap this nested structure.
You seem to be looking for something like the Writer monad, where the intermediate functions return a "primary" value and possibly some additional log information. A Clojure implementation of result and bind for this monad might look something like this (not using any of the monad tools, just writing it ourselves with functions):
(letfn [(m-result [v]
[v []])
(m-bind [[v logs] f]
(let [[v' logs'] (f v)]
[v' (into logs logs')]))
(tell [log]
(fn [x]
[x [[x log]]]))
(f1 [s]
(m-bind (m-result (inc s))
(tell :f1)))
(f2 [s]
(m-bind (m-result (* 2 s))
(tell :f2)))]
(m-bind (m-result 4)
(fn step [x1]
(m-bind (f1 x1) f2))))
Here result, bind, and tell are generic definitions useful for any application of this writer; f1 and f2 are as defined in your question but changed a bit to make them fit the revised monad; and the body of the letfn (starting with m-bind) is the desugared form of your original m-do expression.
The idea is to make a monadic value be a pair, containing (a) the value being worked on, and (b) a list of intermediate states, along with labels for each state, like :f1. bind's job is to call f on just the (a) part of that pair, and concatenate the list of "logged" states. Then in your do-expr, you start with (result 4) so that you have a proper monadic value, and then bind a number of monadic functions to it. And indeed what gets returned from this whole thing is [10 [[5 :f1] [10 :f2]]]: "the final value was 10, and here are all the intermediate values along with their labels, in case you wanted those too".
My syntax for this looks somewhat primitive, for two reasons: (1) I wanted to remind you that this is all just working with functions, and if you're writing your own monad you should understand them well enough to do it without using a monad library (although you'll want to use the library in practice); and (2) because now it's a pasteable, runnable snippet with no other dependencies. If you want to shoehorn all this into the contrib.monads framework, you'll probably find a definition of tell that's more suitable in that context than mine is, such that it's suitable for use as a monadic value instead of as a binding function.
Edit: Note that it looks kinda gross that I had to modify f1 and f2 to make them participate in our writer monad, but you could define a general lift-writer function that wraps an existing function, and then wrap your "dumb" functions in that, like so:
(defn lift-writer [f]
(fn [s]
(let [[ret label] (f s)]
(m-bind (m-result ret) (tell label)))))
(def f1* (lift-writer f1 :f1))
(def f2* (lift-writer f2 :f2))
and then use those lifted versions instead in the m-do.
I know that the -> form can be used to pass the results of one function result to another:
(f1 (f2 (f3 x)))
(-> x f3 f2 f1) ; equivalent to the line above
(taken from the excellent Clojure tutorial at ociweb)
However this form requires that you know the functions you want to use at design time. I'd like to do the same thing, but at run time with a list of arbitrary functions.
I've written this looping function that does it, but I have a feeling there's a better way:
(defn pipe [initialData, functions]
(loop [
frontFunc (first functions)
restFuncs (rest functions)
data initialData ]
(if frontFunc
(recur (first restFuncs) (rest restFuncs) (frontFunc data) )
data )
) )
What's the best way to go about this?
I must admit I'm really new to clojure and I might be missing the point here completely, but can't this just be done using comp and apply?
user> (defn fn1 [x] (+ 2 x))
user> (defn fn2 [x] (/ x 3))
user> (defn fn3 [x] (* 1.2 x))
user> (defn pipe [initial-data my-functions] ((apply comp my-functions) initial-data))
user> (pipe 2 [fn1 fn2 fn3])
2.8
You can do this with a plain old reduce:
(defn pipe [x fs] (reduce (fn [acc f] (f acc)) x fs))
That can be shortened to:
(defn pipe [x fs] (reduce #(%2 %1) x fs))
Used like this:
user> (pipe [1 2 3] [#(conj % 77) rest reverse (partial map inc) vec])
[78 4 3]
If functions is a sequence of functions, you can reduce it using comp to get a composed function. At a REPL:
user> (def functions (list #(* % 5) #(+ % 1) #(/ % 3)))
#'user/my-list
user> ((reduce comp functions) 9)
20
apply also works in this case because comp takes a variable number of arguments:
user> (def functions (list #(* % 5) #(+ % 1) #(/ % 3)))
#'user/my-list
user> ((apply comp functions) 9)
20