Altering a list permanently in common lisp - list

I have a list that is used within a loop, and on each iteration I apply a function that will alter the list permanently (popping and adding elements). The problem is, the original list is never changed whenever it is nil. How may I solve this problem?. My code is shown below
(defun looping-func ()
(let ((queue '(2)))
(loop while (not (null queue)) do
(let ( (num (pop queue)))
(if (oddp num)
(format t "~%~A success" num)
(progn (format t "~%fail")
(add-to-list (1+ num) queue)))))))
(defun add-to-list (elem l)
(nconc l (list elem)))
The code works as intended if the list contains more than 1 element. if it contains exactly 1 element, once that element is popped and the list becomes nil, the applied changes aren't permanent to the list anymore. I suppose this is because of how nconc is defined, if the first argument is nil, just return the second one without any alteration. Any ideas on how to go about this?
PS: I know the code above is useless, but I am using the same concept for a school project that I unfortunately can't post code for.

Change
(add-to-list (1+ num) queue)
to
(setq queue (add-to-list (1+ num) queue))
You can't "extend" nil with nconc
(nconc nil . lists)
is equivalent to
(nconc . lists)
so, you need to put the result of add-to-list in queue

Don't add elements to the end of a list.
Never.
Lists in Lisp are designed in a way that adding an element to the head is cheap. Adding to the end is potentially costly.
To implement a LIFO queue you need a different implementation.
Don't alter constant literal data in source code during runtime.
Indent your code properly.

Because I assumed this to be an exercise, here's an example, which you shouldn't use in your daily practice, you should use push macro, which probably does something similar to it:
(defmacro push-example (item list)
(let ((the-list list)) ; we do this to prevent
; multiple evaluations
; of the `list' argument
`(setq ,the-list (cons ,item ,the-list))))
(defparameter *test* nil)
(push-example 'foo *test*) ;; (foo)
*test* ;; (foo)
While you didn't ask for a macro (you asked for the function), Doug's answer is technically more correct, this illustrates how you could have done it using code generation through macro. Notice how this is basically doing the same thing as your function does, except that it can encapsulate the call to setq you would have to make otherwise.

Related

Can one apply a macro to an argument list?

My goal is to be able to apply a macro to an argument list in the same way the apply primitive procedure applies a procedure to an argument list.
The list will already be evaluated at the time of application of the macro, there is no way around that and that’s fine; I am wondering if there is any way to programmatically “splice” the list into the macro application (in the same sense as with unquote-splicing). The difficulty resides in that one cannot pass the macro identifier as an argument.
One use case would be
(apply and list)
which would be equivalent to
(not (memq #f list))
to see if there is a #f in list.
Preferably this would be R7RS conformant.
One sort of hacky way would be (as suggested on reddit)
(eval (cons 'and list))
but this is not R7RS conformant, as eval must take an environment argument and it seems to me the standard doesn’t specify how to snatch the environment in effect at the call to eval.
Another half solution is the following, which only works if the list is given directly as a parenthesized sequence of values:
(syntax-rules ()
((_ identifier (val ...))
(identifier val ...)))
I'm posting this as a partial answer I found to my own question, and I'll accept it in a few days if nothing new pops up.
The following works, but only if the macro to apply is contained in a library.
(import (scheme base)
(scheme eval)
(scheme write))
(define (apply-macro mac args . libs)
(eval (cons mac args)
(apply environment libs)))
(define list '(#f #t #t #t))
(display (apply-macro 'and list '(scheme base))) ; => #f
(display (apply-macro 'and (cdr list) '(scheme base))) ; => #t
You can't do that; macros apply to syntax, transforming code fragments into other code fragments, not to values.
Even if you could do it, it would not be equivalent to applying and, since all the elements of list would be evaluated.
For instance, if you define the non-terminating procedure,
(define (forever) (forever))
then (and #f (forever)) is #f, but (apply and (list #f (forever))) would not terminate.
You cannot do this without eval. You would need to implement a procedure version of AND.
The reason it's impossible is because macro expansion is one phase and evaluation is a later phase. The list is piece of dynamic data existing only in the later phase, so a macro cannot use that.

Passing list as a function parameter and returning list from a function

I have the following code:
(defun read_coords (in)
(setq x (read-line))
(if (equalp x "0")
in
(progn
(append in (cons x nil))
(read_coords in)
)
)
)
(setq coords (read_coords (cons nil nil)))
The goal is to read lines of input and store them in a list. The problem is that the list coords remains unchanged (thus containing only NIL). What am I doing wrong?
Here is your code, with better formatting:
(defun read_coords (in)
(setq x (read-line))
(if (equalp x "0")
in
(progn
(append in (cons x nil))
(read_coords in))))
(setq coords (read_coords (cons nil nil)))
Now, what is the return value of read_coords? A function contains an implicit PROGN, hence it is the last form. Here, the last form is an IF. Depending on the outcome of the test, the return value is either in or the return value of PROGN in else position. Thus, the return value in case the test fails is the one obtained by calling (read_coords in). When the recursion eventually ends without error, it is necessarily in the then branch of the IF, which returns in. Note that in is never modified during the whole execution.
Indeed, APPEND creates a fresh list based on its inputs. In other words, the new list is the value returned by the call to APPEND, which unfortunately is never stored anywhere. The computation is done without any side-effect and its result is discarded.
You should probably do this instead:
(read_coords (append in (cons x nil)))
Thus, the new list is being passed as an argument to the recursive call.
Remarks
(setq x (read-line))
Don't use SETQ to define local variables. You need to use a LET-binding here. Otherwise you change the global lexical scope in a way that is implementation-dependent (except if you defined a global variable named x, which is bad because it goes against the naming convention of special variables, which should have *earmuffs*). Mutating a global variable inside a function makes it possibly non-reentrant, which is pretty bad.
(cons x nil)
In order to build a list with one element, just use LIST:
(list x)
Finally, note that you shoudn't use underscores in names, prefer dashes. Hence, your function should be named read-coords, or better yet, read-coordinates.
(equalp x "0")
Even though the above is correct, it might be better to use string= here, since you know READ-LINE returns a string.
Performance
You are appending a list again and again, which makes a copy for each element being read. Your code is being quadratic in time and space usage, for a task that can done with a linear algorithm.
Moreover, you are using a tail-recursive function where a simple iteration would be clearer and more idiomatic. We generally don't use tail-recursive procedures in Common Lisp because the language provides iteration control structure and because tail-merging optimization is not guaranteed to be always applied (the optimization being not mandatory (which is a good thing) does not prevent implementations to provide it, even though it might require additional declarations from the user). Better use a LOOP here:
(defun read-coordinates (&optional (input-stream *standard-input*))
(loop for line = (read-line input-stream nil nil)
until (or (not line) (string= line "0"))
collect line))
We pass an input stream in parameter, which defaults to *STANDARD-INPUT*. Then READ-LINE reads lines while ignoring errors (thanks to the first NIL). In case an error is found, like when we reach end-of-file, the returned value is NIL (thanks to the second NIL). The LOOP ends when the line being read is either NIL or equal to "0". The loop accumulates all the successive lines being read into a list.
append does not modify its arguments, i.e., since you are not using its value, you are not doing anything.
(defun read-coords (&optional accumulation)
(let ((x (read-line)))
(if (string= x "0")
(nreverse accumulation) ; done
(read-coords (cons x accumulation)))))
(defvar *coords* (read-coords))

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.

Racket - output content of a list

I have defined a list (in Racket/Scheme):
(define myList (cons 'data1 (cons 'data2 (cons 'data3 (cons 'data4 empty)))))
or
(list 'data1 'data2 'data3 'data4)
And I want to write a function that cycles through the list and outputs all values of the list.
(define (outputListData list)
(cond
[(null? list) list]
[else (getListData)]))
With what function can I cycle through the content of the list? I know one can use first & rest to get list data, but I guess that's not the right way here.
BTW: Is there a good, compact racket reference like php.net? I find the official Racket docs very confusing ...
You can use a for loop. Example:
(for ([x (list 1 2 3)])
(printf "~s -> ~s\n" x (* x x)))
There are more functional ways to do this, of course, but this way works too. You'll probably want to look at a textbook like How To Design Programs to do the recursive approach. See: http://www.ccs.neu.edu/home/matthias/HtDP2e/
dyoo's solution is nice and succinct in a Scheme like Racket that has useful iteration routines built in. Just FYI, though, your 'outputListData' is not far from being the standard recursive way to do this. You just need to change a couple of lines:
(define (outputListData list)
(cond
[(null? list) #f] ; actually doesn't really matter what we return
[else (printf "~s\n" (first list)) ; display the first item ...
(outputListData (rest list))])) ; and start over with the rest
Since this is an "imperative" kind of procedure that isn't designed to return a value, it doesn't really matter what we do with an empty list so long as we stop recurring (to avoid an infinite loop). If the list isn't empty, we output the first element and start over recursively with the rest of the list.
BTW, here's another way you could write something almost identical if you just needed a "for" loop in the middle of some other function:
(let loop ((l (list 'foo 'bar 'baz 'quux))) ; or put whatever input you need
(cond ((null? l) #f)
(else
(printf "~s\n" (first l))
(loop (rest l)))))
One way to think about this "named let" is that it defines a temporary function called loop, which works just like outputListData above. Scheme has the nice property that it won't grow the stack for "tail calls" like these, so you can always write what would be an "iterative" for or while loop in this recursive style.
I highly recommend The Little Schemer by Friedman and Felleisen for a quick intro to this style of function writing! I found it through Douglas Crockford's page here.
Edit as per comments: Use for-each
(for-each display myList)
Try this:
(void (map display myList))
Breaking it down:
(void x) causes x to be ignored instead of returned to the REPL/parent expression as a value.
(map function lst): For a list '(a1 a2 ... an) returns the list '((function a1) (function a2) ... (function an)).
So we use map to display all the items, but since we only care about the side-effect and not the return value, we call void on the returned list.
Official docs:
void
map
I think the solution that is the easiest to understand it to come up with a so called "list-eater" function. This is the way my university introduced recursion and lists in Racket. Also most books on Racket (i.e. "How To Design Programs" or "Realm Of Racket") explain it this way. This is the code:
(define my-list (list 'data1 'data2 'data3 'data4))
(define (print-list a-list-of-data)
(when (not (empty? a-list-of-data))
(print (first a-list-of-data))
(print-list (rest a-list-of-data))))
If you call the function with the example list my-list, you will get the following output:
(print-list my-list)
'data1'data2'data3'data4
The function does the following: As long as the given list is not empty, it grabs the first element of that list and passes it to the function print. Then, it tells itself to do the exact same thing with the rest of the list. (It calls itself on the rest of the list.) This second part is what they call recursion.
However, you can shorten that by using a function called map:
(define (print-list a-list-of-data)
(map print a-list-of-data))
This basically says that you want the function print to be called on each element of the given list. The output is exactly the same.
Hope it helped!