EVAL: undefined function NIL in Lisp - lisp

I'm trying to write a function named calculate that gets a list as an input, and calculates its value (works as a lambda calculus reducer).
Here's my code:
(defun substitue(x y z)
(cond ((atom z) (cond ((eq z y) x)
(T z)))
(T (cons (substitue x y (car z))
(substitue x y (cdr z))))))
(defun substitute-and-eval(x y z)
(eval (substitue x y z)))
(defun calculate(l)
(cond ((eq l nil) nil)
((atom l) (eval l))
(T (substitute-and-eval (calculate (cdr l))
(calculate (car l))
l))))
but when I call the following line in Lisp, I get the error:
(calculate '((lambda (x) (+ x 2))
(lambda (y) (y))
((lambda (z) (+ z 4)) 3)))
Error :
EVAL: undefined function NIL
So I traced the code and didn't find anywhere where I'm recursively calling eval on nil, so I couldn't find the problem. I also am not sure if my calculate function does what it should correctly. Since I'm a newbie in Lisp, I would appreciate any help.

If we call calculate on ((lambda (z) (+ z 4)) 3), it then calls calculate on the cdr of above, which is (3).
Then there is a call to (substitute-and-eval nil 3 '(3)). Which then tries to evaluate (nil)...
With a stepper the wrong call is easy to find, see STEP.

Related

Lisp pass evaluated expression to macro

I've got an issue where I've got a macro, isentropic expansion which then calls solve-format replacing NIL in a list with 'x?, which then returns a valid expression can be passed to solve.
(isentropic-expansion 295 nil 1 4.2 1.4)
returns
(-
(expt
(/ 4.2 1)
(/
(- 1.4 1)
1.4))
(/ x\? 295))
which is the valid expression to then put into the solve function
but if I do the following (let's imagine I've set the output from the above command to the variable expr
(solve expr 2)
the macro doesn't replace the expression symbols with the value of expr, just expr the string, and I get
Wrong number of arguments: (lambda nil expr), 1
I think this is because I don't fully understand macros yet! Can anyone explain why this is please?
(defun newton-f (func x0)
"Solve the equation FUNC(x)=0 using Newton's method.
X0 is an initial guess."
(let* ((tolerance 1e-6)
(x x0)
(dx 1e-6)
fx fpx)
(while (> (abs (funcall func x)) tolerance)
(setq fx (funcall func x)
fpx (/ (- (funcall func (+ x dx)) (funcall func (- x dx))) (* 2 dx))
x (- x (/ fx fpx))))
x))
(defmacro solve (expression guess)
`(newton-f
(lambda ,(cl-loop for item in (flatten expression)
if (and (symbolp item) (s-ends-with? "?" (symbol-name item)))
collect item)
,expression)
,guess))
(defun solve-format (exp)
(cond ((null exp) 'x?)
((atom exp) exp)
((list exp) (cons (solve-format (car exp))
(if (cdr exp)
(solve-format (cdr exp))
nil)))
(t (print "what"))))
(defmacro isentropic-expansion (t01 t02 p01 p02 gamma)
`(solve-format '(- (expt (/ ,p02 ,p01) (/ (- ,gamma 1) ,gamma)) (/ ,t02 ,t01))))
solve is also a macro:
(defmacro solve (expression guess) ...)
As macros do not automatically evaluate their arguments, when you use this:
(solve expr 2)
During the macro's expansion it has expression bound to the symbol expr and guess bound to the number 2.
The (lambda nil expr) in the error message is this call:
(lambda ,(cl-loop for item in (flatten expression)
if (and (symbolp item) (s-ends-with? "?" (symbol-name item)))
collect item)
,expression)

How do I fix "BINDING form is not a proper list" error

I'm new in lisp, I'm trying to define a simple function that search an element in a list.
I'm not finding myself comfortable with the sintax of the language, also I don't quite understand the error/warning messages.
(defun in-list (x l)
(let y (car l))
(let z (cdr l))
(if (null l)
nil
(if (equal x y)
t
(in-list x z)
)
)
)
I also tried to replace let with seq, but still gave me warnings on "variables assumed to be special".
There is an error in the syntax of let. The correct form is:
(let ((var1 exp1)
(var2 exp2)
...
(varn expn))
body-of-let)
So you should write:
(defun in-list (x l)
(let ((y (car l))
(z (cdr l)))
(if (null l)
nil
(if (equal x y)
t
(in-list x z)))))
Note that it is not necessary define the two local variables since the corresponding expression is used only once, so you could abbreviate the function in this way:
(defun in-list (x l)
(if (null l)
nil
(if (equal x (car l))
t
(in-list x (cdr l)))))
and, since you have three different cases in the body, you could use a single cond instead of two if:
(defun in-list (x l)
(cond ((null l) nil)
((equal x (car l)) t)
(t (in-list x (cdr l)))))
There are very good free books on the web to learn the basis of the language. See for instance this one.
To be able to use setq, you can declare your function's inner variables after the &aux keyword in the function's lambda-list:
(defun in-list (x l &aux y z)
(setq y (car l)
z (cdr l))
(and l
(or (equal x y)
(in-list x z))))
A better style is to give the auxiliary variables their values right at the point of declaration:
(defun in-list (x l &aux (y (car l)) (z (cdr l)))
(and l
(or (equal x y)
(in-list x z))))

Why does my function keep returning an empty list?

I am writing an upper-threshold function in Racket that takes two arguments: a list of numbers and an integer.
All it has to do is recursively go through the list and return a list of integers that are below the value of the given integer. However, my function always spits out an empty list. I feel like it has something to do with how I am using the append function.
I have displayed the values that should be appended to my empty list z, and they are correct, but for some reason they are not appending to the list!
(define (upper-threshold x y [z '()])
(cond [(null? x) z]
[else (cond [(< (first x) y) (append (list (first x)) z) (upper-threshold (rest x) y)]
[else (upper-threshold (rest x) y)])]))
For example, a call and return should look like this:
(upper-threshold '(1 2 3 5 6) 4)
'(1 2 3)
You aren't including the third argument, z, in any of the recursive calls to upper-threshold. This means that on each iteration, z will always be the empty list. Furthermore, Racket's append doesn't mutate the lists it operates on. This means the expression (append (list (first x)) z) produces an entirely new list instead of changing x or z.
(cond [(< (first x) y)
(append (list (first x)) z) ; produces a new list which is not used, x and z
; remain unchanged
(upper-threshold (rest x) y ; no z argument passed in here, defaults to '()
)]
[else
(upper-threshold (rest x) y ; no z argument passed in here, defaults to '()
)])
All we need to do is provide the correct third argument to each recursive call.
(cond [(< (first x) y)
(define new-z (append (list (first x)) z))
(upper-threshold (rest x) y new-z)]
[else
(upper-threshold (rest x) y z)])
Also: whenever you want to add an element onto the front of a list, it's easier to use the function cons instead of append. Thus, (append (list (first x)) z) becomes (cons (first x) z).
(cond [(< (first x) y)
(define new-z (cons (first x) z))
(upper-threshold (rest x) y new-z)]
[else
(upper-threshold (rest x) y z)])

funcall function error cannot take car lisp

What's wrong with this code?
(defun f (l)
(funcall #'(lambda (ff)
(cond
((null l)nil)
((listp (car l)) (append ff (f (cdr l)) (car ff)))
(t (list (car l)))))
(f (car l))))
If I enter (f '(( 1 2 3))) it gives me an error:
"Cannot take car of 1".
What's wrong?
Here is a more detailed explanation of the comment of #Sylwester, that answers correctly to the question.
If you write (f '((1 2 3)) then the function f is called, l is bound to ((1 2 3)), and the result is the application of the internal function (lambda (ff) (cond ...)) to the value of (f (car l)).
To perform this application, first (f (car l)) is evaluated to produce a value, and since l is bound to ((1 2 3)), its car is (1 2 3).
So, f is applied to the list (1 2 3), which is bound to l in the recursive call. This evaluation again means that fshould apply the internal function (lambda (ff) (cond ...)) to the value of (f (car l)), that is to (f 1).
The process is reapeated, l is bound this time to 1, and again fshould apply the internal function (lambda (ff) (cond ...)) to the value of (f (car l)), but, since l is now 1, the function tries to evaluate the (car 1), which produces the error that you have found.

Undefined function in lisp

I am writing a lisp function and I keep getting EVAL - undefined function x when I try to return the value of x from the function.
(defun p+ (x y)
(recurcollect (gluelist x y) '()))
(defun isinlist (x y)
(if (car y)
(if (equal (cdr x) (cdar y))
t
(if (cdr y)
(isinlist(x (cdr y)))
NIL))
NIL))
(defun collectvalue (x y) ;takes an expression and a list and returns the sum of all like expressions from the list
(if (equal x NIL)
(print '(x is NIL))
(if (equal (cdr x) (cdar y))
(if (cdr y)
(collectvalue (list (+ (car x) (caar y)) (cdr x)) (cdr y))
(list (+ (car x) (caar y)) (cdr x)))
(if (cdr y)
(collectvalue x (cdr y))
x))))
(defun recurcollect (x y) ;returns a flat list of collected expressions
(if (isinlist (car x) y)
(recurcollect (cdr x) y)
(if (cdr x)
(recurcollect x (cons y (collectvalue (car x) (cdr x))))
(cons y (car x)))))
(defun gluelist (x y)
(if (cdr x)
(cons (car x) (gluelist (cdr x) y))
(cons (car x) y)))
(print (p+ '(2 0 1) '(4 0 1))) ;(6 0 1)
I believe the error is caused by the x at the end of the function but I cant see why, as far as I can tell my brackets are correctly paired up and I cant see why it is trying to evaluate x as a function.
The problem is in isinlist which is called recursively as (isinlist(x (cdr y))).
(x ...) is interpreted as a function call of function x.
You probably want (isinlist x (cdr y)) instead.
Incidentally, you can replace isinlist with member (with :key #'cdr :test #'equal).