What does (cons? list-name) do? - list

I was wondering what (cons? list-name) does. Does it just check that list-name is not a non-empty list? Is it just like the opposite of (empty? list-name)? If so, then is it not better to just say (empty? list-name) and then say else instead of cons?? For example:
(define (f list-name)
(cond
[(empty? list-name) empty]
[(cons? list-name) "do something]))

jozefg's answer is right in pointing out that (cons? x) is not the same as (not (empty? x)), in general, because there are things (e.g., numbers) that are neither cons cells nor the empty list.
However, your variable was list-name, so you may have some reason to expect that its value is, in fact a list. A list, in Scheme, is either:
the empty list; or
a cons cell whose car is the first element of a list and whose cdr is the rest of the list.
Because of this, if you're writing a function that requires a list be passed in, then it does make sense to simply check for the trivial case (the empty list) with empty?, and to assume, since you've required a list, that anything that doesn't match that case is a cons cell on which you can call cdr and cdr. This is because while
(cons? x) == (not (empty? x))
is not true of values in general, it is true for lists. That is, if you already know that lst is a list, then
(cons? lst) == (not (empty? lst))
is true. There are a number of functions that do the same thing when we're talking about lists and cons cells. E.g., empty? and null? do the same thing, but they signal a slightly different intent on the part of the programmer. Similarly, car and cdr do the same thing as first and rest, but car and cdr signal that you might be treating something as a pair of two things, whereas first and rest clearly signal the intent that you're working with a list.
Your code, since it seems to expect a list, should probably be the following, since, for a list, if it's not the empty list, it must be a cons.
(define (f lst)
(cond
[(empty? lst) empty]
[else "do something]))
More generally, the code you write should depend on what kind of input you expect. E.g., in the first case, it's fine to check for empty, and assume a cons otherwise, because you're expecting a list. In the second case, you have to check for all the different kinds of things you might see.
(define (frob-list lst)
(cond
[(empty? lst) empty] ; arg is ()
[else ...])) ; arg is (x . y)
(define (frob-object obj)
(cond
[(null? obj) ...] ; arg is ()
[(cons? obj) ...] ; arg is (x . y)
[(number? obj) ...] ; arg is r
... ; arg is ...
[else ...])) ; else ...

cons? checks whether the value is a cons cell, e.g., something that's (cons foo bar) for some foo and bar.
> (cons? 1)
#f
> (cons? '())
#f
> (cons? (list 1 2 3))
#t
> (cons? (cons 1 2))
#t
If (cons? a) is true, then it is safe to use car and cdr on a.
This isn't the opposite of empty? since empty? is true if and only if the argument is the empty list, so (empty? 1) == (cons? 1) == #f.
Sidenote: Please don't put PLEASE HELP!! or similar in your question titles, everyone here is happy to help, but it's a bit obnoxious to read. Just something to keep in mind in the future. Welcome to SO.

Related

Recursion/Lists in Racket

I am trying to make the function remove-member, where I have a list of strings and I give one of the members of the string (i.e. "A") to the function, and it removes that member and returns the rest of the list without that member. At the moment I have created tests and started my function, but I am lost beyond that. I know recursion functions include the first member of the list and the rest of it, but how would I remove the first member of a string?
(define str (list->string (list 'A 'B 'C)))
(check-expect (remove-occurrences "A") (list 'B 'C))
(check-expect (remvove-occurrences '()) (list 'A 'B 'C))
(define (remove-occurrences r)
(cond
[(empty? r) str]
[(??? r)]))
To remove a single element from a list:
Is the list empty? If it is, we're done and the result is the empty list.
OK, it's not empty. Is the first element of the list the same as the element you want to remove? If it is then the result is the rest of the list.
OK, it's not empty, and the first element didn't match. So the answer is a list consisting of a cons of the first element and the result of removing the element from the rest of the list. Which you now know how to do.
Alternatively, to remove all occurrences of an element from a list:
Is the list empty? If it is, we're done and the result is the empty list.
OK, it's not empty. Is the first element of the list the same as the element you want to remove? If it is then the result is the the result of removing all occurrences of the element from rest of the list, which you know how do to now.
OK, it's not empty, and the first element didn't match. So the answer is a list consisting of a cons of the first element and the result of removing the element from the rest of the list. Which you now know how to do.
How these functions differ:
> (remove-one '(a b b c) 'b)
'(a b c)
> (remove-all '(a b b c) 'b)
'(a c)
Let's follow the data type.
This way we get the mundane tasks taken care of automatically for us, and get to focus our creative mental abilities on more interesting, less common aspects of our problem:
(define (list-p ad)
(cond
((null? ad) ; follow
#t)
((pair? ad)
(let ((a (car ad)) ; the
(d (cdr ad))) ; type!
(list-p d)))
(else #f)))
We can see this predicate as a constructor of Boolean values. Creating a list following the same example aka skeleton code is also easy:
(define (list-l ad)
(cond
((null? ad) ; return proper
(list)) ; type here, and
((pair? ad)
(let ((a (car ad))
(d (cdr ad)))
(list-l d))) ; here
(else #f)))
We've just followed the type's skeleton code, mended it in the few appropriate places, and got ourselves a working code which creates values of the proper type, all by itself!
But does it create any interesting value, fully using the supplied argument? Evidently, not. For that we must mend the recursive call:
(define (list-copy ad)
(cond
((null? ad)
(list))
((pair? ad)
(let ((a (car ad))
(d (cdr ad)))
(cons ... ; here
(list-copy d))
))
(else #f)))
Now you get to tweak this further, consing the first element of a pair conditionally, as required by your problem.
(note: null? could be called empty? in your dialect).

Counting in Scheme without recursion?

So, I have a homework assignment that is asking me to make a function that counts the number of elements in a list without using recursion. (Which seems crazy to me, since Scheme is all about recursion from what I've learned so far, but that's a different discussion.) We're also not allowed to use the built-in length function.
I'm assuming this involves map somehow, but beyond that, I'm stuck, and everything I've googled for help offers a recursive solution (or uses !set, which the class hasn't taught us about and which I'm assuming is not the answer they're looking for).
If you take a rather fussy definition of recursion: a function is recursive iff it calls its own name, either directly or indirectly, then you can write things which are not 'recursive' in this very limited sense, by, really, noting that functions that don't have names can't be recursive (again: in this limited sense).
So you can start with this slightly odd function:
(λ (f)
(λ (l)
(if (null? l)
0
(+ 1 ((f f) (cdr l))))))
This is a function which takes another function, f as an argument and returns a function which takes a list as an argument and which:
if the list is empty will correctly compute its length;
if the list is not empty, then if (f f) is a function which will correctly compute the length of the cdr of the list, this function will compute the length of the whole list, by adding one to it.
So, wait: this function, if given another function which, when called with itself as an argument, will return a function which will compute the length of the rest of a list, will compute the length of a list. That means that this function itself is a candidate for this f function: when called with itself as an argument it should return a function which computes the length of a list. So, OK, we can wrap it up a bit to make this proposed length-computing function:
((λ (g)
(g g))
(λ (f)
(λ (l)
(if (null? l)
0
(+ 1 ((f f) (cdr l)))))))
Should be a function which computes the length of a list. And we can try it:
> (((λ (g)
(g g))
(λ (f)
(λ (l)
(if (null? l)
0
(+ 1 ((f f) (cdr l)))))))
'(1 2 3))
3
Well, it does seem to compute the length of the list. So we can, finally, give this thing a name to make it easier to call:
(define list-length
((λ (g)
(g g))
(λ (f)
(λ (l)
(if (null? l)
0
(+ 1 ((f f) (cdr l))))))))
And now
> (list-length '())
0
> (list-length '(a b c d))
4
OK.
So, conventionally, this is done by giving the thing that applies a function to itself a name: it's the U combinator:
(define U
(λ (f) (f f)))
And then we can rewrite list-length in terms of U:
(define list-length
(U (λ (f)
(λ (l)
(if (null? l)
0
(+ 1 ((U f) (cdr l))))))))
And the question is: is list-length recursive? Well, maybe?

Why is my lisp function giving me this output?

I am writing a function that will take a list from a user and will flatten this list into one simplified list. The function seems to only return the first item on the list and not the rest? Any suggestions on why it is doing this?
Example:
> (flatten '(a () b (c d))
(a b c d)
This is what I have so far
(defun flatten (list)
(cond
((null list)t)
(list (first list) (rest list))
(t(append (flatten (first list))
(flatten (rest list)))
(t(cons (first list (flatten (rest list))))))))
The output it is giving
> (flatten '(a () b (c d)))
(NIL B (C D))
You are editing the original question with updated code, which makes it a moving target. Currently, your code is the following one, after I ask Emacs to indent it with M-q (lisp-mode):
(defun flatten (list)
(cond
((null list)t)
(list (first list) (rest list))
(t (append (flatten (first list))
(flatten (rest list)))
(t (cons (first list (flatten (rest list))))))))
;; ^^^ Something is not good, why is the clause indented?
Parentheses structure the code for the computer, whereas indentation is a way to print this structure for human readers. This redundancy allows you to detect problems in source code when one does not match the other. Here, the (t cons) is not a cond clause, it is nested inside the previous clause.
Second, as said in comments, cond will go to the first clause for which the test succeeds. If you wrote (cond (t X) ...), nothing in the ... part would change the meaning of the code, which always returns X. In your code, you test as follows:
(null list) tests whether list is eq to nil.
list does not test whether list is a list. There is a predicate named listp to detect that. When you put list alone like this, you are asking whether list is a generalized true value, which is necessarily true when you previously ruled out nil (the previous clause).
The default clause (t ...) has no way to be used, because the previous test cannot fail.
Here is a skeleton:
(defun flatten (form)
(cond
((null list) ...)
((consp list) ...)
(t ...)))
Instead of consp you could write listp, but note that by definition a list is either nil or a cons cell, so consp is a little more explicit and does not overlap with a test for nil. Note also that I always test against the type of form, which is a pattern that is often found. That's why you might prefer to use typecase.

Insertion into a list doesn't reflect outside function whereas deletion does?

I am new to Lisp. Deletion of an item in a list by a function gets reflected outside the function but insertion doesn't. How can I do the same for insertion?
For example
(defun test (a b)
(delete 1 a)
(delete 5 b)
(append '(5) b)
(member '5 b))
(setq x '(2 3 1 4))
(setq y '(8 7 5 3))
(test x y)
;;x and y after function ends
x
(2 3 4)
y
(8 7 3)
Why doesn't append affect list y? How can I insert something into y from within the function?
Append isn't supposed to modify anything
Why doesn't append affect list y?
The first sentence of the documentation on append is (emphasis added):
append returns a new list that is the concatenation of the copies.
No one ever said that append is supposed to modify a list.
You can't change the value of a lexical binding outside its scope
How can I insert something into y from within the function?
In the most general sense, you cannot. What happens if the value of y is the empty list? There's no way with a function (as opposed to a macro) to make something like this work in Common Lisp:
(let ((list '())
(insert list 1)
l)
;=> (1)
A function cannot change the lexical binding of a variable outside its scope1, so there's no way for insert to change the value of list.
You can, of course, modify the internal structure of an object, so if the value of list is some non-empty list, then you could modify the structure of that list. The value of list wouldn't change (i.e., it would still the same cons cell), but the list represented by that cons cell would change. E.g.,
(defun prepend (list element)
(let ((x (first list)))
(setf (rest list) (list* x (rest list))
(first list) element)))
(let ((list (list 1 2)))
(prepend list 'a)
list)
;=> (a 1 2)
Save return values
In general, you need to get into the habit of saving the results of functions. Most functions won't modify their arguments, so you need to save their results. Some functions are permitted, but not required, to modify their arguments, and they don't have to modify in a predictable way, so you need to save their results too. E.g., your code could be:
(defun test (a b)
(setf a (delete 1 a))
(setf b (delete 5 b))
(setf b (append '(5) b))
(member 5 b))
(test ...)
;=> true
1 You could work around this by giving it a setter function that closed over the binding, etc. But those kind of techniques would be workarounds.

Lisp Exercises Involving List Manipulation

I trying to complete this exercise;
Write a Lisp function that takes as input a list of elements, such as (A B C)
, and returns a list in which the position of each element follows it, such as (A 1 B 2 C 3)
I'm trying to do it with two functions, however its not working correctly, I'm just getting the same list. Here is my code:
(defun insert (index var userList)
(if (or (eql userList nil) (eql index 1))
(cons var userList)
(cons (car userList) (insert (- index 1) var (cdr userList)))))
(defun insertIndex (userList)
(setq len (length userList))
(loop for x from 1 to len
do (insert x x userList)))
The insert functions seems to work fine on its own, but it seems like it doesn't do anything with loop. I'm new lisp and any help would be appreciated, thanks in advance.
Positions in Lisp start with 0. In insertIndex the variable len is not defined. The LOOP does not return any useful value.
If you want to solve it with recursion, the solution is much simpler.
You need to test for the end condition. If the list is empty, return the empty list.
Otherwise create a new list with the FIRST element, the current position and the result of calling the function on the rest of the list and the position increased by one.
(LIST* 1 2 '(3 4)) is shorter for (cons 1 (cons 2 '(3 4))).
Here is the example with a local function. To create a top-level function with DEFUN is now your task. You only need to rewrite the code a bit. LABELS introduces a potentially recursive local function.
(labels ((pos-list (list pos)
(if (null list)
'()
(list* (first list)
pos
(pos-list (rest list) (1+ pos))))))
(pos-list '(a b c d e f) 0))
The main problem with your insertIndex function is that the do clause of loop is for side-effects only, it doesn't change the return value of the loop. (And your insert is side-effect free.) The right loop clause to add elements to a list return value is collect. (There are also append and nconc to join multiple lists.)
This is a working function:
(defun insert-index (list)
(loop for elt in list and i from 1
collect elt
collect i))
Your whole expectations about the behaviour of the insert and insertIndex functions seem to be flawed. You need to get a clearer mental model about which functions are side-effecting, which are not, and whether you need side-effects or not to solve some particular problem.
Also, you shouldn't call setq on an undefined variable in Common Lisp. You need to first use let to introduce a new local variable.
Minor points: CamelCase is very unidiomatic in Lisp. The idiomatic way to seperate words in identifiers is to use dashes, like I did in my code example. And you don't need to do (eql something nil), there's the special null function to check if something's nil, e.g. (null something).