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

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

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.

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 task decomposition - global variable issues

So here is my problem (generalized to an abstract situation). It is generally an interpreter.
I have got a program that needs to parse an input list and according to its elements sequentially call some functions that need to modify variables. Functions are defined separately and chosen by (cond . Those 3 variables that I need to update contain information about current situation (exactly - robot position, maze and robot orientation). The result of previous function is used in the next function (i.e. the updated variables are used).
(define func-a ... )
(define func-b ... )
(define (main-func <maze> <orientation> <coordinates> <list with commands>)
;; here I parse the list and choose which function to call
;; output must contain (list <new-maze> <new-orientation> <new-coordinates>))
)
What scheme tools can I use to update those variables? I have considered several options:
use (define and then call set! (this is bad style cause it is not pure functional programming);
call functions from back to beginning (this won't work: I also have to check if movement is valid);
don't make those variables constant at all, try passing them as arguments to each function;
Is there any other proper way to do it?
You have to keep some state (as well as read a file), so there will not be a pure functional programming, and you have to accept some deviations.
The general approach is to keep the shared object as a local in some meta-function, say parse, and update it by calling those your function, say parse-one, parse-two, and so on.
Now you need a way to update them.
You can make them visible for parse-one and parse-two by defining them inside the scope:
(let ((state (make-state)))
(let ((parse-one (lambda () ...))
(parse-two (lambda () ...)))
....))
Or you use the return value:
(let ((state (make-state)))
...
(set! state (parse-one state))
...)
There is a third approach, called OOP. Define all of them in a single closure, so they can share some data:
(define (make-parser)
(let ((state (make-state))
(let (((parse-one (lambda () ...))
((parse-two (lambda () ...))
((get-state (lambda () state)))
(list parse-one parse-two get-state))))
(destructuring-bind (parse-one parse-two get-state) (make-parser)
...
(parse-one)
...
(get-state))
(destructuring-bind is just an easy way to destruct a list, see it's scheme implementation) But it seems to be a complicated version of the first.
Just because Scheme is considered a 'functional language' doesn't forbid you from using 'set!' - after all it exists in the language to be used. Thus there is nothing wrong with:
(define-record-type position (fields x y z))
(define robot-position (make-position 0.0 0.0 0.0))
(define update-robot-position (new-x new-y new-z)
(set! robot-position (make-position new-x new-y new-x)))
[I've chosen to define positions as invariant.]
You can chose another approach if you want but fundamentally the position of the robot changed and that change will be in your code is some fashion. Why not use the simplest, most straight-forward approach?

Altering a list permanently in common lisp

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.

Are there variables in Clojure sequence comprehensions?

I'm reading Programming Clojure 2nd edition, and on page 49 it covers Clojure's for loop construct, which it says is actually a sequence comprehension.
The authors suggest the following code:
(defn indexed [coll] (map-indexed vector coll))
(defn index-filter [pred col]
(when pred
(for [[idx elt] (indexed col) :when (pred elt)] idx)))
(index-filter #{\a} "aba")
(0 2)
...is preferable to a Java-based imperative example, and the evidence given is that it "by using higher-order functions...the functional index-of-any avoids all need for variables."
What are "idx", "elt" if they are not variables? Do they mean variables besides the accumulators?
Also, why #{\a} instead of "a"?
pred is a function - #{\a} is a set containing the character a. In Clojure, a set is a function which returns true if its argument \a is contained by it. You could also use #(= % \a) or (fn [x] (= \a x)).
As the other answer implies, "no state was created in the making of this example." idx and elt function like variables, but are local only to the for sequence comprehension, so the code is more compact, not stateful, and arguably clearer (once you're used to sequence comprehensions, at least :-) ) -- perhaps the text is not optimally clear on this point.
There are no variables in functional languages. Actually, you need distinguish variable and value. idx it's just a name bound to concrete value, and you can not reassign it (but you can rebound it to another value).
First parameter of function index-filter is predicate, that means function that return true or false. #{\a} it's a data structure set, but it also can be treated like a function. If you pass element as argument to set function it returns this argument (like true) if element exists and nil (like false) otherwise. So you can think about this set predicate as anonymous function written in more understandable way #(contains? #{\a} %)