Add lists to a list lisp - list

I'm new to Lisp and I'm having trouble figuring out how I add a list to another list. I start with an empty list, and I have to add new lists, each containing three elements. For example,
(add '(1 2 3) '())
would return ((1 2 3)) [let's call it new-list], and adding a new list to this new one, for example
(add '(4 5 6) new-list)
would return ((1 2 3) (4 5 6)) or ((4 5 6) (1 2 3))
I've tried a few different ways, but so far the closest I've come up was ((((1 2 3)) (4 5 6)) (7 8 9))
I was using something like this:
(defun add (lst new-let)
(if (null lst) '()
(setf new-lst (cons new-lst (cons lst '()))))

Have you tried :
(defun add (thing lst) (append lst (list thing)))
I haven't tried this with Common Lisp as I am more of a Scheme kind of guy, bu I think it would work.

The way I read it, your requirement is exactly cons (non destructive) or push (destructive).

You being new to LISP I'd like to give you an alternative to the accepted answer.
Lists are singly linked list chains. Such structure allows for adding and removing in front to be a constant time operation while adding or removing something from the end would take as many turns as there are elements in the list in both time and space (it will have to recreate the list structure on it's way).
(defun add (element list)
(cons element list))
This looks very familiar.. It's actually just a wrapper to cons. So lets imagine you have a practical application where you'd like to use add, but needed the elements in the order in your question. One way to do it would then be to finish up first (add whats to add), then do one reverse or nreverse (if every element was made in your function and mutation won't matter for the outside)..
(defun fetch-all (num-elements thunk &optional acc)
(if (zerop num-elements)
(nreverse acc)
(fetch-all (- num-elements 1) thunk (add (funcall thunk) acc)))); add == cons

Related

Build list in Lisp using an iterative recursive function

Super newbie in Lisp but at least I am trying so forgive me if the approach seems a bit strange.
I am open to learn new ideas but I will definitely need to learn whats wrong with my approach.
I have a function that builds a list using an iterative recursive approach.
(defun create-tree-iteratively(sub-list)
(if (equal (length sub-list) 1)
sub-list
(loop for i in sub-list
do(setq subtree (list i))
do(setq sub-sub-list (remove i sub-list))
do(append subtree (create-tree-iteratively sub-sub-list))
)
)
)
Input to my program is
'(1 2 3)
Expected output is
'((1 (2 3) (3 2)) (2 (1 3) (3 1)) (3 (1 2) (2 1)))
My loops (recursion) runs file. I have issues in combing the output of recursion appropriately.
Code style
It is preferable to not have closing parentheses on their own lines, the usual
convention in Lisp is to have parentheses grouped at the end, like so:
))).
Since cons-cells have only two slots, CAR and CDR, when they are used as a list they do not hold the
length of the list. So the only way to
compute the length is to traverse the whole chain of cells, which is exactly
what your function is already doing. If your list is of size N, you'll have to
compute the length N times, which makes the number of steps in your function proportional to N*N.
In a loop, a single DO can be followed by multiple expressions, you do not need
to repeat the DO keyword. Also, add spaces before opening parentheses.
SETQ is not supposed to be applied with unbound variables, like subtree or
sub-sub-list. You should first have a surrounding let where you introduce
local variables (e.g. around the loop), or use with clauses in your
loop. Or better, use the existing facilities of LOOP to avoid doing the mutation
yourself.
The return value of APPEND is important, since it 's the
results of appending the arguments (which are left unmodified). But here you do
not use the return value, which makes the whole expression useless.
Alternative
Instead of computing the length, it is sufficient to check whether the input
lists is empty, contains one elements or more (without counting). Also, you can
use collect to collect all trees as a list. I am not sure the result for a
singleton input list is correct, maybe it should be (list list).
(defun create-tree (list)
(if (null (rest list))
;; covers both empty list and list with a single element
list
;; otherwise, collect a list of trees
(loop
for i in list
;; collect all trees rooted at i, where a tree is a list (r c1 .. cn)
;; with R the root node and C1...CN each child tree. The child trees
;; are build recursively, with i removed from the list of values.
collect (list* i (create-tree (remove i list))))))
Some initial notes.
When asking a question which involves implementing an algorithm describe the algorithm: it is not easy to guess what you want based on a single example (below I have made two guesses).
I would guess you have written in Python previously, as your code shows significant signs of 'Python braindamage' (note this is a comment about Python, which I've spent years of my life on, not about your ability). In particular:
Lisp does not confuse forms which create new bindings (variables) with assignment the way Python does. You don't create a new binding in a function by setq you create it by some binding form such as let;
You don't add new things to the end of a list by append, you create a new list which has the new things added to it, and since lists are linked lists and not variable-length arrays in drag, append takes time proportional to the length of the list.
But in one respect your code ignores an important lesson of Python: all those group-closing markers don't matter to anyone reading the code, and you should not fill lines with single group closing (or opening) markers. They are just noise which makes reading code hard. In Python, in fact, they are so invisible they don't exist at all. This is one of the things Python got right.
That being said, here are three versions of what I think you want: the first implements what I'd think of as a consistent algorithm, the second implements what I think you may want, and the final one abstracts out the termination test & can do either (or anything else)).
(defun make-permuted-tree (l)
;; this builds the tree all the way down
(if (null l)
'()
(loop for e in l
collect (cons e (make-permuted-tree (remove e l))))))
(defun make-permuted-tree/strange (l)
;; this stops before the end
(if (null (rest l))
l
(loop for e in l
collect (cons e (make-permuted-tree/strange (remove e l))))))
(defun make-permuted-tree/general (l &key (base-test (lambda (b)
(null b))))
;; this stops where you want it to, which by default is at the end
(labels ((make-permuted-tree (lt)
(if (funcall base-test lt)
lt
(loop for e in lt
collect (cons e (make-permuted-tree (remove e lt)))))))
(make-permuted-tree l)))
As examples of these:
> (make-permuted-tree/strange '(1 2 3))
((1 (2 3) (3 2)) (2 (1 3) (3 1)) (3 (1 2) (2 1)))
> (make-permuted-tree '(1 2 3))
((1 (2 (3)) (3 (2))) (2 (1 (3)) (3 (1))) (3 (1 (2)) (2 (1))))
> (make-permuted-tree/general '(1 2 3))
((1 (2 (3)) (3 (2))) (2 (1 (3)) (3 (1))) (3 (1 (2)) (2 (1))))
> (make-permuted-tree/general '(1 2 3) :base-test (lambda (b)
(null (rest b))))
((1 (2 3) (3 2)) (2 (1 3) (3 1)) (3 (1 2) (2 1)))

What's the point of building a list with a non-list tail?

The Emacs lisp manual states about the function nconc that:
Since the last argument of nconc is not itself modified, it is reasonable to use a constant list, such as '(4 5), as in the above example. For the same reason, the last argument need not be a list
And indeed I can write
(setq x '(1 2 3))
=> (1 2 3)
(nconc x 0)
=> (1 2 3 . 0)
but that yields a totally broken list:
(length x)
=> eval: Wrong type argument: listp, 0
(butlast x)
=> butlast: Wrong type argument: listp, 0
How can I retrieve the original list? (reverse (cdr (reverse '(1 2 3 . 0)))) doesn't cut it either.
In which contexts is this a useful pattern? In the standard distribution some functions in minibuffer.el use it, in particular completion-all-completions and the like.
They're not "broken" lists; they're actually known as improper lists (as opposed to nil-terminated lists, which are proper lists). Many list functions, such as length and butlast that you just named, expect proper lists, and listp returns true only for proper lists.
Improper lists are used in association lists (where the associations are often not proper; though the alist itself must be proper).
If you want to make an improper list proper, you have two options:
Remove the "improper" element.
Treat the improper element as the last element of the proper list.
Here's a procedure I wrote called properise which will do the former:
(defun properise (x)
(let ((r nil))
(while (consp x)
(push (pop x) r))
(nreverse r)))
(If you want the latter behaviour, add (unless (null x) (push x r)) just before the nreverse line.)
Generally I would avoid creating data structures like that, where the last element is a cons cell with some object other than NIL in the cdr... It makes debugging harder, it's a hack, makes code more difficult to understand, ...
I'm still unsure why this is a good pattern, but here's an easy way of getting a proper list out of an improper one, without making a copy:
(defun nmake-proper-list (x)
(let ((y (last x)))
(setcdr y nil)
x))

Clojure - Recursive up function

Hi I'm kind of new to clojure and I'm trying to write a function called up that removes a pair of parentheses from each top level element of a list. If the top level element is not a list, then it is added as well. For example,
>(up '((1 2) (3 4)))
(1 2 3 4)
>(up '(x (y) z))
(x y z)
Right now, I'm having a problem with the function ending too soon if I'm trying to remove one pair of parentheses. I want to do this recursively and without the help of other functions if possible. What I have at the moment:
(defn up [lst]
(if (empty? lst)
()
(if (list? (first lst))
(up (first lst))
(cons (first lst) (up (rest lst))))))
I know that the problem is that I am cons-ing an empty list with the last element of a nested list which ends my function, but I can't figure out how else to do it.
Diego's comment seems to indicate there were other answers here, but I don't see them now, so here goes...
Your function ends too soon because, when it hits an item that is itself a list, it recursively calls up on that item and ignores the rest of the items in the original list. (up (first lst))
The minimal change to your code would be to, instead, recursively call up on the concatenation of that first list item and the rest of the list. (up (concat (first lst) (rest lst)))
Even better would be to use the existing core function flatten instead of up.
On a side note, you would generally want to achieve recursion using recur instead of calling up directly, in order to avoid a stack overflow for large input lists.

Scheme list always in reverse order

Probably a trivial question for most of the more advanced schemers here, but as a newcomer, I've found this to be a problem.
I need a way to construct a new list that is in the same order it was when it came in. As an example, say we are given a list '(1 2 0 3 4 0 0 5). But traversing the list and passing the cdr back as the 1st argument ends up constructing the new list backwards.
Here's an example in code:
I pass it an "old-list" that needs work done on it and an empty list as "new-list" to be formed and returned.
note that taking 0s out is just here as "some condition" that the new list must meet
(define (form-new-list old-list new-list)
(cond ((null? old-list) new-list)
(else
(if (eq? (car old-list) 0) (form-new-list (cdr old-list) new-list)
(form-new-list (cdr old-list) (cons (car old-list) new-list))))))
;test
(form-new-list '(1 2 0 3 4 0 0 5) '()) ; gives (5 4 3 2 1)
;but want (1 2 3 4 5)
I DO NOT just want to reverse the list that is returned with a reverse procedure, but rather, want the new list to be put together in the correct order in the first place.
Is there some kind of "trick" to this, like making the recursive call somewhere else perhaps?
Any advice is greatly appreciated.
You're looking for the natural way to traverse a list using recursion. Use this procedure as a template for your solution - it simply copies a list exactly as it is received:
(define (copy lst)
(if (null? lst)
'()
(cons (car lst)
(copy (cdr lst)))))
Notice the following points:
The recursion ends when the input list is null, and given that we're building a new list, the correct value to return is the null list
We're interested in building a new list, we do this by consing a new element for the output list, which in this case happens to be the first element of the input list (its car part)
Finally, the recursive step advances by invoking the procedure with the rest of the input list (its cdr part)
As usual, I end up my answers to people learning how to think recursively by recommending you take a look at either The Little Schemer or How to Design Programs, both books will teach you how to grok recursive processes in general, using Scheme.

Trying to reverse a list in Scheme

Be forewarned: this is a homework problem. I'm trying to write a Scheme function that reverses a list. '(1 2 3) becomes '(3 2 1), etc. I'm not allowed to use the predefined function that does this.
Am I on the right track with what I wrote here?
;myReverse
(define (myReverse list)
(if (null? list) '()
(append (myReverse(cdr list)) car list)))
Thanks!
Well, using list as an name is going to be odd, since Scheme is a Lisp-1. Call it lst instead.
Think about what you can do with foldl, cons, '(), and lst.
Am I on the right track with what I wrote here?
Yes. Some things to consider:
list is a built-in function name, and one you might actually want to use in this solution, so you probably shouldn't name your formal that
You forgot the parentheses around car list
append expects two lists; you're passing it a list and a number
> (append '(1) 2)
(1 . 2)
> (append '(1) '(2))
(1 2)