(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.
Related
I am new to LISP and was wondering how to return a list from a function.
I need to write a function that takes a list as an input and outputs a list.
If first and last elements are even numbers:
return a list with first ** 2 and last ** 4
else
return a list with first and last elements
How do I return a list correctly?
(defun test (elements)
(if (and (numberp (nth 0 elements))
(numberp (last elements)))
(if (and (evenp (nth 0 elements))
(evenp (last elements)))
(return from test (list (expt (last elements) 2) (expt (nth 0 elements) 4)))
)
)
(return from test (list (nth 0 elements) (last elements)))
)
Example:
(cond ((foo-p n) (list 1 2)) ; returns the list
((bar-p m) (list 3 4)) ; returns the list
(t (list 5 6))) ; returns the list
or
(if (foo-p n)
(list 1 2) ; returns the list
(if (bar-p m)
(list 3 4) ; returns the list
(list 5 6))) ; returns the list
A list is a chain of pairs. eg. (1 2 3) is created with (cons 1 (cons 2 (cons 3 '()))). If you know this in your heart it will be much easier to do list processing.
Because of the structure fo a list a list is created from end to beginning and iterated from beginning to end.
Eg. replacing first element is easy. You (cons (do-something (car elements)) (cdr elements)) and you have a list with the first element changed. You could do the same with (reverse elements) to alter the last element before reversing it again. Put these two together and you have a solution.
No return is necessary. eg. if the body if a function is as follows the argument will get a new element in the beginning if some-expr is truthy and the argument if it is not.
(if some-expr
(cons 3 elements)
elements)
Every part of lisp works like this. An expression can be seen as computing a returned value. eg. some-expr returns a value that is evaluated by if. Eg. it's not the function scope you are exiting, but each level of an expression as well.
I am trying to write a function in Racket that will reverse the order of pairs. For example, given the list '(1 2) the function should produce '(2 1). Here is my code so far:
(define (reverse aList)
(cons (second aList)
(first aList))
This is not producing the correct answer, however. When I test with '(a b) it returns '(b . a) instead of '(b a). How do I get rid of the period between the b and a?
You should have:
(define (reverse-pair lst)
(cons (second lst) (cons (first lst) empty)))
As stated in Racket's docs:
The cons function actually accepts any two values, not just a list for the second argument. When the second argument is not empty and not itself produced by cons, the result prints in a special way. The two values joined with cons are printed between parentheses, but with a dot (i.e., a period surrounded by whitespace) in between.
So,
> (cons 1 2)
'(1 . 2)
> (cons 1 (cons 2 empty)) ; equivalent to (list 1 2)
'(1 2)
I am struggling to find the right approach to solve the following function
(FOO #'– '(1 2 3 4 5))
=> ((–1 2 3 4 5) (1 –2 3 4 5) (1 2 –3 4 5) (1 2 3 –4 5) (1 2 3 4 –5))
The first Parameter to the foo function is supposed to be a function "-" that has to be applied to each element returning a list of list as shown above. I am not sure as to what approach I can take to create this function. I thought of recursion but not sure how I will preserve the list in each call and what kind of base criteria would I have. Any help would be appreciated. I cannot use loops as this is functional programming.
It's a pity you cannot use loop because this could be elegantly solved like so:
(defun foo (fctn lst)
(loop
for n from 0 below (length lst) ; outer
collect (loop
for elt in lst ; inner
for i from 0
collect (if (= i n) (funcall fctn elt) elt))))
So we've got an outer loop that increments n from 0 to (length lst) excluded, and an inner loop that will copy verbatim the list except for element n where fctn is applied:
CL-USER> (foo #'- '(1 2 3 4 5))
((-1 2 3 4 5) (1 -2 3 4 5) (1 2 -3 4 5) (1 2 3 -4 5) (1 2 3 4 -5))
Replacing loop by recursion means creating local functions by using labels that replace the inner and the outer loop, for example:
(defun foo (fctn lst)
(let ((len (length lst)))
(labels
((inner (lst n &optional (i 0))
(unless (= i len)
(cons (if (= i n) (funcall fctn (car lst)) (car lst))
(inner (cdr lst) n (1+ i)))))
(outer (&optional (i 0))
(unless (= i len)
(cons (inner lst i) (outer (1+ i))))))
(outer))))
Part of the implementation strategy that you choose here will depend on whether you want to support structure sharing or not. Some of the answers have provided solutions where you get completely new lists, which may be what you want. If you want to actually share some of the common structure, you can do that too, with a solution like this. (Note: I'm using first/rest/list* in preference to car/car/cons, since we're working with lists, not arbitrary trees.)
(defun foo (operation list)
(labels ((foo% (left right result)
(if (endp right)
(nreverse result)
(let* ((x (first right))
(ox (funcall operation x)))
(foo% (list* x left)
(rest right)
(list* (revappend left
(list* ox (rest right)))
result))))))
(foo% '() list '())))
The idea is to walk down list once, keeping track of the left side (in reverse) and the right side as we've gone through them, so we get as left and right:
() (1 2 3 4)
(1) (2 3 4)
(2 1) (3 4)
(3 2 1) (4)
(4 3 2 1) ()
At each step but the last, we take the the first element from the right side, apply the operation, and create a new list use revappend with the left, the result of the operation, and the rest of right. The results from all those operations are accumulated in result (in reverse order). At the end, we simply return result, reversed. We can check that this has the right result, along with observing the structure sharing:
CL-USER> (foo '- '(1 2 3 4 5))
((-1 2 3 4 5) (1 -2 3 4 5) (1 2 -3 4 5) (1 2 3 -4 5) (1 2 3 4 -5))
By setting *print-circle* to true, we can see the structure sharing:
CL-USER> (setf *print-circle* t)
T
CL-USER> (let ((l '(1 2 3 4 5)))
(list l (foo '- l)))
((1 . #1=(2 . #2=(3 . #3=(4 . #4=(5))))) ; input L
((-1 . #1#)
(1 -2 . #2#)
(1 2 -3 . #3#)
(1 2 3 -4 . #4#)
(1 2 3 4 -5)))
Each list in the output shares as much structure with the original input list as possible.
I find it easier, conceptually, to write some of these kind of functions recursively, using labels, but Common Lisp doesn't guarantee tail call optimization, so it's worth writing this iteratively, too. Here's one way that could be done:
(defun phoo (operation list)
(do ((left '())
(right list)
(result '()))
((endp right)
(nreverse result))
(let* ((x (pop right))
(ox (funcall operation x)))
(push (revappend left (list* ox right)) result)
(push x left))))
The base case of a recursion can be determined by asking yourself "When do I want to stop?".
As an example, when I want to compute the sum of an integer and all positive integers below it, I can do this recusively with a base case determined by answering "When do I want to stop?" with "When the value I might add in is zero.":
(defun sumdown (val)
(if (zerop val)
0
(+ (sumdown (1- val)) val)))
With regard to 'preserve the list in each call', rather than trying to preserve anything I would just build up a result as you go along. Using the 'sumdown' example, this can be done in various ways that are all fundamentally the same approach.
The approach is to have an auxiliary function with a result argument that lets you build up a result as you recurse, and a function that is intended for the user to call, which calls the auxiliary function:
(defun sumdown1-aux (val result)
(if (zerop val)
result
(sumdown1-aux (1- val) (+ val result))))
(defun sumdown1 (val)
(sumdown1-aux val 0))
You can combine the auxiliary function and the function intended to be called by the user by using optional arguments:
(defun sumdown2 (val &optional (result 0))
(if (zerop val)
result
(sumdown2 (1- val) (+ val result))))
You can hide the fact that an auxiliary function is being used by locally binding it within the function the user would call:
(defun sumdown3 (val)
(labels ((sumdown3-aux (val result)
(if (zerop val)
result
(sumdown3-aux (1- val) (+ val result)))))
(sumdown3-aux val 0)))
A recursive solution to your problem can be implemented by answering the question "When do I want to stop when I want to operate on every element of a list?" to determine the base case, and building up a result list-of-lists (instead of adding as in the example) as you recurse. Breaking the problem into smaller pieces will help - "Make a copy of the original list with the nth element replaced by the result of calling the function on that element" can be considered a subproblem, so you might want to write a function that does that first, then use that function to write a function that solves the whole problem. It will be easier if you are allowed to use functions like mapcar and substitute or substitute-if, but if you are not, then you can write equivalents yourself out of what you are allowed to use.
I am new to lisp and working on a homework problem to flatten a nested list. I have my funciton working except it needs to 'remove' dotted pairs. So given (1 (2 3) (4 . 5) ((6 7) (89))) my function should output (1 2 3 4 5 6 7 8 9).
So.. my actual question..
Given a dotted pair e.g (1 . 2), how can I get the list '(1 2)?
A cons cell is a structure that has two parts, called its car and its cdr. The pair (1 . 2) is a cons cell whose car is 1 and whose cdr is 2. Lists in Lisps are built up from cons cells and nil. How this works is described in lots of places, including the answer to Recursive range in Lisp adds a period? A list is either the empty list () (also called nil), or a cons whose car is the first element of the list and whose cdr is another list which is the rest of the list. That means that a list
(1 2)
is built of cons cells and nil as
(cons 1 (cons 2 nil))
If you've already got (1 . 2), then you can get 1 and 2 with car and cdr. You'd put them back together as just described. That is,
(let ((x '(1 . 2)))
(cons (car x) (cons (cdr x) nil)))
Alternatively, you could just use list:
(let ((x '(1 . 2)))
(list (car x) (cdr x)))
If you want to reuse the same cons cell, you could replace the cdr of the cell with (cons 2 nil). For instance (and note that we're not quoting the pair anymore, because modifying literal data is undefined behavior):
(let ((x (cons 1 2)))
(setf (cdr x) (cons (cdr x) nil))
x)
That could also be
(let ((x (cons 1 2)))
(setf (cdr x) (list (cdr x)))
x)
You could also use rplacd:
(let ((x (cons 1 2)))
(rplacd x (list (cdr x)))
x)
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
what is the ‘cons’ to add an item to the end of the list?
After watching many tutorials on lisp and searching high and low on google for answers, I still cannot figure out how to add to the end of a list in LISP.
I want my function to add 'a at the end of the list '(b c d) but I only know how to add it in front. Can someone help me use cons correctly to add 'a at the end of the list? Here is my code. Thanks in advance.
(defun AddRt (a list)
(cond
((null list)
0)
(t
(princ (cons a (cons (car list) (cdr list))))
)))
(AddRt 'a '(b c d))
Either push to last, or use nconc:
> (defparameter a (list 1 2 3))
A
> (push 4 (cdr (last a)))
(4)
> a
(1 2 3 4)
> (nconc a (list 5))
(1 2 3 4 5)
> a
(1 2 3 4 5)
note that these are destructive operators, i.e., they modify the object which is the value of a, not just the binding of a.
This is why, BTW, you should never use nconc on quoted lists, like (nconc '(1 2 3) '(4 5 6)).
PS. Note that adding to the end of a list requires its full
traversal and is thus an O(length(list)) operation. This may be a bad
idea if your lists are long, so people often use the
push/nreverse
idiom, e.g.,
(let (range)
(dotimes (i 10 (nreverse range))
(push i range)))
==> (0 1 2 3 4 5 6 7 8 9)
You may use a recursive function. Also, you should avoid using princ inside.
The following function, endcons, does exactly the same thing as cons, except the value is added at the end.
(defun endcons (a v)
(if (null v) (cons a nil) (cons (car v) (endcons a (cdr v)))))
(endcons 'a '(b c d))
Of course, you could also use append:
(append '(b c d) '(a))
See also this related question: what is the 'cons' to add an item to the end of the list?
One way is to reverse the list. Add the element to beginning of the reversed list. And then finally reverse the whole list.
Scheme code:
(define (add-to-tail l x)
(reverse (cons x (reverse l)))
But if this is an operation you need often, then I'd suggest you find a data structure other than (single linked) lists.