Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What do Clojure symbols do when used as functions?

Tags:

clojure

While trying to solve the 4Clojure problem "Universal Computation Engine" involving reimplementing evaluation, I accidentally ended up calling something like this:

(apply '/ '(16 8))

rather than the intended:

(apply / '(16 8))

This had the confusing side effect of returning 8, which made me think I had messed up my maths.

I later realised my error after some debugging—I was failing to evaluate the / symbol before attempting to call it—and so realised that clojure.lang.Symbol must implement clojure.lang.IFn. But what does that implementation do? All I can get it to do is return nil with one argument, or the second argument if given.

like image 592
Asherah Avatar asked Sep 05 '12 12:09

Asherah


People also ask

What are symbols in Clojure?

There may be some confusion here from the different usages of the term "symbol" in Common Lisp and in Clojure. In Common Lisp, a "symbol" is a location in memory, a place where data can be stored. The "value" of a symbol is the data stored at that location in memory. In Clojure, a "symbol" is just a name.

What is FN in Clojure?

Most Clojure code consists primarily of pure functions (no side effects), so invoking with the same inputs yields the same output. defn defines a named function: ;; name params body ;; ----- ------ ------------------- (defn greet [name] (str "Hello, " name) )

What are forms in Clojure?

Binding Forms (Destructuring) The simplest binding-form in Clojure is a symbol. However, Clojure also supports abstract structural binding called destructuring in let binding lists, fn parameter lists, and by extension any macro that expands into a let or fn .


1 Answers

Symbols look themselves up in a map, much as keywords do. See Symbol's implementation:

…
122 public Object invoke(Object obj) {
123         return RT.get(obj, this);
124 }
125
126 public Object invoke(Object obj, Object notFound) {
127         return RT.get(obj, this, notFound);
128 }
…

(RT is clojure.lang.RT, which does just about everything. "RunTime"?)

In the example given, the lookup is failing (because 16 is not a map), and therefore the notFound value (8) is being returned.

like image 75
Asherah Avatar answered Oct 24 '22 14:10

Asherah