3

gurus

Here's a question for you: I am working on a clojure program that involves passing functions to functions.

I have something like:

(defn funct-op [args]
      ((first args) 
       (second args) 
       (last args)   )

(funct-op '(+ 2 2))

How can I coax funct-op into giving me 4 rather than the 2 I am currently getting? I may need to pass a function to a macro as my project progresses. Any tips on how to do that? Thanks for your help!

0

3 Answers 3

4

In order to turn the '+' into a function you can use resolve. This should work on core functions, but you may need ns-resolve for custom functions. You can then use apply to pass the rest of the arguments to that function.

(defn funct-add [args] (apply (resolve (first args)) (rest args)))

Not sure what your end goal really is but I think that is the answer you were looking for.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for your solution. A discussion of my end goals are better suited for another question(or does SO allow me to nest questions)?
4

What is funct-add really supposed to do? What if it was (funct-add '(- 2 2))?

Anyway, consider apply, even wrapped up:

(defn apply-wrapper [args]
   (apply (first args) (rest args)))

; note use of of the [...] form
(apply-wrapper [+ 2 2]) ; => 4
(apply-wrapper [- 2 2]) ; => 0

Comparing these forms may be enlightening:

(+ 1 2)   ; 3
'(+ 1 2)  ; (+ 1 2)
[+ 1 2]   ; [#<core$_PLUS_ clojure.core$_PLUS_@a8bf33> 1 2]

Note how the last one was evaluated; it is not just a "literal list" -- no symbol there anymore! :-)

Happy coding.

8 Comments

funct-add is supposed to take an unevaluated list of arguments, evaluate it and yield the result. So (funct-add '(- 2 2)) will yield 0. In general (funct-add '(binary-op operand1 operand2)), where binary-op can be +, -, or any operator that takes two arguments using prefix notation. Thanks.
@tscala I think the point is why is "add" in the name if it does more than add
Also remember that you don't have to quote a list just to keep from evaluating the entire form. If you'd like to evaluate the contents, but not the form as a function call, you can use list. (list + 1 2). Of course, it is by far better to just use a vector.
@AdrianMouat you do make a good point. I should edit the post to reflect the generality I'm aiming for. Thanks.
@Rayne if vector arg as in (funct-add [+ 2 2]), this is not the behavior I am looking for. Otherwise, an example? Thanks.
|
1

I'm not sure, these things?

(defn funct-op [f list]
  (apply f list))

(funct-op + '(1 2));=>3

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.