> (cons 2 3)
(2 . 3)
The Lisp environment needs to allocate only a single cons cell to connect the two items.
Above is from the Lisp book "Land of Lisp". I don't understand why this pair is only located in a single cons cell. What does the memory look like for this data?
A cons cell always holds two values, called car and cdr:
+-----+-----+
| car | cdr |
+-----+-----+
To represent a cons cell, Lisp has the "dot notation":
(car . cdr)
The function cons creates such a cons cell from its two arguments:
(cons 1 2)
=> (1 . 2)
which can be thought of like this:
+-----+-----+
| 1 | 2 |
+-----+-----+
The values of a cons cell can also be "references" or "pointers" to other things. Those other things can, for example, be other cons cells:
+-----+-----+ +-----+-----+
| 1 | ------->| 2 | nil |
+-----+-----+ +-----+-----+
This would be (1 . (2 . nil)) in dot notation. This chaining is used in Lisp to represent lists. Since lists are used for the representation of code, they are important for Lisp. Therefore, there is a shorter notation for them: (1 2).
A CONS cell is a record with two fields.
In many Lisp implementations there are special optimizations for cons cells. A typical one is that fixnum numbers are stored directly in the fields - without pointers. As long as the data fits into the memory, they can be stored directly. This may be for example also the case with characters. A cons cell with two characters may also be stored such that the characters are encoded into the fields.
With other, larger, data there are pointers to that data stored into the cons cell.
Then also note the difference between:
(cons 1 2)
and
(list 1 2)
(cons 1 2) creates a single cons cell. (list 1 2) creates two cons cells. The first cons cell contains 1 and a pointer to the second one. The second cons cell contains 2 and NIL (the end of list marker).
Thus as an optimization, often in key/value pairs one uses only the cons cell and not a list.
((age . 22) (name . "Barbara))
vs.
((age 22) (name "Barbara"))
The latter uses two more cons cells.
I think what's the cons in lisp is something like ( just for explanation, not the real code)
typedef struct _cons
{
void* car;
void* cdr;
} cons;
That's what the "single cons" means.
Memory is an illusion:
(define (cons a d)
(lambda (f) (f a d)))
(define (car x)
(x (lambda (theCar theCdr) theCar)))
(define (cdr x)
(x (lambda (theCar theCdr) theCdr)))
Look Ma, no memory required !
(just kidding)
Related
(equal? '(1 2) (cons 1 2)) ; #f
Why exactly are these two not equivalent considering lists are just that — illusion built on top of cons cells.
(cons 1 2) does not create a proper list. It creates a cons cell with two elements, both are numbers.
A normal list is recursively defined as:
the empty list
or a cons cell with an object as the car and a list as the cdr.
In your call 2 is not a list, but a number. The second argument to cons must be a list to get a proper list.
(1 2)
in (1 2), the car element is a number, the cdr element is (2).
in (2), the car element is a number, the cdr element is (), the empty list.
() is the empty list.
Thus (1 2) is a list according to the definition above.
(cons 1 2) creates (1 . 2), which is not a list according to the definition above, since 2 is not a list.
A list is a chain of conses, with one cons for each element. So '(1 2) is equivalent to (cons 1 (cons 2 '())), which can be simplified to (list 1 2).
The literal equivalent to (cons 1 2) is '(1 . 2)
The question is tagged "racket" and "lisp", here I'm using the Common Lisp language but apart from details this is the same in Racket.
The literal list as read by the Lisp reader when reading the following text:
'(1 2)
can be built by evaluating the following form:
(cons 1 (cons 2 nil))
This is different from:
(cons 1 2)
Which also can be read using a special syntax, as follows:
'(1 . 2)
Racket represents XML data as an X-expression: http://docs.racket-lang.org/xml/index.html?q=#(def._((lib._xml/private/xexpr-core..rkt)._xexpr~3f))
which is defined as follows:
xexpr = string
| (list symbol (list (list symbol string) ...) xexpr ...)
| (cons symbol (list xexpr ...))
| symbol
| valid-char?
| cdata
| misc
In the second alternative, why is it (list symbol string) and not (cons symbol string) ? Is there any specific reason to use list instead of cons ? If not, would there be any advantage in using cons instead of list ?
It's really just a preference on the part of the X-expression designers, probably to mirror let's syntax (which also uses proper lists only).
With (list symbol string), you'd represent Stack Overflow as:
(a ((href "http://stackoverflow.com/")) "Stack Overflow")
whereas with (cons symbol string), it'd be:
(a ((href . "http://stackoverflow.com/")) "Stack Overflow")
Some would consider the "dot" an ugly thing to see.
These are the outputs of different combinations of arguments to cons. I just started learning lisp. Can someone help me understand these ?
Break 80 [81]> (CONS '(A) 'B)
((A) . B)
Break 80 [81]> (CONS '(A) '(B))
((A) B)
Break 80 [81]> (CONS 'A 'B)
(A . B)
Break 80 [81]> (CONS 'A '(B))
(A B)
Break 80 [81]>
The cons function always does the same thing: it produces a cons cell of its arguments. A cons cell is simply a pair. You can get the first element of the pair with car and the second element with cdr.
For writing a literal cell, you can quote and use the notation (x . y) where x is the car and y is the cdr. Using this notation, you can write your examples as follows (but don't just take my word for it, try it in the REPL):
> '((A) . B ) ;=> ((A) . B)
> '((A) . (B)) ;=> ((A) B)
> '( A . B ) ;=> (A . B)
> '( A . (B)) ;=> (A B)
But why don't the results of the second and fourth cases print the same way that we wrote them? There are special printing conventions for cons cells, because we use cons cells to implement linked lists.
Read 14.1.2 Conses as Lists for specifics, but a list is a cons cell whose car is the first element of the list, and whose cdr is the rest of the list (i.e., another list). That means that the list (1 2 3) is the same as (using the literal dotted pair notation) (1 . (2 . (3 . nil))). You can try that in the REPL:
> '(1 . (2 . (3 . nil))) ;=> (1 2 3)
That's a very useful printing (and input) convention for a language where lists are so fundamental. I've written more about this in an answer to other questions, too:
Dot notation in scheme
Recursive range in Lisp adds a period?
I'm just starting to learn Common Lisp and the text I'm reading uses an example with the member function.
I'm unsure of the distinction between these two blocks of code:
(if (member nil '(1 nil 2 3))
'contains-nil
'does-not-contain-nil)
returns CONTAINS_NIL
(if (member nil '(1 2 3))
'contains-nil
'does-not-contain-nil)
returns DOES-NOT-CONTAIN-NIL
From what I understand, lists are equivalent to nested cons cells, so I would think (member nil (cons 1 (cons 2 (cons 3 nil))) would return (nil), but it just returns nil. I'm not sure how a compiler or interpreter would make that distinction, and if someone could give me some insight on how I could implement the member function, I'd appreciate it.
A cons cell holds two values, typically called its car and its cdr. The expression (cons x y) returns a cons cell whose car is x, and whose cdr is y. In Lisp, a list is either the empty list (typically the symbol nil), or a cons cell. When a list is a cons cell, the first element of the list is the cons cell's car, and the rest of the list is the cons cell's cdr. Consider the list (1 2 3). It is a cons cell, and the first element of the list is 1. The rest of the list is not empty, so it must be another list whose first element is 2. The rest of that list is not empty, so it must be another list whose first element is 3. The rest of that list is empty, i.e., nil. Based on that analysis, we can see why the list is formed by
(cons 1 (cons 2 (cons 3 nil)))
== (1 2 3)
In a chain of cons cells that make up a list, the elements of the list are the car values of each cons cell in the chain. Lists can be elements of lists, as in
(cons 1 (cons nil (cons 2 (cons 3 nil))))
== (1 nil 2 3)
or
(cons 1 (cons (cons 2 (cons 3 nil)) nil))
== (1 (2 3))
but just because we see nil in the longer expression doesn't mean that nil is an element of the list.
MEMBER looks only at the elements of the list, not the list itself. An empty list is something different than an empty list with another empty list as an element.
() is not the same as (()). () is not the same as (nil).
Since a list is made of cons cells, the elements are the cars of the cons cells.
A list is defined to be either the empty list NIL or to be a cons cell whose CAR is an element of the list and whose CDR is another list.
The list that is produced by
(cons 1 nil)
is a list that has the element 1 and also all the elements of the empty list. The empty list has no elements, so NIL is not an element of the list.
It is similar with sets: Although the empty set is a subset of any set it is not an element of every set (while it isn't generally prohibited from being an element of a set).
One way o implement MEMBER is like this:
(defun member (item list)
(if list
(if (eql item (car list))
list
(member item (cdr list)))))
So if LIST is NIL the whole function will return NIL.
Our own version of the predefined member function in lisp can be defined as :
(defun member2 (item lst)
(if lst
(if (eql item (car lst))
T
(member2 item (cdr lst)))))
It seems one is not supposed to quote KEYMAP when using define-key.
(define-key org-remember-mode-map "\C-c\C-r" 'org-remember-kill)
I'm confused because I think that all arguments of a function that is not quoted are evaluated, and according to the help, define-key is a function, not a macro. I don't see why the value of KEYMAP can be modified after a call of define-key.
(defun increment-value (a)
(setq a (+ 1 a)))
(setq my-num 10)
(increment-value my-num)
my-num ; ===> 10
Update: The answers explain everything, but for those still confused, let me clear up with more examples.
My increment-value example above is equivalent to this:
(let ((n 0))
(print n) ; prints 0
(let ((a n))
(setq a (+ 1 a))
(print a) ; prints 1
)
(print n) ; prints 0
)
What's going on above is, I think, similar to what's going on in this some-map example:
(let ((some-map '(1 2)))
(print some-map) ; prints (1 2)
(let ((a some-map))
(setq a (list 4 (second a)))
(print a) ; prints (4 2)
)
(print some-map) ; prints (1 2)
)
What's going on in define-key is similar to this second some-map example:
(let ((some-map '(1 2)))
(print some-map) ; prints (1 2)
(let ((a some-map))
(setcar a 4)
(print a) ; prints (4 2)
)
(print some-map) ; prints (4 2)
)
Now read the answers again with these three examples in mind and you will get it. Read also http://www.emacswiki.org/emacs/ListModification
You aren't actually changing what 'org-remember-map is (a pointer to a particular list structure), you are modifying the actual structure. Read this info page for details on modifying lists.
Specificially, if you take a look at the documentation for 'make-keymap:
(make-keymap &optional string)
Construct and return a new keymap, of
the form (keymap CHARTABLE . ALIST).
CHARTABLE is a char-table that holds
the bindings for all characters
without modifiers. All entries in it
are initially nil, meaning "command
undefined". ALIST is an assoc-list
which holds bindings for function
keys, mouse events, and any other
things that appear in the input
stream. Initially, ALIST is nil.
You'll see that keymap is a list with three elements. Let me draw that for you (yay M-x artist-mode):
org-remember-map
|
|
v
+----+----+ +----+----+
| | | --+--->+ / | \ |
+-+--+----+ +-/--+--\-+
| | |
v v v
keymap CHARTABLE ALIST
So, the value of the 'org-remember-map is something like the above structure, and when you define a key, what you are doing is changing what is pointed to in the ALIST blob part of the structure.
you're confusing value and name-value mapping.
in your increment-value function, you're not changing a's value as much as changing the mapping of the name a to a new value.
Fundamentally, there is no way to change the value of 10. 10 is 10!
But in the first case, you can either modify the mapping of the name org-remember-mode-map to a fully different map (set a new value), or you can alter the map pointed by that name (its current value). This is what define-key does.
Illustration:
(setq a '(1 2)) -> (1 2)
(setcar a 4) -> 4
a -> (4 2)
Everything you write is completely correct. The thing you are missing is that lists (keymaps are represented as lists) are not values themselves, but containers of values. Thus, you can pass a list to a function and have that function change the values of the list, but the list you have is still the same list.
All the details are in the Cons Cell Type section of the elisp manual.