Not retrieving the character at an index of a list correctly? - global-variables

I am writing a program that recursively iterates through a list, provided the index of the current character and a list of characters. However, when I run the following program:
(defun printAllElementsRecursively (index providedList)
(if (>= index (length providedList))
(return-from printAllElementsRecursively NIL)
)
(defvar currCharacter (nth index providedList))
(print (format nil "Character at index ~a: ~a" index currCharacter))
(printAllElementsRecursively (+ index 1) providedList)
)
(printAllElementsRecursively 0 '(A B B A))
I get the following output:
"Character at index 0: A"
"Character at index 1: A"
"Character at index 2: A"
"Character at index 3: A"
This seems strange, considering that the value of index does increment correctly.

You are misusing defvar:
It should never be used inside a function, use let instead or just (nth index providedList) instead of currCharacter.
It defines a new global variable, and only sets it if it has not been set yet, so it sets
currCharacter once only.
You also do not really need return-from, and your code
would be more readable if use used dashes instead of camel case.
E.g.,
(defun print-list-elements-recursively (list)
(when list
(print (first list))
(print-list-elements-recursively (rest list))))
Also, nth is linear in its list argument's length,
so your function is quadratic in it (my version is linear).

Related

Problem while defining variables in racket

I am trying to create a recursive function which picks n items from a list returning the picked values and the list without the values, but when I create my variables I get this error:
new-list: unbound identifier in: new-list
Here is my code:
(define(pick-randomr list n picked) ;;Picked always called as empty list
(if(= n 0) (values list picked)
((let* ([aux list]
[r (random (length aux))]
[value (list-ref aux r)]
[new-picked (cons value picked)]
[new-list (values (remove value aux))])
(values aux r new-list))
(pick-randomr new-list (- n 1) new-picked))))
EDIT:
The line that goes:
(values aux r new-list)
is just to not have an empty body
There are a couple of problems with your syntax:
You should not use list as a parameter name, it conflicts with a built-in procedure of the same name.
Don't surround let* with two brackets, that's a common mistake, brackets are not like curly braces in other languages, you must not use them to define a block of statements, use begin for that - but we don't need it in this particular case.
The first error you got stated that you must not define a let* with an empty body. But the expression you added there isn't right, you must write the expressions that use the variables inside the let*, otherwise the new-list variable won't be visible.
This is what you meant to write:
(define (pick-randomr lst n picked)
(if (= n 0)
(values lst picked)
(let* ([aux lst]
[r (random (length aux))]
[value (list-ref aux r)]
[new-picked (cons value picked)]
[new-list (values (remove value aux))])
(pick-randomr new-list (- n 1) new-picked))))
Let's test it:
(pick-randomr '(1 2 3 4 5) 2 '())
=> '(1 2 5)
'(3 4)

Variable Not A Number Error in Lisp (Which is not true)

I have a code which takes a list and returns all possible permutations by the parameter result.
But when I compile I have an error which says *** - =: (1+ INDEX) is not a number.
Is this message true or I messed up the code generally?
I am new to lisp I can looking for a fix and also open to suggestions from fucntional programmers.
;; Creates permutatiions of a given list and returns it via parameter
(defun create-permuations (source)
(setf result (list))
(create-permuations-helper source 0 '() result)
result)
(defmacro create-permuations-helper (source index cur result)
(if (= (list-length cur) index)
(cons cur result)
(loop for i from 0 to (list-length cur) do
(create-permuations-helper source (1+ index)
(append cur (list (nth i source))) result))))
99% of times when a compiler reports an error you can trust it to be true. Here Index is the list (1+ index), literally the 1+ symbol followed by the index symbol. This is so because you are using a macro, and macros operate on code.
In your macro, you do not return a form to be evaluated, you execute code during macro-expansion that depends on itself. That alone is an undefined behaviour. For example:
(defmacro a (x)
(if (plusp x)
(a (- x 1))
nil))
In the body of a, you want to expand code using a recursive call to itself. But the macro is not yet fully known and cannot be until the whole macro is defined.
Maybe the particular lisp implementation binds a to the macro function in body of the macro, which is a strange thing to do, or you evaluated the definition twice. The first time the compiler assumes a is an unknown function, then binds a to a macro, and the second time it tries to expand the macro.
Anyway macro are not supposed to be recursive.
In the example, since the macro does not evaluate its argument, the nested call to the macro is given the literal expression (- x 1), and not its actual value, which cannot be known anyway since x is unknown. You are crossing a level of abstraction here by trying to evaluate things at macroexpansion time.
But, macros can expand into code that refers to themselves.
(defmacro a (x)
(if (plusp x)
`(b (a ,(- x 1)))
nil))
Now, (a 2) expands into (b (a 1)), which itself macroexpands into (b (b (a 0))), and finally reaches a fixpoint which is (b (b nil)).
The difference is that the macro produces a piece of code and returns, which the compiler macroexpands again, whereas in the first example, the macro must already be expanded in the body of its own definition.
Possible implementation
One way to solve your problem is to define a local function that has access to a variable defined in your main function. Then, the local function can set it, and you do not need to pass a variable by reference (which is not possible to do):
(defun permut (list)
(let (result)
(labels ((recurse (stack list)
(if list
(dolist (x list)
(recurse (cons x stack)
(remove x list :count 1)))
(push stack result))))
(recurse nil list))
result))
Alternatively, you can split the process in two; first, define permut-helper, which is a higher-order function that takes a callback function; it generates permutations and calls the callback for each one:
(defun permut-helper (stack list callback)
(if list
(dolist (x list)
(permut-helper (cons x stack)
(remove x list :count 1)
callback))
(funcall callback stack)))
You call it with a function that pushes results into a list of permutations:
(defun permut (list)
(let (result)
(flet ((add-result (permutation)
(push permutation result)))
(permut-helper nil list #'add-result))
result))

LISP Cannot take CAR of T

I am trying to evaluate each atom of a list and see if it's equal to the number provided and remove if its not but I am running into a slight problem.
I wrote the following code:
(defun equal1(V L)
(cond((= (length L) 0))
(T (cond( (not(= V (car(equal1 V (cdr L))))) (cdr L) )))
)
)
(equal1 5 '(1 2 3 4 5))
I obtain the following error
Error: Cannot take CAR of T.
If I add (write "hello") for the action if true, the following error is obtained:
Error: Cannot take CAR of "hello".
I'm still quite new to LISP and was wondering what exactly is going on and how could I fix this so I could evaluate each atom properly and remove it if its not, thus the cdr L for the action.
car and cdr are accessors of objects of type cons. Since t and "hello" are not cons you get an error message.
To fix it you need to know what types your function returns and not car unless you know that it's a cons
EDIT
First off ident and clean up the code.. The nested cond are uneccesary since cond is a if-elseif-else structure by default:
(defun remove-number (number list)
(cond ((= (length list) 0)
t)
((not (= number (car (remove-number number (cdr list)))))
(cdr list))))
(t
nil)))
I want you to notice I've added the default behaviour of returning t when a consequent is not given as we know = returns either t or nil so it returns t when the length is 0 in this case.
I've added the default case where none of the two previous predicates were truthy and it defaults to returning nil.
I've named it according to the functions used. = can only be used for numeric arguments and thus this will never work on symbols, strings, etc. You need to use equal if you were after values that look the same.
Looking at this now we can see that the functions return value is not very easy to reason about. We know that t, nil and list or any part of the tail of list are possible and thus doing car might not work or in the case of (car nil) it may not produce a number.
A better approach to doing this would be:
check if the list is empty, then return nil
check if the first element has the same numeric value as number, then recurse with rest of the list (skipping the element)
default case should make cons a list with the first element and the result fo the recursion with the rest of the list.
The code would look something like this:
(defun remove-number (number list)
(cond ((endp list) '())
((= (car list) number) (remove-number ...))
(t (cons ...))))
There are a couple of things you could do to improve this function.
Firstly, let's indent it properly
(defun equal1 (V L)
(cond
((= (length L) 0))
(T (cond
((not (= V (car (equal1 V (cdr L))))) (cdr L))))))
Rather than saying (= (length l) 0), you can use (zerop (length l)). A minor sylistic point. Worse is that branch returns no value. If the list L is empty what should we return?
The issue with the function is in the T branch of the first cond.
What we want to do is
remove any list item that is the same value as V
keep any item that is not = to V
The function should return a list.
The expression
(cond
((not (= V (car (equal1 V (cdr L))))) (cdr L)))
is trying (I think) to deal with both conditions 1 and 2. However it's clearly not working.
We have to recall that items are in a list and the result of the equal function needs to be a list. In the expression above the result of the function will be a boolean and hence the result of the function call will be boolean.
The function needs to step along each element of the list and when it sees a matching value, skip it, otherwise use the cons function to build the filtered output list.
Here is a skeleton to help you out. Notice we don't need the embedded cond and just have 3 conditions to deal with - list empty, filter a value out, or continue to build the list.
(defun equal-2 (v l)
(cond
((zerop (length L)) nil)
((= v (car l)) <something goes here>) ;skip or filter the value
(t (cons (car l) <something goes here>)))) ;build the output list
Of course, this being Common Lisp, there is a built-in function that does this. You can look into remove-if...

Does FORMAT provide a counter for lists iteration

I often want to output lists and also print their position in the list e.g.
'(a b c) would become "1:A 2:B 3:C"
As FORMAT already supports iterating over a given list, I was wondering whether it also provides some sort of counting directive?
E.g. the FORMAT string could look like this: "~{~#C:~a~}" whereas ~#C would be the counter.
If you want a boring answer, here you go:
(format T "~:{~a:~a ~}" (loop for i from 0 for e in '(x y z) collect (list i e)))
And now for a more interesting one! Similarly to #Renzo's answer, this uses the Tilde directive to achieve its work.
(defvar *count* 0)
(defvar *printer* "~a")
(defun iterate-counting (stream arg c at)
(declare (ignore c))
(let ((*count* (if at -1 0)))
(destructuring-bind (*printer* delimiter &rest args) arg
(format stream (format NIL "~~{~~/iterate-piece/~~^~a~~}" delimiter) args))))
(defun iterate-piece (stream arg &rest dc)
(declare (ignore dc))
(incf *count*)
(format stream *printer* *count* arg))
This uses two special variables to make it both thread-safe and to allow nesting. I won't say that it's handy to use though. The first item of the argument to list has to be a format string that denotes how to print the argument and counter. For such a format list, the first argument is the counter, and the second argument is the actual item to list. You can switch those around if you need to using the asterisk directive. The second item should be a string to print as the delimiter between each item. Finally, the rest of the list has to be the actual items to print.
(format T "~/iterate-counting/" '("~a:~a" " " x y z))
=> 1:X 2:Y 3:Z
(format T "~/iterate-counting/" '("~a:~/iterate-counting/" " " ("~a>~a" "," 0 1 2) ("~a>~a" "," a b c) ("~a>~a" "," x y z)))
=> 1:1>0,2>1,3>2 2:1>A,2>B,3>C 3:1>X,2>Y,3>Z
If you want it to start counting from zero, add an # modifier to the iterate-counting:
(format T "~#/iterate-counting/" '("~a:~a" " " x y z))
=> 0:X 1:Y 2:Z
I wouldn't personally use this, as it's far less than obvious what is going on if you stumble across the directive uninitiated. It would probably be much less confusing for the potential future reader to write a tailored function for this, than trying to ab/use format.
A not so simple but reusable way of producing a numbered list is by using the ~/ directive (Tilde Slash: Call Function) with a user-defined function. For instance:
(let ((position 0))
(defun init-pos(str arg col at)
(declare (ignore str arg col at))
(setf position 0))
(defun with-pos(str arg col at)
(declare (ignore col at))
(format str "~a:~a" (incf position) arg)))
and then write format like this one:
(format nil "~/init-pos/~{~/with-pos/~^ ~}" nil '(a b c))
Note that, as said in a comment, this solution has two limitations:
You cannot use it if you need to format objects in concurrent threads, and
you cannot use it for nested lists.

Lisp: How to print out the recursive function to print each item in the list and sublist without quotes and return the number of items?

I want my function to print each item in the list and sublist without quotes and return the number of items. The output of the list also needs to be in order, but my function is printing in reverse. I'm not sure why, is there any reasons why? Any suggestions to how I can recursively count the number of items and return that number? In addition why is the last item printed is supposed to be 9.99 instead of 100.999?
Edit: Thanks for the help so far. Just last question: Is there a way to make any output like DAY to be in lower case (day), or is that something that can't be done?
My function:
(defun all-print (inlist)
(cond
((not (listp inlist))
(format t "Error, arg must be a list, returning nil")
())
((null inlist) 0)
((listp (car inlist))
(ffn (append (car inlist)(cdr inlist))))
(t
(format t "~a " (car inlist) (ffn (cdr inlist))))))
My output example:
CL-USER 1 > (all-print (list 5 "night" 3 (list 9 -10) (quote day) -5.9 (* 100.999)))
100.999 -5.9 DAY -10 9 3 night 5
NIL
What it's suppose to output example:
5 night 3 9 -10 day -5.9 9.99 ;print
8 ;returns
It looks like all-print is supposed to be called ffn, since it looks like those are supposed to be recursive calls. In the rest of this answer, I'm just going to use ffn since it's shorter.
Why the output is in reverse
At present, your final cond clause makes the recursive call before doing any printing, because your recursive call is an argument to format:
(format t "~a " (car inlist) (ffn (cdr inlist)))
; ------------ -----------------
; 3rd 4th
All the arguments to format, including the 4th in this case, are evaluated before format is called. The 4th argument here will print the rest of the list, and then format will finally print the first element of the list. Your last cond clause should do the printing, and then make the recursive call:
(cond
…
(t
(format t "~a " (car inlist))
(ffn (cdr inlist))))
Why you get 100.999 rather than 9.99
You're getting 100.999 in your output rather than 9.99 (or something close to it) because the value of (* 100.999) is simply the value of 100.999. I'm guessing that you wanted (* 10 0.999) (note the space between 10 and 0.99). That still won't be quite 9.99 because of floating point arithmetic, though, but it will be close.
How to get the number of elements printed
uselpa's answer provides a good solution here. If you're supposed to return the number of elements printed, then every return value from this function should be a number. You have four cases,
not a list — returning nil is not a great idea. If this can't return a number (e.g., 0), then signal a real error (e.g., with (error "~A is not a list" inlist).
inlist is empty — return 0 (you already do)
(car inlist) is a list — here you make a recursive call to ffn. Since the contract says that it will return a count, you're fine. This is one of the reasons that it's so important in the first case (not a list) that you don't return a non-number; the contract depends on every call that returns returning an number.
In the final case, you print one item, and then make a recursive call to ffn. That recursive call returns the number of remaining elements that are printed, and since you just printed one, you need to add one to it. Thus the final cond clause should actually be something like the following. (Adding one to something is so common that Common Lisp has a 1+ function.)
(cond
…
(t
(format t "~a " (car inlist))
(1+ (ffn (cdr inlist))))) ; equivalent to (+ 1 (ffn (cdr inlist)))
A more efficient solution
We've addressed the issues with your original code, but we can also ask whether there are better approaches to the problem.
Don't append
Notice that when you have input like ((a b c) d e f), you create the list (a b c d e f) and recurse on it. However, you could equivalently recurse on (a b c) and on (d e f), and add the results together. This would avoid creating a new list with append.
Don't check argument types
You're checking that the input is a list, but there's really not much need to do that. If the input isn't a list, then using list processing functions on it will signal a similar error.
A new version
This is somewhat similar to uselpa's answer, but I've made some different choices about how to handle certain things. I use a local function process-element to handle elements from each input list. If the element is a list, then we pass it to print-all recursively, and return the result of the recursive call. Otherwise we return one and print the value. (I used (prog1 1 …) to emphasize that we're returning one, and printing is just a side effect. The main part of print-all is a typical recursion now.
(defun print-all (list)
(flet ((process-element (x)
(if (listp x)
(print-all x)
(prog1 1
(format t "~A " x)))))
(if (endp list)
0
(+ (process-element (first list))
(print-all (rest list))))))
Of course, now that we've pulled out the auxiliary function, the iteration is a bit clearer, and we see that it's actually a case for reduce. You might even choose to do away with the local function, and just use a lambda function:
(defun print-all (list)
(reduce '+ list
:key (lambda (x)
(if (listp x)
(print-all x)
(prog1 1
(format t "~A " x))))))
Here's my suggestion on how to write this function:
(defun all-print (lst)
(if (null lst)
0 ; empty list => length is 0
(let ((c (car lst))) ; bind first element to c
(if (listp c) ; if it's a list
(+ (all-print c) (all-print (cdr lst))) ; recurse down + process the rest of the list
(progn ; else
(format t "~a " c) ; not a list -> print item, then
(1+ (all-print (cdr lst)))))))) ; add 1 and process the rest of the list
then
? (all-print (list 5 "night" 3 (list 9 -10) (quote day) -5.9 (* 100.999)))
5 night 3 9 -10 DAY -5.9 100.999
8

Resources