This question already has answers here:
What is the difference between eq?, eqv?, equal?, and = in Scheme?
(7 answers)
Closed 9 years ago.
I really cant figure out the major difference between eq?, eqv? and equal?
Please explain this.
Besides, why do we need them?
For a technical explanation, take a look at the specification, you won't find a more detailed reference. Or simply check your interpreter's documentation, for example in Racket:
(equal? v1 v2) → boolean?
Two values are equal? if and only if they are eqv?, unless otherwise specified for a particular datatype. Datatypes with further specification of equal? include strings, byte strings, pairs, mutable pairs, vectors, boxes, hash tables, and inspectable structures. In the last six cases, equality is recursively defined; if both v1 and v2 contain reference cycles, they are equal when the infinite unfoldings of the values would be equal.
(eqv? v1 v2) → boolean?
Two values are eqv? if and only if they are eq?, unless otherwise specified for a particular datatype. The number and character datatypes are the only ones for which eqv? differs from eq?.
(eq? v1 v2) → boolean?
eq? returns #t if v1 and v2 refer to the same object, #f otherwise. See also Object Identity and Comparisons.
There are a full two pages in the RNRS specification related to eq?, eqv?, equal? and =. Here is the Draft R7RS Specification. Check it out!
Related
How can I hash pairs or triples of 'eq-able objects like symbols or ints?
In python I can use tuples as dictionary keys, is there a way to do this in lisp without resorting to an 'equal test?
While some implementations might provide provisions for custom hash table functions, the standard only defines four:
18.1.1 Hash-Table Operations
There are four kinds of hash tables: those whose keys are compared with eq, those whose keys are compared with eql, those whose keys are
compared with equal, and those whose keys are compared with equalp.
That means that if you want to use the standard hash tables, then you'll probably need to use an equal or equalp hash table. I do notice that you wrote:
How can I hash pairs or triples of 'eq-able objects like symbols or
ints?
While symbols can be compared reliably with eq, you shouldn't compare numbers with eq. The documentation of eq says:
numbers with the same value need not be eq, … An implementation is permitted to make "copies" of characters and numbers at any time. The effect is that Common Lisp makes no guarantee that eq is true even when both its arguments are "the same thing" if that thing is a character or number.
and gives this example:
(eq 3 3)
; => true
; OR=> false
However, if you are working with (small) tuples of integers, you could easily hash on a function of them. E.g., the tuple (a,b,c) could be mapped to 2a×3b×5c. Since a function like that would generate unique numbers which are comparable with eql, you could use an eql hash table.
Another option for such a mapping function (that would work with symbols, too) would be to use sxhash. It's a standard hashing function that should produce identical values for equal values. How it works, and what exactly it does is not really specified at all, but it has the advantage that it's stable across Lisp images of the same implementation (e.g., run one version of SBCL today and tomorrow, and sxhash will return the same result for an equal object). Of course, it's possible that an equal-hash-table is just doing this for you already, so your mileage might vary.
Basically, the title says it all: In Common Lisp, why is the null predicate called null. not nullp (to conform to other predicates such as evenp or oddp)? Is there a special reason for this?
First of all, null is not the only one. See atom.
Second, I think these predicates are fundamental ones and thus, very old. I don't think the 'end with p' agreement was introduced from the very beginning of LISP.
Also interesting info on the topic:
By convention, the names of predicates usually end in the letter p (which stands for 'predicate'). Common Lisp uses a uniform convention in hyphenating names of predicates. If the name of the predicate is formed by adding a p to an existing name, such as the name of a data type, a hyphen is placed before the final p if and only if there is a hyphen in the existing name. For example, number begets numberp but standard-char begets standard-char-p. On the other hand, if the name of a predicate is formed by adding a prefixing qualifier to the front of an existing predicate name, the two names are joined with a hyphen and the presence or absence of a hyphen before the final p is not changed. For example, the predicate string-lessp has no hyphen before the p because it is the string version of lessp (a MacLisp function that has been renamed < in Common Lisp). The name string-less-p would incorrectly imply that it is a predicate that tests for a kind of object called a string-less, and the name stringlessp would connote a predicate that tests whether something has no strings (is ``stringless'')!
Source: http://www.cs.cmu.edu/Groups/AI/html/cltl/clm/node69.html
The predicate NULL is very old. It's called NULL in Common Lisp in the hope of encouraging the conversion of legacy Lisp code into Common Lisp
Gosh! It appears in the March 1959 version, and possibly earlier, of McCarthy's original memos (see page 3 of the pdf found here: http://dspace.mit.edu/handle/1721.1/6096 ) as one of the three basic predicates.
Amusingly this is before the introduction of car and cdr. Fascinating - in that memo elements in lists are separated by commas.
In book 'land of lisp' I read
Because the case command uses eq for comparisons, it is usually used
only for branching on symbol values. It cannot be used to branch on
string values, among other things.
Please explain why?
The other two excellent answers do answer the question asked. I will try to answer the natural next question - why does case use eql?
The reason is actually the same as in C (where the corresponding switch statement uses numeric comparison): the case forms in Lisp are usually compiled to something like goto, so (case x (1 ...) (2 ...) (3 ...)) is much more efficient than the corresponding cond. This is often accomplished by compiling case to a hash table lookup which maps the value being compared to the clause directly.
That said, the next question would be - why not have a case variant with equal hash table clause lookup instead of eql? Well, this is not in the ANSI standard, but implementations can provide such extensions, e.g., ext:fcase in CLISP.
See also why eql is the default comparison.
Two strings with the same content "foo" and "foo" are not EQL. CASE uses EQL as a comparison (not EQ as in your question). Usually one might want different tests: string comparison case and case insensitive, for example. But for CASE on cannot use another test. EQL is built-in. EQL compares for pointer equality, numbers and characters. But not string contents. You can test if two strings are the identical data objects, though.
So, two strings "FOO" and "FOO" are usually two different objects.
But two symbols FOO and FOO are usually really the same object. That's a basic feature of Lisp. Thus they are EQL and CASE can be used to compare them.
Because (eq "foo" "foo") is not necessarily true. Each time you type a string literal, it may create a fresh, unique string. So when CASE is comparing the value with the literals in the cases with EQ, they won't match.
Is it possible to convert a church numeral to an integer representation without using a language primitive such as add1?
All the examples I've come across use a primitive to dechurch to int
Example:
plus1 = lambda x: x + 1
church2int = lambda n: n(plus1)(0)
Example 2:
(define (church-numeral->int cn)
((cn add1) 0))
I'm experimenting with a micro lisp intepretter (using only John McCarthy's 10 rules) and would like to understand if that can be done without adding a primitive.
The integer numeric type is not part of McCarthy's list of Lisp elementary primitive procedures - you only have functions at that level, no other data types exist. That's why integers would need to be represented as functions (for instance, using Church numerals) if we were to adhere strictly to such minimalistic definition of Lisp. So the answer is no. You can't convert to a data type that doesn't exist yet.
Now suppose that we add integers as atoms in the language (notice that adding a new data type to the language goes beyond the 7-10 primitive procedures mentioned). To simplify even more, suppose that we just add a single number, the number zero - then we'd still need the add1 operation to build the rest of the integers, as per Peano axioms, which require the existence of the successor operation for the natural numbers to exist. Again, we can't convert from Church numerals to integers without at least having the number zero as an atom and the add1 function.
No. int, as you describe it, is a primitive type of value, not a function. You can't manipulate such ints at all without primitives (without add1, how are you ever going to get to 1 from 0?).
However, you certainly can convert between two different Church-encodings of natural numbers without using primitives, as long as your language is Turing-complete without those primitives.
For the love of the almighty I have yet to understand the purpose of the symbol 'iamasymbol. I understand numbers, booleans, strings... variables. But symbols are just too much for my little imperative-thinking mind to take. What exactly do I use them for? How are they supposed to be used in a program? My grasp of this concept is just fail.
In Scheme and Racket, a symbol is like an immutable string that happens to be interned so that symbols can be compared with eq? (fast, essentially pointer comparison). Symbols and strings are separate data types.
One use for symbols is lightweight enumerations. For example, one might say a direction is either 'north, 'south, 'east, or 'west. You could of course use strings for the same purpose, but it would be slightly less efficient. Using numbers would be a bad idea; represent information in as obvious and transparent a manner as possible.
For another example, SXML is a representation of XML using lists, symbols, and strings. In particular, strings represent character data and symbols represent element names. Thus the XML <em>hello world</em> would be represented by the value (list 'em "hello world"), which can be more compactly written '(em "hello world").
Another use for symbols is as keys. For example, you could implement a method table as a dictionary mapping symbols to implementation functions. To call a method, you look up the symbol that corresponds to the method name. Lisp/Scheme/Racket makes that really easy, because the language already has a built-in correspondence between identifiers (part of the language's syntax) and symbols (values in the language). That correspondence makes it easy to support macros, which implement user-defined syntactic extensions to the language. For example, one could implement a class system as a macro library, using the implicit correspondence between "method names" (a syntactic notion defined by the class system) and symbols:
(send obj meth arg1 arg2)
=>
(apply (lookup-method obj 'meth) obj (list arg1 arg2))
(In other Lisps, what I've said is mostly truish, but there are additional things to know about, like packages and function vs variable slots, IIRC.)
A symbol is an object with a simple string representation that (by default) is guaranteed to be interned; i.e., any two symbols that are written the same are the same object in memory (reference equality).
Why do Lisps have symbols? Well, it's largely an artifact of the fact that Lisps embed their own syntax as a data type of the language. Compilers and interpreters use symbols to represent identifiers in a program; since Lisp allows you to represent a program's syntax as data, it provides symbols because they're part of the representation.
What are they useful apart from that? Well, a few things:
Lisp is commonly used to implement embedded domain-specific languages. Many of the techniques used for that come from the compiler world, so symbols are an useful tool here.
Macros in Common Lisp usually involve dealing with symbols in more detail than this answer provides. (Though in particular, generation of unique identifiers for macro expansions requires being able to generate a symbol that's guaranteed never to be equal to any other.)
Fixed enumeration types are better implemented as symbols than strings, because symbols can be compared by reference equality.
There are many data structures you can construct where you can get a performance benefit from using symbols and reference equality.
Symbols in lisp are human-readable identifiers. They are all singletons. So if you declare 'foo somewhere in your code and then use 'foo again, it will point to the same place in memory.
Sample use: different symbols can represent different pieces on a chessboard.
From Structure and Interpretation of Computer Programs Second Edition by Harold Abelson and Gerald Jay Sussman 1996:
In order to manipulate symbols we need a new element in our language:
the ability to quote a data object. Suppose we want to construct the list
(a b). We can’t accomplish this with (list a b), because this expression
constructs a list of the values of a and b rather than the symbols themselves.
This issue is well known in the context of natural languages, where words
and sentences may be regarded either as semantic entities or as character
strings (syntactic entities). The common practice in natural languages is to use quotation marks to indicate that a word or a sentence is to be treated
literally as a string of characters. For instance, the first letter of “John” is
clearly “J.” If we tell somebody “say your name aloud,” we expect to hear
that person’s name. However, if we tell somebody “say ‘your name’ aloud,”
we expect to hear the words “your name.” Note that we are forced to nest
quotation marks to describe what somebody else might say.
We can follow this same practice to identify lists and symbols that are
to be treated as data objects rather than as expressions to be evaluated.
However, our format for quoting differs from that of natural languages in
that we place a quotation mark (traditionally, the single quote symbol ’)
only at the beginning of the object to be quoted. We can get away with this in Scheme syntax because we rely on blanks and parentheses to delimit
objects. Thus, the meaning of the single quote character is to quote the
next object.
Now we can distinguish between symbols and their values:
(define a 1)
(define b 2)
(list a b)
(1 2)
(list ’a ’b)
(a b)
(list ’a b)
(a 2)
Lists containing symbols can look just like the expressions of our language:
(* (+ 23 45) (+ x 9))
(define (fact n) (if (= n 1) 1 (* n (fact (- n 1)))))
Example: Symbolic Differentiation
A symbol is just a special name for a value. The value could be anything, but the symbol is used to refer to the same value every time, and this sort of thing is used for fast comparisons. As you say you are imperative-thinking, they are like numerical constants in C, and this is how they are usually implemented (internally stored numbers).
To illustrate the point made by Luis Casillas, it might be useful to observe how symbols eval differently than strings.
The example below is for mit-scheme (Release 10.1.10). For convenience, I use this function as eval:
(define my-eval (lambda (x) (eval x (scheme-report-environment 5))))
A symbol can easily evaluate to the value or function it names:
(define s 2) ;Value: s
(my-eval "s") ;Value: "s"
(my-eval s) ;Value: 2
(define a '+) ;Value: a
(define b "+") ;Value: b
(my-eval a) ;Value: #[arity-dispatched-procedure 12]
(my-eval b) ;Value: "+"
((my-eval a) 2 3) ;Value: 5
((my-eval b) 2 3) ;ERROR: The object "+" is not applicable.