Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
2.1k views
in Technique[技术] by (71.8m points)

using clojure symbol function to make indirect function call

I'm expecting below that I should be able to call my function squared indirectly via the symbol function, but its not working. What am I doing wrong here:

user=> (defn squared [x] (* x x))
#'user/squared
user=> (squared 2)
4
user=> ((symbol "squared") 2)
nil
user=> ((symbol "user" "squared") 2)
nil
user=> 
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The symbol itself does not hold your function, the Var it names does.

This says "take the contents (@ = deref) of the Var (resolve) named by the symbol (symbol) whose name is "squared" and apply it (as a function) to the argument 2:

(@(resolve (symbol "squared")) 2)

This says "take the Var named by the symbol etc.":

((resolve (symbol "squared")) 2)

Both will work, since Vars, when asked to act as a function, defer to the functions stored in them. (If you try to use a Var as a function when it is not bound to a function, an error will result.)

This says "take the symbol named "squared" and apply it as a function to the argument 2" -- note that the symbol itself is used as the function:

((symbol "squared") 2)

Now symbols can be used as functions (they implement the clojure.lang.IFn interface), but the way they act when used in this way is that they look themselves up in their argument, i.e. treat their argument as a map and perform a lookup inside it:

('foo {'foo 2})
; is equivalent to
(get {'foo 2} 'foo)

If the argument passed to a symbol is not something it makes sense to do lookups in, nil is returned.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...