Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>REPL = read eval print loop. Step through the read-eval process.</p> <p>READ: Clojure sees the string <code>"(`a)"</code>, parses it and ends up with a data structure. At read time, reader macros are expanded and not much else happens. In this case, the reader expands the backquote and ends up with this:</p> <pre><code>user&gt; (read-string "(`a)") ((quote user/a)) </code></pre> <p>EVAL: Clojure tries to evaluate this object. Evaluation rules vary depending on what kind of object you're looking at. </p> <ul> <li>Some objects evaluate as themselves (numbers, strings, keywords etc.).</li> <li>A Symbol is evaluated by resolving it in some namespace to obtain some value (usually).</li> <li>A List is evaluated by macro-expanding the list until there are no macros left, then recursively evaluating the first item in the list to obtain some <strong>resulting value</strong>, then using the <strong>value</strong> of the first item in the list to decide what to do. If the first value is a special form, special stuff happens. Otherwise the first value is treated as a function and called with the values of the rest of the list (obtained by recursively evaluating all of the list's items) as parameters.</li> <li>etc.</li> </ul> <p>Refer to <code>clojure.lang.Compiler/analyzeSeq</code> in the Clojure source to see the evaluation rules for lists, or <code>clojure.lang.Compiler/analyzeSymbol</code> for symbols. There are lots of other evaluation rules there.</p> <h2>Example</h2> <p>Suppose you do this:</p> <pre><code>user&gt; (user/a) </code></pre> <p>The REPL ends up doing this internally:</p> <pre><code>user&gt; (eval '(user/a)) </code></pre> <p>Clojure sees that you're evaluating a list, so it evaluates all items in the list. The first (and only) item:</p> <pre><code>user&gt; (eval 'user/a) #&lt;user$a__1811 user$a__1811@82c23d&gt; </code></pre> <p><code>a</code> is not a special form and this list doesn't need to be macroexpanded, so the symbol <code>a</code> is looked up in the namespace <code>user</code> and the <strong>resulting value</strong> here is an <code>fn</code>. So this <code>fn</code> is called.</p> <h2>Your code</h2> <p>But instead you have this:</p> <pre><code>user&gt; (eval '((quote user/a))) </code></pre> <p>Clojure evaluates the first item in the list, which is itself a list. </p> <pre><code>user&gt; (eval '(quote user/a)) user/a </code></pre> <p>It evaluated the first item in this sub-list, <code>quote</code>, which is a special form, so special rules apply and it returns its argument (the Symbol <code>a</code>) un-evaluated.</p> <p>The symbol <code>a</code> is the <strong>value</strong> in this case as the <code>fn</code> was the value up above. So Clojure treats the Symbol itself as a function and calls it. In Clojure, anything that implements the <code>Ifn</code> interface is callable like an <code>fn</code>. It so happens that <code>clojure.lang.Symbol</code> implements <code>Ifn</code>. A Symbol called as a function expects one parameter, a collection, and it looks itself up in that collection. It's meant to be used like this:</p> <pre><code>user&gt; ('a {'a :foo}) :foo </code></pre> <p>This is what it tries to do here. But you aren't passing any parameters, so you get the error "Wrong number of args passed to: Symbol" (it expects a collection).</p> <p>For your code to work you'd need two levels of <code>eval</code>. This works, hopefully you can see why:</p> <pre><code>user&gt; (eval '((eval (quote user/a)))) Hello, world user&gt; ((eval (first l))) Hello, world </code></pre> <p>Note that in real code, using <code>eval</code> directly is usually a really bad idea. Macros are a better idea by far. I'm only using it here for demonstration. </p> <p>Look in <code>Compiler.java</code> in the Clojure source to see how this all plays out. It's not too hard to follow.</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload