Difference between Symbols and Vars in Clojure

前端 未结 3 483
野的像风
野的像风 2020-11-30 22:37

I\'m always a bit confused about Symbols and Vars in Clojure. For example, is it safe to say that + is a symbol which is used to denote a var, and this var points to a value

3条回答
  •  时光说笑
    2020-11-30 23:17

    This answer is not very different from the other ones, it just doesn't assume you originally wish to learn several new functions and concepts just to understand what's going on:

    1. + is a symbol sitting in clojure.core which is by default accessible to your code.
    2. When used in your code without any very advanced intents such as quoting it or finding out its class ― clojure will seek the Var which it points to.
    3. If this Var is a function, when + is used in head position of a list, clojure will try to call that function (NullPointerException if this Var happened not to point at a function). If supplied as an argument to another function, that function may do the same to call it. That's how function calling works.

    further comments to round up:

    Most or all languages use symbol tables. Being a somewhat dynamic language, Clojure uses this extra layer of indirection (Symbol → Var → function, rather than only Symbol → function) so that dynamically rewriting which function is tied to which symbol ― is more feasible and elegant, and this is sometimes a source of curiosity for beginners.

    As other answers have somewhat overly emphasized, you may otherwise perform fancy stuff like quote it ('+) to avoid its evaluation, or even inspect it with class and/or resolve as if you are interested in verifying what it is (class), or which namespace it sits in (resolve). You can also poke at the var it points at via var or #'. You'll typically do those fancy things if you are writing macros or if you're very experimentally inclined, especially when working in the repl; depending on which style you write your macros, you might actually quote quite a lot in them.

    and a fancy illustration for the extra-exploratory person:

    Being a somewhat flexible language, clojure exposes api for taking the Symbol → Var → function walk on your own. You'd not typically ever do that for just using a function, because obviously that would be boring and redundant, but it can be used here to illustrate the process:

    (deref (resolve '+))
    

    Namely, the symbol is first resolved to its Var, then the thing that the Var points to, is arrived at. This just illustrates the 2-step process for arriving at a function (Symbol → Var → function), which happens behind the scenes. I hope you've avoided reading this extra part.


    TL;DR

    the answer to the original question is simply: Yes.

提交回复
热议问题