Reputation: 1725
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?
Upvotes: 6
Views: 333
Reputation: 72926
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.
Upvotes: 4
Reputation: 7825
It isn't clear enough to me what you're trying to achieve, but the following is an answer to what I guess is your question:
user=> (declare a b) #'user/b user=> (defn runner [] (+ a b)) #'user/runner user=> (binding [a 1 b 2] (runner)) 3 user=> (binding [a 2 b 3] (runner)) 5
Note that the above style is likely not what you ought to be doing. Ask a better question and we'll give you better answers.
Upvotes: 0
Reputation: 91534
I'm not really sure i'm answering the correct question. I'm thinking "if i pass a function a symbol instead of a value how can it use the value that symbol represents? is that close?
(def a 4)
(defn my-inc [x] (+ (eval x) 1))
user> (my-inc 'a)
5
I'm sure there is a more elegant way than using eval.
Upvotes: 0
Reputation: 82559
I would make its signature be something like
(runner alen blen op)
example:
(runner 10 10 +)
Upvotes: 0