Generating a symbol from a string and applying it as a function

。_饼干妹妹 提交于 2021-02-05 10:11:59

问题


I'm just learning clojure, and I'm hitting a wall.

I'm trying to read an arithmetic expression as an infix string and process it in Clojure.

e.g. "1 + 2" -> (+ 1 2)

I read in the "+" and turn it into a symbol like this:

(def plus (symbol "clojure.core" "+"))

Which appears to work properly, but when I call it, I don't get what I'm expecting:

user=> plus
+

user=> (plus 1 1)
1
user=> (plus 1 2)
2
user=> (plus 1 2 3)
ArityException Wrong number of args (3) passed to: Symbol  clojure.lang.AFn.throwArity (AFn.java:437)

What am I missing here?


回答1:


Symbols have a function attached to them by default. The function that is attached to them by default is look this key up in a map. That is why your plus behaves oddly. It is attempting to look up elements in a map.

(plus 1 1) This is really look the symbol + up in the map 1 and if not found return a default value of 1.

(plus 1 2) Same as above except default value is 2.

clojure docs for symbols




回答2:


What's your reason to write such code? If you want to have function called plus which gonna be + synonym just write (def plus +).

Clojure + is normal function. You can use it like (+ 1 2 3 4 5). There's no reason to turn it into symbol.

Clojure have no operators at all. Only functions and macros.

Still, if you insist on using symbol you need to eval it like so

(def plus (eval (symbol "clojure.core/+"))).

Have a look on class of (symbol "clojure.core/+") and + itself.

(class (symbol "clojure.core/+")) ;;clojure.lang.Symbol

(class +) ;;clojure.core$_PLUS_

Symbols themselves are not callable as functions which are "under this symbols". If you want to "turn symbol into callable function" you have to eval it.



来源:https://stackoverflow.com/questions/19795906/generating-a-symbol-from-a-string-and-applying-it-as-a-function

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!