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)
Related
The task was to Create an XLISP program that simulates the stack implementation of push and pop. Remember, the push and pop of a stack happens only on the top of stack (which is different from a queue)
In this case, we assume that the right most part of your list is the top portion.
Push operation description
Ask the user to enter a number
Insert the data into your stack
0 or negative number is not allowed. If so, simply print "Invalid Input"
Pop
Simply removes the top data from your stack.
Assumption:
You have a list called mystack initialized as an empty list.
Example Run:
(setq myStack())
NIL
(push)
*** When I try to run the code it says that undefined function NIL
(setq myStack(nil))
> (push)
> (pop)
; PUSH Function
(defun push ()
(let ((num (read)))
(if (and (numberp num) (> num 0))
(setq myStack (append myStack (list num)))
(print "Invalid Input"))))
; POP Function
(defun pop ()
(if (null myStack)
(print "Stack is empty")
(progn
(setq myStack (butlast myStack))
(print myStack))))
Your Problem first of all is
(setq myStack (nil))
In Common Lisp, one would write it:
(defparameter *my-stack* nil)
In Common Lisp, there is the equality: NIL == () == '() == 'NIL.
What you want is an empty list, which is one of those.
Remember, an empty list () or '() already contains an implicit NIL
as its last CDR. Proof:
(cdr ()) ;; => NIL
(cdr '()) ;; => NIL
(cdr NIL) ;; => NIL
(cdr 'NIL) ;; => NIL
At least in Common Lisp it is defined like this.
However, in Racket/Scheme this is not defined like this. Therefore, this is not universal to Lisps:
$ racket
Welcome to Racket v6.11.
> (cdr NIL)
; NIL: undefined;
; cannot reference undefined identifier
; [,bt for context]
> (cdr '())
; cdr: contract violation
; expected: pair?
; given: '()
; [,bt for context]
> (cdr ())
; readline-input:4:5: #%app: missing procedure expression;
; probably originally (), which is an illegal empty application
; in: (#%app)
; [,bt for context]
> (cdr 'NIL)
; cdr: contract violation
; expected: pair?
; given: 'NIL
; [,bt for context]
Therefore, in XLISP this must not be ...
However, for all lisps, it will be true that you need '() as an empty list.
So at least, your line must be:
(setq my-stack '())
If you forget the quote ', the interpreter/compiler thinks it is a function call and searches the function name nil and doesn't find it. Therefore your error.
Later you ask in your pop function: (null my-stack). If you start with '(nil), the problem is you don't start with an empty list.
Proof:
In Common Lisp:
(null '(nil)) ;;=> nil
In Racket:
(null? '(nil)) ;;=> #f
Why? because your list then contains still and element which has as value NIL.
In both languages, you can do:
(cdr '(nil)) ;;=> '() <-- Now the list is empty!
I would define your push und pop in Common Lisp:
(defparameter *my-stack* '())
(defun my-push (x)
(setf *my-stack* (cons x *my-stack*))
(defun my-pop ()
(let ((x (car *my-stack*)))
(setf *my-stack* (cdr *my-stack*))
x))
As you see I don't append it at the end because this is very inefficient (otherwise one has to traverse the entire list).
In Lisp, one adds at the start by cons-ing. And pops from the start by car-ing and cdr-ing.
Also, your pop doesn't return the pop-ed value.
Actually, your function to behave like the in-built push and pop in Common Lisp, must be:
(defmacro my-push (x lst)
`(setf ,lst (cons ,x ,lst)))
(defmacro my-pop (lst)
`(let ((x (car ,lst)))
(setf ,lst (cdr ,lst))
x))
Usage:
(defparameter *stack* '())
(my-push 1 *stack*) ;;=> (1)
(my-push 2 *stack*) ;;=> (2 1)
(my-push 3 *stack*) ;;=> (3 2 1)
*stack* ;;=> (3 2 1)
(my-pop *stack*) ;;=> 3
(my-pop *stack*) ;;=> 2
(my-pop *stack*) ;;=> 1
(my-pop *stack*) ;;=> NIL
(my-pop *stack*) ;;=> NIL
;; whether the list is empty or the first element's value is NIL
;; you can check by (length *stack*) => if that is 0, the stack is empty
In racket:
(define-syntax-rule (push x lst)
(set! lst (cons x lst)))
(define-syntax-rule (pop lst)
(let ((x (car lst)))
(set! lst (cdr lst))
x))
Usage:
> (define stack '())
> (push 1 stack)
> (push 2 stack)
> (push 3 stack)
> stack
'(3 2 1)
> (pop stack)
3
> (pop stack)
2
> (pop stack)
1
> (pop stack)
; car: contract violation
; expected: pair?
; given: '()
; [,bt for context]
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.
This function here:
(defun test (a)
(if (equal a nil) 0)
(if (listp (car a)) (print "a")
(print "b"))
(test (cdr a))
)
I want it to return 0 if a is nil which is the base case. then if the element in the front of the list is a list, print the letter a otherwise print b then call function again. Why doesn't the base case prevent the infinite loop?
Your code ends up with a stack overflow because you recurse into test regardless of the result of the nil-check.
(defun test (a)
(if (equal a nil) 0) ; <-- problem is partly here...
(if (listp (car a))
(print "a")
(print "b"))
(test (cdr a))) ; <-- ...and partly down here
Even if (equal a nil) evaluates to T and the surrounding if therefore evaluates to 0, you basically ignore this result, because the next step you do is checking if a is a list regardless of the outcome of the previous nil-check. Eventually you call test again without taking the result of your comparisons into consideration.
Keep in mind that the result of a function in Lisp is the result of the last evaluated expression, meaning that if you want your function to return 0 you have to make 0 the last evaluated expression.
The following code behaves as you specified:
(defun test (a)
(if (null a)
0
(progn
(if (listp (car a))
(print "a")
(print "b"))
(test (cdr a)))))
Note that you can use null to do a nil-check.
If a is not nil, then and only then, a is examined further. For this purpose progn lets you evaluate a sequence of expressions and eventually evaluates to the result of its last expression.
The other answers have explained your problem very well; just 2 notes:
cond
At least one style guide advises againt the use of if and prefers cond; this would have avoided the "fall-through problem":
(defun test (a)
(cond
((equal a nil) 0)
(t (if (listp (car a))
(print "a")
(print "b"))
(test (cdr a)))))
return
You can return early from a function; your code would have worked with a return-from clause:
(defun test (a)
(if (equal a nil) (return-from test 0))
(if (listp (car a))
(print "a")
(print "b"))
(test (cdr a)))
Because your base case is still followed by the printing and recursion. It didn't return straight afterwards.
Perhaps you wanted this:
(defun test (a)
(if (null a)
0
(progn (if (listp (car a))
(print "a")
(print "b"))
(test (cdr a)))))
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.
I am trying to define a recursive function balanced that takes a string and returns true only if the parens in the string are balanced.
The elisp code I wrote is based on some Scala code I wrote for the Coursera class by Odersky, it's a transliteration.
;; check if expr (list of chars of some expression) is balanced
(defun balanced (expr)
(defvar lparen (string-to-char "("))
(defvar rparen (string-to-char ")"))
(defun is-open (c) (eq lparen c))
(defun is-close (c) (eq rparen c))
(defun is-empty (ls) (eq ls nil))
(defun is-matching (l r) (and (is-open l) (is-close r)))
(defun is-balanced (list stack)
(cond ((is-empty list) (is-empty stack))
((is-open (car list))
(is-balanced (cdr list) ;; 'push' open-paren onto stack
(cons (car list) stack)))
((is-close (car list))
(if (is-empty stack) nil
(and
(is-balanced (cdr list) (cdr stack))
(is-matching (car stack) (car list)))))
(is-balanced (cdr list) (cdr stack))))
is-balanced
I am in lisp-interaction-mode, so I used Ctrl-J to evaluate the above defun statement.
Then, when I attempt to evaluate this:
(balanced "(balanced nil nil)")
I get a void-variable error:
Debugger entered--Lisp error: (void-variable is-balanced)
balanced("(balanced nil nil)")
(progn (balanced "(balanced nil nil)"))
eval((progn (balanced "(balanced nil nil)")) t)
eval-last-sexp-1(t)
eval-last-sexp(t)
eval-print-last-sexp()
call-interactively(eval-print-last-sexp nil nil)
recursive-edit()
debug(error (void-variable is-balanced))
balanced("(balanced nil nil)")
(progn (balanced "(balanced nil nil)"))
eval((progn (balanced "(balanced nil nil)")) t)
eval-last-sexp-1(t)
eval-last-sexp(t)
eval-print-last-sexp()
call-interactively(eval-print-last-sexp nil nil)
recursive-edit()
The function doesn't seem to recognize itself, what am I doing wrong?
When you execute your function (balanced ...), what it does is this:
It first defines two global variables
It defines five other functions
It accesses the variable is-balanced.
Step 3. happens right after the end of (defun is-balanced (list stack) ... )))).
(defun balanced (expr)
...
(defun is-balanced (list stack)
...
(is-balanced (cdr list) (cdr stack))))
is-balanced ;; <= here!
But you have not defined such a variable. You have defined a function of the same name, but you cannot access function objects as if they're variables in Emacs Lisp. See also here. Since there is no variable named is-balanced you get an error message.
(That said, there's a lot to be critized about the rest of your code. For starters, be aware that by having defuns inside defuns, you're re-defining your is-* functions every single time you're invoking (balanced ...). That's certainly not what you want. Similarly, you probably want to move the defvar outside the function body, since they define global variables. Or did you mean to use (let ...) instead? If you really want global values, then (defconst...) might be more appropriate.)
The problem is that the final element of the cond expression is not wrapped in (t ... ):
Incorrect:
(is-balanced (cdr list) (cdr stack))
Correct
(t (is-balanced (cdr list) (cdr stack)))
The reason this is needed is that the last expression is supposed to be the else case.