Why does Clojure allow (eval 3), although 3 is not quoted?

I study Clojure and try to understand the reader by quoting, eval and homoiconicity, drawing parallels with similar Python functions.

In Python, one way to avoid (or defer) evaluation is to wrap the expression between quotes, for example. '3 + 4' . You can evaluate this later using eval , for example. eval('3 + 4') gives 7 . (If you need to specify only Python values, you can use the repr function instead of adding quotes manually.)

In Lisp, you use quote or ' to quote and eval to evaluate, for example. (eval '(+ 3 4)) gives 7 .

So, in Python, the β€œquoted” material is represented by a string, while in Lisp it is represented by a list that has quote as the first element.

My question is finally: why does Clojure allow (eval 3) , although 3 not quoted? Is it just a Lisp style question (trying to give an answer instead of an error where possible) or are there some other reasons? Is this behavior significant for Lisp or not?

+8
eval lisp clojure
source share
4 answers

Other answers explained the mechanics, but I think that the philosophical point is different in lisp and python look at the "code". In python, the only way to represent the code is through a string, so of course, trying to evaluate a non-row will fail. lisp has richer data structures for code: lists, numbers, characters, etc. Thus, the expression (+ 1 2) is a list containing a character and two numbers. When evaluating a list, you must first evaluate each of its elements.

Thus, it is only natural that you need to evaluate a number in the normal course of lisp code execution. To this end, the numbers are defined as "evaluate for themselves", that is, they are the same after the evaluation, as before: just a number. The eval function applies the same rules to the general "code snippet" 3 that the compiler will apply when compiling, say, the third element of a larger expression, such as (+ 5 3) . For numbers, this means leaving him alone.

+4
source share

The short answer will be that numbers (both characters and strings, for example) are evaluated on their own. Quote the lisp instruction (reader) to convey invaluable information following the quote. eval then gets this list as you wrote it, but without a quote, and then evaluates it (in the case of (eval '(+ 3 4)) , eval will evaluate the call to the ( + ) function with two arguments).

What happens to this last expression:

  • When you press enter, the expression is evaluated. It contains a regular function call ( eval ) and some arguments.
  • Arguments are evaluated. The first argument contains a quote that tells the reader what will happen after the quote (actual list (+ 3 4) ).
  • No more arguments, and the actual function call is calculated. This means calling the eval function with a list (+ 3 4) as an argument.
  • The eval function does the same thing again, detecting the normal function + and the arguments and applying it to get the result.
+6
source share

What should 3 rate? It makes the most sense that Lisp evaluates the number for itself. Do we want the numbers indicated in the code? This would not be very convenient and extremely problematic:

Instead

 (defun add-fourtytwo (n) (+ n 42)) 

we would have to write

 (defun add-fourtytwo (n) (+ n '42)) 

Each number in the code must be indicated. A missing quote will cause an error. This is not what I would like to use.

As an additional note, imagine what happens if you want to use eval in your code.

 (defun example () (eval 3)) 

The above would be wrong. Numbers must be indicated.

  (defun example () (eval '3)) 

The above would be nice, but generate a runtime error. Lisp evaluates '3 to number 3. But then calling eval to a number will be an error, as they must be specified.

So, we will need to write:

 (defun example () (eval ''3)) 

This is not very useful ...

Numbers are always self-esteeming in Lisp history. But in earlier Lisp implementations, some other data objects, such as arrays, did not have self-esteem. Again, since this is a huge source of errors, Lisp dialogs such as Common Lisp have determined that all data types (except lists and characters) are self-evaluating.

+3
source share

To answer this question, we need to look at the definition of eval in lisp. For example. in CLHS there is a definition:

Syntax: eval form => result *

Arguments and meanings: form - form.
results are the values ​​obtained when evaluating the form.

Where form is

  • any item that needs to be evaluated.
  • symbol, compound form or self-esteem of the object.
  • (for an operator, as in <<operator>> form'') a compound form having that operator as its first element. The quote form is a permanent form. ''

In your case, the number "3" is a self-evaluating object . self-evaluating object - a form that is neither a symbol nor a cons is defined to be a self-evaluating object . I believe that for clojure we can simply replace cons with list in this definition.

In clojure, only lists interpreted by eval as function calls. Other data structures and objects are valued as self-valued objects.

'(+ 3 4) is equal to (list '+ 3 4) . ' (transformed by the reader into a quote function), just avoid evaluating this form. Thus, the expression (eval '(+ 3 4)) eval takes the list data structure ('+ 3 4) as an argument.

+2
source share

All Articles