How do I tell if a list contains NILs? - lisp

I have the following list:
(X O X O X NIL X NIL O)
If I do (find 'x (X O X O X NIL X NIL O)) it returns X, so I know the list contains X. But If I do (find nil (X O X O X NIL X NIL O)) I get NIL, which is meaningless because I'd get NIL even if my list didn't contain NIL.
How can I tell if my list contains NILs or not?

You can use position
(position NIL '(X O X O X NIL X NIL O))
--> 5

It may not be as processor-efficient as the others, but I'd likely write it pretty much like I say it in English:
(some #'null '(X O X O X NIL X NIL O))

Would something like this work?
(or
(map (lamdba (x)
(eq? x nil))
'(X O X O X NIL X NIL O)))
I don't have CL installed right now, but I think it would work. (or works that way in CL, right? or is there an any function?
EDIT:
Wait a second, nil counts as false, right?
(apply and '(X O X NIL))
;Or
(all '(X O X NIL))
;Whichever works in CL.

NOT is what you're looking for.
Here's an example:
(reduce #'(lambda (a b) (or a b))
(mapcar 'not '(1 2 3 4)))

Related

How do I append a list recursively in common lisp?

(defun foo (in i out)
(if (>= i 0)
(progn
(append (list (intern (string (elt in i)))) out)
(print output)
(foo in (- i 1) out )
)
(out)
)
)
(print (foo "abcd" (- (length "abcd") 1) (list)))
I am trying to return this string as (a b c d). But it does return nil as output. What do I do wrong here? Thanks
I don’t know what this has to do with appending. I think your desired output is also weird and you shouldn’t do what you’re doing. The right object for a character is a character not a symbol. Nevertheless, a good way to get the list (a b c d) is as follows:
CL-USER> '(a b c d)
Interning symbols at runtime is weird so maybe you would like this:
(defconstant +alphabet+ #(a b c d e f g h i j k l m n o p q r s t u v w x y z))
(defun foo (seq)
(map 'list
(lambda (char)
(let ((index (- (char-code char) (char-code #\a))))
(if (< -1 index (length +alphabet+))
(svref +alphabet+ index)
(error "not in alphabet: ~c" char))))
seq))
You have just some minor mistakes. First, we need to get rid of output and (output); these bear no relation to the code. It seems you were working with a variable called output and then renamed it to out without fixing all the code. Moreover, (output) is a function call; it expects a function called output to exist.
Secondly, the result of append must be captured somehow; in the progn you're just discarding it. Here is a working version:
(defun foo (in i out)
(if (>= i 0)
(foo in (1- i) (cons (intern (string (elt in i))) out))
out))
Note also that instead of your (append (list X) Y), I'm using the more efficient and idiomatic (cons X Y). The result of this cons operation has to be passed to foo. The out argument is our accumulator that is threaded through the tail recursion; it holds how much of the list we have so far.
I.e. we can't have (progn <make-new-list> (foo ... <old-list>)); that just creates the new list and throws it away, and then just passes the old list to the recursive call. Since the old list initially comes as nil, we just keep passing along this nil and when the index hits zero, that's what pops out. We need (foo .... <make-new-list>), which is what I've done.
Tests:
[1]> (foo "" -1 nil)
NIL
[2]> (foo "a" 0 nil)
(|a|)
[3]> (foo "ab" 1 nil)
(|a| |b|)
[4]> (foo "abcd" 3 nil)
(|a| |b| |c| |d|)
[5]> (foo "abcd" 3 '(x y z))
(|a| |b| |c| |d| X Y Z)
Lastly, if you want the (|a| |b| |c| |d|) symbols to appear as (a b c d), you have to fiddle withreadtable-case.
Of course:
[6]> (foo "ABCD" 3 nil)
(A B C D)

how to get defun to accept a list as its argument

I am trying to learn lisp and searched the question and found a response I couldnt understand. Could someone help me with what I am trying.
SO I have created a basic function RotateL which should take a list as its argument and returns a new list in which the former first element becomes last.
So I created
(defun rotate (L)
(Append ( rest L) (first L)))
ROTATE
I can't set L as a (a b c) I tried SETQ L '( a b c) and when at the end I did (rotate L) it gives me an error as well.
I think its the fact that I am trying to put a list rather then an element in value L.
Could someone explain and help please.
Since you are deeply lost:
? (defun rotate (L) (append (rest L) (first L)))
ROTATE
? (rotate '(a b c))
(B C . A)
? (setq X '(x y z))
(X Y Z)
? (rotate X)
(Y Z . X)
But you see that your function is broken, correcting by adding a list:
? (defun rotate (L) (append (rest L) (list (first L))))
ROTATE
? (rotate '(a b c))
(B C A)
? (rotate X)
(Y Z X)
You may want to look up the meaning of formal and actual parameters.

fixed point combinator in lisp

;; compute the max of a list of integers
(define Y
(lambda (w)
((lambda (f)
(f f))
(lambda (f)
(w (lambda (x)
((f f) x)))))))
((Y
(lambda (max)
(lambda (l)
(cond ((null? l) -1)
((> (car l) (max (cdr l))) (car l))
(else (max (cdr l)))))))
'(1 2 3 4 5))
I wish to understand this construction. Can somebody give a clear and simple explanation for this code?
For example, supposing that I forget the formula of Y. How can I remember it , and reproduce it long after I work with it ?
Here's some related answers (by me):
Y combinator discussion in "The Little Schemer"
Unable to get implementation of Y combinator working
In Scheme, how do you use lambda to create a recursive function?
Basically, with Y defined as λr.(λh.h h) (λg.r (λx.(g g) x)), an application Y r reduces as
Y r
(λw.(λh.h h) (λg.w (λx.(g g) x))) r
(λh.h h) (λg.r (λx.(g g) x))
h h
;where
h = (λg.r (λx.(g g) x)) <----\
|
(λg.r (λx.(g g) x)) h |
r (λx.(g g) x) <-------------- | ----------\
;where | |
g = h -----/ |
;so that |
(g g) = (h h) = r (λx.(g g) x) ------/
So r must expect two arguments - first representing the recursive function to be called, and second - an actual argument:
r = λf (λx. ....x.....(f y)...... )
so that (Y r) x reduces as
(r (λx.(g g) x)) x
(r f) x
;where
f = (λx.(g g) x)
f y = (λx.(g g) x) y = (g g) y = (r f) y ; f is "fixed point" of r
The definiton f = (λx.(g g) x) means, when f y is called, (g g) y will be called, at which point g will be self-applied, r "pulled" from inside g and the result of (r f) called with y argument. I.e. any call (f y) in the body of lambda expression resulting from (r f) application, is translated back to (r f) y i.e. invocation of same body with a new argument y.
The important implementational detail is whether it is the same function body, or its copy, but the semantics are the same - we are able to enter the same function body with a new argument value.
The essence of Y combinator is replication through reference and self-application: we refer to the same thing through same name, twice; and thus we arrange for it to receive itself as an argument.
When there's no referencing, as in pure lambda calculus, and parameters receive textual copies of arguments - i.e. reduction is done by textual rewriting - this still works, because same copies get replicated and passed around, being fed as argument to self so it is available on the next iteration, if need be.
But it is much more efficient when shared referencing is available (all uses of same name refer to same thing). Under environment model of evaluation creation of self-referential function is simple as
(let ((fact #f))
(set! fact
(lambda (n) (if (< 2 n) 1
(* n (fact (- n 1))))))
fact)
In fact the definition in your answer is that of applicative-order Y combinator. With normal-order, eta-reduction can be applied without causing infinite looping, to get Ynorm = (λw.(λh.h h) (λg.w (g g))) which is canonically written as
Ynorm = (λf.(λx.f (x x)) (λx.f (x x)))
indeed
Ynorm g
= (λx.g (x x)) (λx.g (x x))
= g ((λx.g (x x)) (λx.g (x x)))

Lisp List Printing

I am having some troubles regarding the lisp format function. I have the following list:
((X X X)(X X X X X X)(X X X X X X X X X))
and I need to print it in the following format:
X X X
XX XX XX
XXXXXXXXX
Any thoughts on how to achieve this? The format function is kinda confusing and the HyperSpec documentation doesn't seem to do anything for me. Thanks.
Like every tool format has its limitations and it's not suited for such problems very well. Probably the best you can get with plain format without resorting to black magic tricks with ~? or ~/, that you or anyone else probably won't understand in the future, is this code:
CL-USER> (format t "~{~{~A ~}~%~}"
'((X X X) (X X X X X X) (X X X X X X X X X)))
X X X
X X X X X X
X X X X X X X X X
If you want to get your sophisticated output structure, try to do some pre-processing.
Like, if the format of the list is hard-coded, you can use this:
(format t "~{~{~6A~} ~%~}"
(mapcar (lambda (l)
(loop :for i :from 0 :to (1- (length l)) :by (/ (length l) 3)
:collect (format nil "~{~A ~}"
(subseq l i (+ i (/ (length l) 3))))))
'((X X X) (X X X X X X) (X X X X X X X X X))))
Here we first collect the items of a list into same number of groups for each list, print them and this way get 3 lists with the same number of elements, which can then be processed by format.
You can find out more about format in the appropriate chapter of Peter Seibel's excelent Lisp book: http://gigamonkeys.com/book/a-few-format-recipes.html
EDIT
If you have a variable number of lists, with each one being twice bigger than the previous one, you'll also need to prepare the format string beforehand:
CL-USER> (defun format-custom-list (list)
(format t (format nil "~~{~~{~~~DA~~} ~~%~~}" (* 2 (length list)))
(mapcar (lambda (l)
(let* ((len (length l))
(len/3 (/ len 3)))
(loop :for i :from 0 :to (1- len) :by len/3
:collect (format nil "~{~A ~}"
(subseq l i (+ i len/3))))))
list)))
CL-USER> (format-custom-list '((X X X) (X X X X X X) (X X X X X X X X X)
(X X X X X X X X X X X X)))
X X X
X X X X X X
X X X X X X X X X
X X X X X X X X X X X X
NIL
(The trailing nil is the output of format, which isn't printed to the output stream t. If you want to get a string out of this function use nil as format's output stream.)
I'm assuming you want to print each list, inserting spaces to make elements fit max list length.
Though I believe it is possible to print this with nearly single format call, it is better to split printing into several functions:
(defun format-list (stream lst space-count)
(let ((spaces (make-string 5 :initial-element #\Space))) ;; create string of spaces to insert
(let ((fmt (concatenate 'string "~{~a" spaces "~}~%")) ;; create formatting string
(format stream fmt lst)))))
(defvar full-list '((X X X)(X X X X X X)(X X X X X X X X X)))
(defvar max-list-length (max (mapcar length full-list))) ;; find length
(mapcar
#'(lambda (lst) (format-list t lst (/ (- max-list-length (length lst)) (length lst))))
full-list)
UPD.
For X + Space * (NumRows - CurrentRowNumber) condition you can next function instead of 2 last lines in my original code (in functional style, you can also use loop instead of reduce to make it less functional and more CL-like):
(format-list-of-lists (lst)
(let ((num-rows (length lst)))
(reduce #(lambda (cur-row sub-list) (format-list t sub-list (- num-rows cur-row)) (1+ cur-row))
lst)))

Scheme function that sum number u and list x u+x1+x2

Im new to Scheme and trying to make function that is (in f u x), u is integer, x is a list and f binary function. The scheme expression (in + 3 '(1 2 3)) should return 3+1+2+3=9.
I have this but if i do (in + 3 '(1 2)) it return 3 not 6. What am i doing wrong?
(define (in f u x)
(define (h x u)
(if (null? x)
u
(h (cdr x) (f u (car x)))))
(h x 0))
From what I understand of what your in function is supposed to do, you can define it this way:
(define in fold) ; after loading SRFI 1
:-P
(More seriously, you can look at my implementation of fold for some ideas, but you should submit your own version for homework.)