Make list into symbol - list

I was trying to pop an element of a list in elisp as follows,
(pop '(1 2))
but, due to my misunderstanding, that doesn't work b/c the list hasn't been internalized as a symbol. Is there an idiomatic way to do the above, or is that not a proper approach? Messing around a bit further I found I could do
(pop (progn (setq tmp '(1 2)) tmp))
but it doesn't seem right. Is there a way to make anonymous lists and modify them in place like I was trying to do?

pop is a macro
which modifies the value of its argument,
a place.
E.g.,
(defparameter *var* '(1 2 3))
(pop *var*)
==> 1
*var*
==> (2 3)
Note that what gets modified is the value of the place, not the object contained in the place.
E.g.,
(defparameter *var-1* '(1 2 3))
(defparameter *var-2* *var-1*)
(pop *var-1*)
==> 1
*var-1*
==> (2 3)
*var-2*
==> (1 2 3)
IOW, the list (1 2 3) is not modified, only the value of the variable is.
What exactly are you trying to do?

pop doesn't do what you think it does. It doesn't modify any lists. It simply rebinds the given variable with the list's cdr.
Running (macroexpand '(pop foo)) in Emacs, I get:
(car-safe (prog1 foo (setq foo (cdr foo))))
Notice the absence of any list-modification functions such as rplaca or rplacd.

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

Checking multiple outputs with one test in Racket

I am trying to use the library rackunit to do some tests.
However, I would like to check many outputs with a single test, like this:
#lang racket
(require rackunit)
(check-equal? (add1 1) (* 2 1) (- 3 1) (+ 2 0))
As you see, this test shall pass, since all outputs are 2.
However, this test fails, due to a syntax problem:
check-equal?: bad syntax in: (check-equal? (add1 1) (* 1 2) (- 3 1) (+ 2 0))
Is there a way to do this unique test with multiple procedures returning a value?
Looking at the documentation I could not find it.
If I am unable to do this, I think I will be repeating myself...
If you are just checking numbers, like Gibstick suggested, you can just use check-true and =. However, if you are not testing numbers, we need to get a little more creative.
If the objects you want to check equality on are transitive: (aka, if (equal? a b) and (equal? b c) than (equal? a c), you can just run check-equal? in a loop:
(define items (list 'items 'to 'check))
(define compare-item 'correct-item)
(for ([i (in-list items)])
(check-equal? i compare-item))
Of course, if the item equality is not transitive, then you will need to check every item with every other item. You can still do this with a loop, it just becomes a bit more complicated. However, generally speaking, equality testing on items is transitive.
You can use the more general check-true with =, since all of your values are numbers.
#lang racket
(require rackunit)
(check-true (= (add1 1) (* 2 1) (- 3 1) (+ 2 0)))

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

Scheme - Testing if argument is a list (proper or improper)

I'm very new to scheme and am trying to figure out how to define a function that tests if the parameter to that function is a list, where being a proper list doesn't matter.
I've discerned that I need to check if the argument is either the empty list or a pair. I have the empty list case working fine, but I'm not sure how to check for the pair. I'm just coming off working with prolog, so my initial thought was to do something like this:
(define list?
(lambda (ls)
(if (or (eq? ls (quote()))
(cons(car(ls) cdr(ls))))
true false)))
My thinking was that if scheme could car and cdr the parameter, then it must be a pair, and it would return true. Otherwise it would just fail.
However, passing the argument '(1 2) yields this result:
(list? '(1 2))
. . application: not a procedure;
expected a procedure that can be applied to arguments
given: (1 2)
arguments...: [none]
I don't really understand what's going on here. Additionally, I feel like my thinking as to how to make this function is flawed, but I don't really know how to correct it.
EDIT: Is the issue that (if .....) is looking for a boolean from cons?
You have right idea! But the main reason why your code is not working is that on fourth line you have wrong brackets. This is right transcription of your code:
(define list?
(lambda (ls)
(if (or (eq? ls (quote()))
(cons (car ls) (cdr ls)))
#t #f)))
But in my opinion this solution is bad for these reasons:
If you supply improper list to this procedure it will end by an error when trying to do car or cdr.
For example: (1 2 3 . 4) will end by an error.
In Scheme you have to use literals #t and #f to denote true and false.
Cons always end by "true"
It will not check entire list.
I would write that procedure like this:
(define list?
(lambda (ls)
(if (null? ls)
#t
(and (pair? ls)
(list? (cdr ls))))))
Lets try this on an example: (3 . 4). It is just pair - not a list.
The ls is (3 . 4). Is it null? No, then continue to second if branch.
Is it pair? Yes - continue in and and recursively call list? with 4
The ls is 4. Is it null? No. Again, continue to second branch.
Is it pair? No! Procedure returns #f

Add lists to a list lisp

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