I want to be able to do the following pseudocode:
Ideally, I would like the signature to look like:
(runner a b (+ a b))
but I'm not sure that I'm approaching this correctly... I've tried changing the function to
(runner 'a 'b (+ 'a 'b))
and this more complicated example:
(runner 'a 'b (+ (* 'a 'b) 'a))
but this does a + on 'a and 'b before stepping into runner.
Here's my first stab at some clojure:
(defn runner [a b c] (
(for [i (range 10)
j (range 10)] (println i j (c i j))
What concept of clojure am I missing?
Function arguments are always evaluated before the function is called. If you want to defer evaluation or represent some computation or code as an object, you have a few options:
eval
it.Using a function is what you want to do 99% of the time. 1% of the time, you'll want macros. You should never need eval
unless you're generating code at runtime or doing very screwy things.
user> (defn runner [f]
(doseq [a (range 3)
b (range 3)]
(println a b (f a b))))
#'user/runner
user> (runner (fn [x y] (+ x y)))
0 0 0
0 1 1
0 2 2
1 0 1
1 1 2
1 2 3
2 0 2
2 1 3
2 2 4
This could also be written as (runner #(+ %1 %2)
or even simply (runner +)
.
There is no need to pass "a
" and "b
" into the function as arguments. doseq
and for
introduce their own local, lexically scoped names for things. There's no reason they should use a
and b
; any name will do. It's the same for fn
. I used x
and y
here because it doesn't matter.
I could've used a
and b
in the fn
body as well, but they would have been a different a
and b
than the ones the doseq
sees. You may want to read up on scope if this doesn't make sense.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With