Why is a literal quoted list not the same as a list built by list constructors - lisp

(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)

Related

Lisp: How to set element in list of lists?

I am familiar with how to set elements in a 2D array, which can be done using the following statement.
(setf (aref array2D 0 0) 3)
However, I am not familiar how to set elements in a list of lists, such as the following input: '((1) (2) (2) (1)). I can't use aref, since it only works on arrays.
As mentioned, while aref works on arrays, elt works on sequences which can be:
an ordered collection of elements
a vector or a list.
* (setf test-list '((1) (2) (2) (1)))
((1) (2) (2) (1))
* (setf (elt test-list 2) 'hi)
HI
* test-list
((1) (2) HI (1))
You can indeed use variables in place of fixed offsets:
* (setf test-list '((1) (2) (2) (1)))
((1) (2) (2) (1))
* (setf offset 2)
2
* (setf (elt test-list offset) 'hi)
HI
* test-list
((1) (2) HI (1))
To access the nth element of a list, there are (at least) two functions: nth and elt. The order of the parameters is different, and nth only work on lists while elt works on any sequence (i.e. lists, vector, strings ...):
(nth 1 '(foo bar baz)) => BAR
(nth 1 #(foo bar baz)) => ERROR
(elt '(foo bar baz) 1) => BAR
(elt #(foo bar baz) 1) => BAR
Now, in general, the way to set a value (as opposed to simply access it) is very straightforward, and at least for built-in functions this is almost always the case: whenever you have some form FORM which retrieves some value from what is called a place, the form (setf FORM <value>) will set this element to the given <value>. This works for functions such as car, cdr, gethash, aref, slot-value, symbol-function and many others, and any combination of those.
In your example, you have a list of lists. So, for example, to modify the "inner integer" in say the third list:
* (setf test-list '((0) (1) (2) (3))) ; changed the values to have something clearer
((0) (1) (2) (3))
* (car (nth 2 test-list)) ; this accesses the integer in the second list
2
* (setf (car (nth 2 test-list)) 12) ; this modifies it. Notice the syntax
12
* test-list
((0) (1) (12) (3))
On a side note, you should avoid modifying literal lists (created using the quote symbol '). If you want to modify lists, create them at runtime using the list function.
EDIT:
What happens is that setf knows, by "looking" at the form you give it, how to actually find the place that you want to modify, potentially using functions in this process.
If you look at other languages, such as Python, you also have some kind of duality in the syntax used both to get and to set values. Indeed, if you have a list L or a dictionary d, then L[index] and d[thing] will get the corresponding element while L[index] = 12 and d[thing] = "hello" will modify it.
However, in Python, those accessors use a special syntax, namely, the squares brackets []. Other types of objects use another syntax, for example, the dot notation to access slots/attributes of an object as in my-object.attr. A consequence is that the following code is invalid in Python:
>>> L = [1, 2, 3, 2, 1]
>>> max(L)
3
>>> max(L) = 12
Traceback (most recent call last):
File "<string>", line 9, in __PYTHON_EL_eval
File "/usr/lib/python3.8/ast.py", line 47, in parse
return compile(source, filename, mode, flags,
File "<string>", line 1
SyntaxError: cannot assign to function call
You have to write an other function, for example, setMax(L, val), to change the maximum of a list. This means that you now have to functions, and no symmetry anymore.
In Common Lisp, everything is (at least syntactically) a function call. This means that you can define new ways to access and modify things, for any function ! As a (bad) example of what you could do:
* (defun my-max (list)
(reduce #'max list))
MY-MAX
* (my-max '(1 2 3 8 4 5))
8
* (defun (setf my-max) (val list)
(do ((cur list (cdr cur))
(cur-max list (if (< (car cur-max) (car cur))
cur
cur-max)))
((endp (cdr cur)) (setf (car cur-max) val))))
(SETF MY-MAX)
* (setf test-list (list 0 4 5 2 3 8 6 3))
(0 4 5 2 3 8 6 3)
* (setf (my-max test-list) 42)
42
* test-list
(0 4 5 2 3 42 6 3)
This way, the syntax used to both set and get the maximum of a list is identical (FORM to get, (setf FORM val) to set), and combines automatically with every other "setter". No explicit pointers/references involved, it's just functions.

How do I create a version of filter using map (racket ISL)

I am Tasked (in exercise 8) with creating a function in Intermediate Student Language (Racket) that receives a list of numbers and a list of lists of numbers; each list is the same length. Name the first list breakpoints and the second LoR (list of rows). This function should be defined using map and should filter each row in LoR so that only numbers larger than that the n'th row in LoR only contains values larger than the n'th value in breakpoints-- here is an example for clarity:
(define breakpoints (list 7 2 15))
(define LoR (list (list 3 25 13)
(list 1 2 11)
(list 22 4 8)))
would output...
(list (list 25 13) (list 11) (list 22))
Doing this without using map would be fine and I understand the problem in that sense, but I am having trouble figuring out how to use map. I was thinking recursively in the sense that if the list of rows is not empty, I would cons the (filtered first row) to the (recursive call of the function using the rest of breakpoints and LoR) as so:
(define (parallel-filter breakpoints LoR)
(cond((empty? breakpoints) empty)
(else (cons ...
(parallel-filter (rest breakpoints) (rest LoR))))))
However, I'm not sure how to replace the ellipse with a map statement that would make the function work correctly-- as I understand, map's first parameter must be a one-parameter function and I'm not sure how to use map for this purpose. How do I proceed?
edited to correct output
We can solve this problem by combining map and filter, but first bear in mind this:
You can't use just map, because it will always return a list of the same length as the original. For excluding some elements we must use filter (or alternatively: use foldr to implement our own version of filter)
map can receive more than one list as parameter, as long as its function receives enough parameters - one from each list
Your sample output is wrong for the first sublist
With all of the above in mind, here's one possible solution:
(define (parallel-filter breakpoints LoR)
(map (lambda (brk lst) ; `brk` is from `breakpoints` and `lst` is from `LoR`
(filter (lambda (ele) (> ele brk)) ; filter each sublist from `LoR`
lst))
breakpoints
LoR))
It works as expected:
(parallel-filter breakpoints LoR)
=> (list (list 25 13) (list 11) (list 22))

Lists and Member Implementation in Common Lisp

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)))))

Recursive range in Lisp adds a period?

(define ..
(lambda (start stop)
(cond ((> (add1 start) stop) (quote ()))
((eq? (add1 start) stop) (sub1 stop))
(else (cons start (.. (add1 start) stop))))))
I have defined a simple range function.
The intent is for
(.. 1 5) --> (1 2 3 4)
Instead, a bizarre period is being added to my tuple and I have no idea why:
(.. 1 5) --> (1 2 3 . 4)
I don't understand why this is happening. Any help is appreciated
A list in Scheme is either the empty list () (also known as nil in some Lisps), or a cons cell whose car (also known as first) is an element of the list and whose cdr (also known as rest) is either the rest of the list (i.e., another list), or an atom that terminates the list. The conventional terminator is the empty list (); lists terminated by () are said to be "proper lists". Lists terminated by any other atom are called "improper lists". The list (1 2 3 4 5) contains the elements 1, 2, 3, 4, and 5, and is terminated by (). You could construct it by
(cons 1 (cons 2 (cons 3 (cons 4 (cons 5 ())))))
Now, when the system prints a cons cell, the general case is to print it by
(car . cdr)
For instance, the result of (cons 1 2) is printed as
(1 . 2)
Since lists are built of cons cells, you can use this notation for lists too:
'(1 2 3 4 5) ==
'(1 . (2 . (3 . (4 . (5 . ())))))
That's rather clunky, though, so most lisps (all that I know of) have a special case for printing cons cells: if the cdr is a list (either another cons cell, or ()), then don't print the ., and don't print the surrounding parenthesis of the cdr (which it would otherwise have, since it's a list). So, if you're seeing a result like
(1 2 3 . 4)
it means you've got an improper list that is terminated by the atom 4. It has the structure
(1 . (2 . (3 . 4)))
Now the question is: where in your code did the list construction go awry? .. is always supposed to return a proper list, so let's look at the cases: The first case always returns a proper list (the empty list):
((> (add1 start) stop) (quote ()))
The second case looks like it can return something that's not a list (assuming that (sub1 stop) == (- stop 1)):
((eq? (add1 start) stop) (sub1 stop))
Now, if .. were functioning correctly, then the third case would always be returning a proper list (since (cons x y) is a proper list if y is):
(else (cons start (.. (add1 start) stop)))
Make your second case return a list and you should be all set.
Your expression (sub1 stop) needs to read (list (sub1 stop))
In order for cons to build up a proper list, the second element needs to be a list itself. Thus, your function .. should return a list of some type for every cond clause.
Remove this part of the cond
((eq? (add1 start) stop) (sub1 stop))
It's causing a premature finish.

List Item Evaluation

I'm learning lisp and have a question about a simple list:
(setq stuff '(one two three (+ 2 2)))
stuff ; prints "one two three (+ 2 2)"
(setq stuff (list `one `two `three (+ 2 2)))
stuff ; prints "one two three 4"
The first setq creates a list "one two three (+ 2 2)". The second list creates "one two three 4". Why does the first list not evaluate the (+ 2 2), but the second one does? I read in the Emacs Lisp intro documentation that when the list is built that it evaluates from the inside out. Why doesn't the first list evaluate the addition before adding it to the list?
This is elisp in emacs 24.
' is not equivalent to list, it's shorthand for quote. You're really doing this:
(setq stuff (quote (one two three (+ 2 2))))
The argument to quote is the expression (one two three (+ 2 2)).
From http://www.gnu.org/software/emacs/manual/html_node/elisp/Quoting.html: "The special form quote returns its single argument, as written, without evaluating it".
Looks like you're coming to grips with the evaluation semantics of Lisp, so keep playing around!
You can think of quote as suppressing evaluation of its argument. This allows you to write expressions that you can manipulate or pass around. It is also used to write data structures that should not be evaluated as function calls.
Data structures:
'(1 2 3) ; => '(1 2 3)
(1 2 3) ; => Lisp error: (invalid-function 1)
;; The Lisp reader sees the number 1 in the function position and tries to call it, signalling an error.
Syntax transformations:
(setq x '(string-to-int "123"))
(setf (car x) 'string-to-list)
x ; => '(string-to-list "123")
Delayed evaluation:
(setq x '(message "Hello World")) ; => '(message "Hello World")
(eval x) ; => "Hello World"
There is a closely related special operator called syntax quote, written using the backtick. It allows you to evaluate individual forms in a quoted expression using the comma ( , ) operator. It is like quote with an escape hatch.
`(1 2 (+ 3 4)) ; => '(1 2 (+ 3 4))
`(1 2 ,(+ 3 4)) ; => '(1 2 7) ;; Note the comma!
Syntax quote also permits list splicing using the ,# syntax:
`(1 2 ,#(+ 3 4)) ; => '(1 2 + 3 4)
As you can see, it splices the subsequent expression into the containing one. You probably won't see it all that often until you start writing macros.
list on the other hand is a simple function. It evaluates its arguments, then returns a new data structure containing these items.
(list 1 2 (+ 3 4)) ; => '(1 2 7)