Lisp: Why and how does '(nil nil) evaluate to true? - lisp

(if '(nil nil)
'print-true
'print-false)
(if '(nil)
'print-true
'print-false)
In the code above, why does the Lisp interpreter always evaluate these forms to true (print-true). I thought nil represented false in Common Lisp.
I am using GNU CLISP.

nil is false. Anything else is true. '(nil) is a list with one element, namely nil. '(nil nil) is a list with two elements, namely nil and nil. Neither of these expressions is the same as nil by itself, so if sees it as true.

nil is equivalent to an empty list.
CL-USER> (if (list ) 'print-true 'print-false)
; prints PRINT-FALSE
CL-USER> (if (list nil) 'print-true 'print-false)
; prints PRINT-TRUE
'(nil) is equiv to (list nil) which is different from an empty list.

Related

LISP - Replace values in a list

I have a list of nils (NIL NIL NIL NIL) and i need to add two X in place of the two first NILs, so it becomes (X X NIL NIL).
I have the following code:
(cons x (cons x (cons (cdr '(NIL NIL NIL NIL))nil)))
But this way it returns
(X X (NIL NIL))
Those parenteses need to be removed, and i don't know how. Can someone help me?
Thanks
If you pass a list to the first argument of cons then you are making a nested list. First lets say we make your initial list and the symbol x variables:
(defparameter *nils* '(nil nil nil nil))
*nils* ; ==> (nil nil nil nil)
(defparameter *x* 'x)
*x* ; ==> x
So how do we remove the two first. Well we can remove one with (cdr *nils*) so that means we can do it twice:
(cdr (cdr *nils*))
; ==> (nil nil)
Actually more than one car and cdr accessor has a shorthand upto 5 combinations. The shorthand is just starting with c and do the a/d's and end with r like this:
(cddr *nils*)
; ==> (nil nil)
Goodie, how do we add *x* in front of that? Well cons is defines as making an element in front of the second argument, thus (cons *x* (cddr *nils*)) will make(x nil nil). Again if you want to have anotherx` in front of that you do the same with the firt result:
(cons *x* (cons *x* (cddr *nils*)))
; ==> (x x nil nil)
Using list* is like nested cons with a tail in the end. Thus the above code can be replaced with:
(list* *x* *x* (cddr *nils*))
; ==> (x x nil nil)
Now replacing the variables the expression that was stored as their value (substitution method):
(list* 'x 'x (cddr '(nil nil nil nil)))
; ==> (x x nil nil)
(list* X X (nthcdr 2 your-list))
The function NTHCDR returns the list with two first elements dropped & the function LIST* returns a new list appending specified items at the front.
Observe that thus you obtain a new list rather then modify the original one. If you really want to modify the original list (this may very well be a bad idea, proceed with caution), you can just make the assignment:
(setf (first your-list) 'X)
(setf (second your-list) 'X)
Modifying a list like this may result in modifications of seemingly unrelated data. It is not compatible with the quoted literal list, anyway.

Lisp (null (QUOTE NIL)) returns NIL

I am new to lisp and I'm trying to a simple check to see if a list is empty. For test purposes i created this test function:
(defun test (list)
(if (null (caddr list))
(make-node 1)
(caddr list)))
if uses the make-node function defined as:
(defun make-node (atm)
(cons atm `(`() `())))
when running (make-node 6) I get:
(6 (QUOTE NIL) (QUOTE NIL))
which is what I want.
i then call (test (make-node 6)) which i then get:
(QUOTE NIL)
which is the (caddr list) from test. if you run (null (QUOTE NIL)) you get T which is what i want to get but when i run it from the given test function i receive NIL.
So my question is why when i check if this is null why do i get NIL instead of T?
When you evaluate (null (quote nil)), (quote nil) is evaluated, resulting in nil being used as the argument for the function null.
However when you evaluate something like (null (function-returning-quote-nil)), function-returning-quote-nil is evaluated, resulting in the list (quote nil) which is then used as the argument for the function null without further evaluation.
Compare to the difference between
(null (quote nil)) ; => t
and
(null '(quote nil)) ; => nil
(CADDR '(6 (QUOTE NIL) (QUOTE NIL))) ; ==> (QUOTE NIL) or just 'NIL
The list with the two symbols QUOTE and NIL are not equal to NIL. Only NIL is equal to NIL. eg.
(DEFPARAMETER TEST 'NIL)
TEST ; ==> NIL
(NULL TEST) ; ==> T
This works since 'NIL gets evaluated to NIL and assigned to TEST. TEST gets evaluated to NIL and it's CLs NULL value. However:
(DEFPARAMETER TEST2 ''NIL)
TEST2 ; ==> 'NIL or (QUOTE NIL)
(NULL TEST2) ; ==> NIL
A list with two elements QUOTE and NIL, famously displayed as 'NIL, is NOT NIL. Only NIL is NIL.
EDIT
After looking at your comments about unquoting I'm pretty sure you want this as make-node:
(defun make-node (atm)
(cons atm '(() ())))
(test (make-node 6)) ; ==> (1 NIL NIL)
There is no such thing as unquoting in a data structure and unless you actually want the symbol quote in your data there is no sense in having quotes inside something quoted. (Half truth since there is, but it involves macros)

why an extra value at end of hash?

I wrote a function to convert alist to hash:
(defun hash-alist (alist)
"Convert association list to a hash table and return it."
(let ((my-hash (make-hash-table :test 'equal)))
(dolist (entry alist)
(if (gethash (car entry) my-hash)
(error "repeated key"))
(puthash (car entry) (cdr entry) my-hash))
my-hash))
but when I run it as following, why I get nil at the end?
Run:
(setq a '(("a" . 2) ("b" . 1)))
(setq b (hash-alist a))
(maphash (lambda (x y) (princ (format "%s:%d " x y) t))
b)
Output:
a:2 b:1 nil
nil is the return value of maphash. Nothing more than that.
It is the way that you are evaluating the maphash sexp that causes the return value to be printed.
If you look in buffer *Messages* you might see something like this (depending on how you evaluate the expression):
Evaluating...
a:2 b:1
Buffer `*Pp Eval Output*' is in mode `Emacs-Lisp'. For info on the mode: `C-h m'.
nil
The return value is documented in the Elisp manual, node Hash Access. It should also be, but is not, documented in the doc string.
Every Lisp expression has a value.
c-x c-e evaluates an expression and prints the result.
If you evaluate (+ 1 2) you see that it evaluates to 3. If you evaluate a maphash expression, then it evaluates to NIL. So this is printed.
Since your code calls functions which produce output, you see that output printed before the return value. So there is no extra NIL. It is just the NIL that is the result.

LISP modify list passed as argument

So i got this function that receives a list as an argument
(defun do-transf (lst)
...
my initial lst is ((NIL NIL) (NIL NIL))
but in the end i want the lst becomes
(NIL NIL NIL NIL)
example
(defvar a (list (list NIL NIL) (list NIL NIL)))
(do-transf a)
(NIL NIL NIL NIL) -> gives the right answer but when i call the list this isnt the answer
a
((NIL NIL) (NIL NIL)) -> i dont want this
Your post suggests that you wish to do list concatenation, i.e. append lists to another.
As such, try this:
(defvar a (list (list NIL NIL) (list NIL NIL)))
(apply #'append a)
This outputs:
(NIL NIL NIL NIL)
Short, simple, sweet.
UPDATE:
Since you want destructive behavior (that is, modification of the original value of a):
(setq a (apply #'append a))
Now, a is set to this new value (from ((NIL NIL) (NIL NIL))):
(NIL NIL NIL NIL)
Typically, lisp functions don't mutate the data they operate on. This is not a required property, but it does make it much easier writing and reasoning about large code bases.
So, what typically happens is that a function will return a copy of the new data, that can then replace the old value in a variable, at the discretion of the caller.
Even when functions destructively modify data structures, they tend to return the new resulting value.
If we look at the following code:
(defvar *example* '(delete 2 3 4))
=> *example*
(delete 'delete *example*)
=> (2 3 4)
*example*
=> (delete 2 3 4)
This is because there is no way for the function to destructively modify *example* so it loses the first element, so even when you are using destructive, mutating functions, they need to return a value suitable for storing back into the variable that the input came from.
Try using flatten..
(defvar a (flatten (list (list NIL NIL) (list NIL NIL))))

Stripping duplicate elements in a list of strings in elisp

Given a list such as
(list "foo" "bar" nil "moo" "bar" "moo" nil "affe")
how would I build a new list with the duplicate strings removed, as well as the nils stripped, i.e.
(list "foo" "bar" "moo" "affe")
The order of the elements needs to be preserved - the first occurence of a string may not be removed.
The lists I'm dealing with here are short, so there's no need to use anything like a hash table for the uniqueness check, although doing so certainly wouldn't hurt either. However, using cl functionality is not a viable option.
Try "Sets and Lists" in the "Lists" section of the Emacs Lisp Reference Manual:
(delq nil (delete-dups (list "foo" "bar" nil "moo" "bar" "moo" nil "affe")))
The Common Lisp package contains many list manipulation functions, in particular remove-duplicates.
(require 'cl)
(remove-duplicates (list "foo" "bar" nil "moo" "bar" "moo" nil "affe")
:test (lambda (x y) (or (null y) (equal x y)))
:from-end t)
Yes, I realize you said you didn't want to use cl. But I'm still mentioning this as the right way to do it for other people who might read this thread.
(Why is cl not viable for you anyway? It's been shipped with Emacs for about 20 years now, not counting less featured past incarnations.)
If you use dash.el library, that's all you need:
(-distinct (-non-nil '(1 1 nil 2 2 nil 3)) ; => (1 2 3)
dash.el is written by Magnar Sveen and it's a great list manipulation library with many functions for all kinds of tasks. I recommend to install it if you write lots of Elisp code. Function -distinct removes duplicate elements in a list, -non-nil removes nil elements. While the above code is sufficient, below I describe an alternative approache, so feel free to ignore the rest of the post.
-non-nil was added in version 2.9, so if for some reason you have to use earlier versions, another way to achieve the same is to use -keep with built-in identity function, which just returns whatever it is given: (identity 1) ; => 1. The idea is that -keep keeps only elements, for which the predicate returns true (“non-nil” in Lisp jargon). identity obviously returns non-nil only for whatever values that are not nil:
(-distinct (-keep 'identity '(1 1 nil 2 2 nil 3)) ; => (1 2 3)
This is a short example:
(delete-duplicates '("~/.emacs.d" "~/.emacs.d") :test #'string-equal) ;; '("~/emacs.d")
Basically you use the :test keyword to select the function string-equal to test if the elements are duplicated.
Else the default function test doesn't check string equality.
Here ya go:
(defun strip-duplicates (list)
(let ((new-list nil))
(while list
(when (and (car list) (not (member (car list) new-list)))
(setq new-list (cons (car list) new-list)))
(setq list (cdr list)))
(nreverse new-list)))