1

When we talk about a clojure (or other lisp) prog, what should we say when refer an object declared in it? For example:

(let [a ...

Of course, if a is a function, we say function a, but what should we say when it's not a function? Form? Data? Symbol? Literal?

Generally, we say those things in other prog language variables or objects.

象嘉道
  • 3,657
  • 5
  • 33
  • 49

3 Answers3

5

The let special form creates bindings between symbol(s) and a value.

The official documentation for let actually uses the vocabulary and wording that you are looking for and should use, specifically the Binding Forms section sheds more light to the subject:

The basic idea is that a binding-form can be a data structure literal containing symbols [or just a single symbol] that get bound to the respective parts of the init-expr.

juan.facorro
  • 9,791
  • 2
  • 33
  • 41
  • my question is not limited to `let` form. – 象嘉道 Jul 02 '15 at 15:48
  • @xando The answer is not limited to `let` forms, it generalizes to every special form and expression in Clojure that expects a binding form (i.e. `let`, `loop`, argument vector in `defn`, etc.). What other cases do you have in mind? `def` is somewhat different but the *binding* concept remains. – juan.facorro Jul 02 '15 at 17:52
2

a is always a symbol, independently of the value bound to it (whether it's a function or a number or anything else)

There's a previous answer on Clojure symbols that may clarify things a little bit more here: Symbols in Clojure

And remember symbols are not the same thing as vars

Community
  • 1
  • 1
guilespi
  • 4,672
  • 1
  • 15
  • 24
2

I think the question mixed up two things, or at least didn't make it clear that they're different.

As the other answers so far indicated, "a" is a symbol, which evaluates to something else. So when we talk about a, we could mean the symbol, or the something else. And we could even mean the var that is an intermediary between the symbols and the something else. (See the page linked by Guillermo Winkler for more on the var/symbol relationship, which I'll leave in the background.)

A symbol is never a function, but it can have a function as its value. When you call a function, you are just using its value in a special way. You can even set the values of built-in functions to other values:

(def + -)
WARNING: + already refers to: #'clojure.core/+ in namespace: user, being replaced by: #'user/+
#'user/+
user=> (+ 5 2)
3
user=> (def - "This used to be the minus function")
WARNING: - already refers to: #'clojure.core/- in namespace: user, being replaced by: #'user/-
#'user/-
user=> -
"This used to be the minus function"

I gave + the value of -, and then made -'s value a string. (Yes, there were warnings, but it worked.) The fact that functions are just values of symbols is a way in which Clojure differs from many other languages. (Scheme is similar. Common Lisp is similar, but in a more complicated way.)

So the symbol is just the symbol. And it usually has a value, which may be a function, or a number, or a string, or a keyword, or anything that can be a value in Clojure--vectors, lazy sequences, lists (which may be Clojure code), or even another symbol (even the same one: (def a 'a).) You could call some of these things data if that's useful in a particular context. It's sometimes reasonable to describe functions as data in Clojure.

(def add-fns [#(+ 1 %) #(+ 2 %) #(+ 3 %)]) ;=> #'user/add-fns

add-fns ;=> [#object[user$fn__1178 0x71784911 "user$fn__1178@71784911"] #object[user$fn__1180 0x45ed957d "user$fn__1180@45ed957d"] #object[user$fn__1182 0x7838c8c5 "user$fn__1182@7838c8c5"]]

add-fns is a vector of functions. What should we call the functions that are elements of the vector? Aren't they data in some sense, if we use them like data? We can map a function over them, or reorder them, for example:

(map #(% 10) add-fns) ;=> (11 12 13)

(map #(% 10) (reverse add-fns)) ;=> (13 12 11)

Each of those expressions takes each function in add-fns and calls it with 10 as its argument, returning the results in a sequence.

Exception: macros don't follow the same rules:

user=> and
CompilerException java.lang.RuntimeException: Can't take value of a macro: ...

Some of the Java interop tricks don't follow the same rules, either.

Mars
  • 8,689
  • 2
  • 42
  • 70
  • so, in general scenario, is it proper to say anything declared in a clojure prog as *symbol*? – 象嘉道 Jul 02 '15 at 15:50
  • 1
    Given what you probably mean, that's correct. Maybe it depends on what you mean by "anything declared ...". You probably don't mean only "Anything that appears in a [`declare`](https://clojuredocs.org/clojure.core/declare) statement", i.e. anything in an expression like `(declare ...)`, and I'm not sure that Clojure has any other meaning for "declare". The term "symbol" has a precise meaning in Clojure, [here](http://clojure.org/data_structures#Data%20Structures-Symbols) and [here](http://clojure.org/reader). – Mars Jul 03 '15 at 22:33
  • 1
    Also note that even if it's true that anything declared is a symbol, not all symbols are declared. If you just type `foo` at a repl prompt, it's a symbol, even though it hasn't been defined or declared or bound or anything. – Mars Jul 03 '15 at 22:33