I am learning lisp and i am trying to create simple function to sum arr.
(defun sum( N )
( if ( null N )
nil
( + (car N ) ( sum ( cdr N )))))
(sum '(1 2 3 ))
yet it throws error
Error: execute: unbound symbol: "N" []
The parenthesis should be correct. Why is this throwing the error or what is wrong with logic behind my code?
If list is empty it will return nil , if not , it will return first element + rest of the list recursively.
Thanks for help
The base case is incorrect, you're adding the numbers in a list, hence you can't return nil, it'll fail when you try to add a number to it. Try this:
(defun sum (N)
(if (null N)
0
(+ (car N) (sum (cdr N)))))
Related
I was working on this question to print the sum of prime numbers in a range of numbers. The range values will be be taken as an input from the user. I got the syntax errors all cleared out but could not figure out how to return the value of the prime no. to the sum if it is true.
(defun check-prime(num)
(if (= num 1) nil)
;(setq i 2)
(loop for i from 2 to ( isqrt num) do
(if (= (mod num i) 0) nil t)
(= i (+ i 1))
)
)
(defun prime-sum(*begin* *end*)
(defvar *s* 0)
(defvar *i* *end*)
(loop for *i* from *end* to *begin* do
;i= 13
(if (check-prime *i*)
(= *s* (+ *s* *i* ) )
)
(= *i* (- *i* 1))
)
(write *s*)
)
(defun vals()
(print "enter the range1: ")
(defvar *begin* (read))
(print "enter the range2: ")
(defvar *end* (read))
(prime-sum *begin* *end*)
)
(print(vals))
;b =4
;e 13
Here is your function, cleaned up a bit and formatted in a conventional way:
(defun check-prime(num)
(if (= num 1) nil)
(loop
for i from 2 to (isqrt num)
do
(if (= (mod num i) 0) nil t)
(= i (+ i 1))))
There are multiple things that are incorrect, and they boil down to how are Lisp forms evaluated.
There is a special form progn in Common Lisp that is used to evaluate a list of expressions, with the following pattern:
(progn E1 E2 ... EN)
A lot of other functions in Lisp are described has having "an implicit progn", that's the case for defun which allows for more than one expression in its body, but since the progn doesn't appear literally it is implicit. The behavior is however always the same: each expression E1 to EN is evaluated in sequence, and evaluation of the whole progn are the values returned by the last expression, EN (that's where the N comes from in the name). In other words, the intermediate values from E1 etc. are discarded, the expressions are only useful for their side-effects.
In your code, that's the case for (if (= num 1) nil), which is an expression in the body of defun which is not the last one, and which doesn't even have side-effects. It is thus completely useless.
Likewise, in the loop macro, all that follows the do keyword are expressions that are evaluated for their side effects and do not contribute to the resulting value of the whole loop form.
In fact, loop is a bit complicated but here your don't have any accumulating clause in your loop (something like collect, append, sum etc. that would compute a result). Instead, your loop will always return nil.
Note also that for i from 2 to (isqrt num) takes care of incrementing i, you don't have to do it yourself like you tried in the do. Moreover, = is a comparison operator, in order to mutate i you would need to use setf instead: (setf i (+ i 1)), or (incf i) (which I repeat is unnecessary here).
To combine the first two expressions, I would write:
(if (= num 1) nil ...)
Where ... is the loop: because if is a functional if, it evaluates to whichever branch is selected by the condition.
And inside the loop, I would use never:
(loop for i from 2 to (isqrt num) never (= 0 (mod num i)))
The never clause makes the loop compute a boolean and halt as soon as the result is false.
CL-USER> (a-sum 0 3)
->> 6
I wrote this program :
(defun a-sum (x y)
(if (and (> x -1) (> y -1))
(do ((i 0 (1+ i))
(sum 0)
(num x))
((equal i (+ (- y x) 1)))
(setq sum (+ sum num))
(setq num (+ num 1))
sum)
(print " NOPE")))
put if I run it in the terminal it returns nil and not the answer stated above;
can someone help with the problem so it returns the value then Boolean.
DO,DO* Syntax
The entry for DO,DO* says that the syntax is as follows:
do ({var | (var [init-form [step-form]])}*)
(end-test-form result-form*)
declaration*
{tag | statement}*
The body is used as a list of statements and no intermediate value in this body is used as the result form of the do form. Instead, the do form evaluates as the last expression in result-form*, which defaults to nil.
(do ((i 0 (1+ i))
(sum 0)
(num x))
((equal i (+ (- y x) 1))
;;; RESULT FORMS HERE
)
(setq sum (+ sum num)) ;; (*)
(setq num (+ num 1)) ;; (*)
sum ;; (*)
)
All the expressions marked commented (*) above are used for side-effects only: the result of their evaluation is unused and discarded.
Problem statement
It is not clear to me what Σpi=ni means, and your code does not seem to compute something that could be expressed as that mathematical expression.
One red flag for example is that if (+ (- y x) 1) is negative (i.e. if y < x-1, for example y=1,x=3), then your loop never terminates because i, which is positive or null, will never be equal to the other term which is negative.
I would try to rewrite the problem statement more clearly, and maybe try first a recursive version of your algorithm (whichever is easier to express).
Remarks
Please indent/format your code.
Instead of adding setq statements in the body, try to see if you can define them in the iteration clauses of the loop (since I'm not sure what you are trying to achieve, the following example is only a rewrite of your code):
(do ((i 0 (1+ i))
(sum 0 (+ sum num)
(num x (1+ num))
(... sum))
Consider what value(s) a function returns. It's the value of the last form evaluated. In your case, that appears to be a do or maybe a setq or print (It's difficult to read as it's formatted now, and I don't have question edit privileges).
In short, the form that's returning the value for the function looks to be one evaluated for side-effects instead of returning a value.
I try to factorial for in this code but, I did not get the answer.
(defun fact(n)
(if (= n 0)
(setq n 1)
(setq pr (* n ( fact (- n 1))))
(print pr)
)
The issue is that you are supplying too many arguments to the if expression in your code. An if statement will accept at most 3 arguments:
A test expression
A 'then' expression
An optional 'else' expression
In your code, you are supplying 4 arguments:
(= n 0)
(setq n 1)
(setq pr (* n ( fact (- n 1))))
(print pr)
You are also missing a closing parenthesis.
To correct your code, the final print expression can be moved outside of the if expression, and the pr variable should be declared as a local variable i.e.:
(defun fact ( n / pr )
(if (= n 0)
(setq n 1)
(setq pr (* n (fact (- n 1))))
)
(print pr)
)
However, whilst the code is syntactically correct, you will now receive the error:
; error: bad argument type: numberp: nil
This is because, when n is 0, the variable pr is not defined and so the print expression will return nil, causing the multiplication with the return of the recursive call to fail.
However, whilst the code could be modified to define pr when n=0, this variable is not actually required, and the code may become:
(defun fact ( n )
(if (< 0 n) (* n (fact (1- n))) 1)
)
The function will now return the value of the calculated factorial:
_$ (fact 5)
120
I am writing a lisp program called pellnumbers to return a list of pell numbers. However, I always get NIL right after a test result. I am new to Lisp and do not understand much about its errors. Could you please help me out? Thank you!
Below is my code
;define a function of how to compute a pell number
(defun P (n)
(cond
((= n 0) 0)
((= n 1) 1)
(t (+ (* 2 (P (- n 1))) (P (- n 2))))))
;define an iterative function to return a sequence of pell numbers
(defun pellnumbers (n)
(prog
(setq res '())
(loop for i from 0 to n
do (setq res (append res (list (P i))))
)
(print res)))
;test cases
(print (pellnumbers 0))
(print (pellnumbers 6))
(print (pellnumbers 9))
and here is the result I get
(0)
NIL
(0 1 2 5 12 29 70)
NIL
(0 1 2 5 12 29 70 169 408 985)
NIL
NIL is not an error. It's just a a piece of data, which is both a symbol and means the empty list.
a few hints for your code:
it's unclear why you use PROG but you need to check it's syntax
The syntax of PROG:
prog
({var | (var [init-form])}*)
declaration*
{tag | statement}*
Your code lacks a list of variables. The form (setq res '()) is wrong.
Why not just use LET instead.
you need to indent your code properly
Example indent:
(defun pellnumbers (n)
(prog
(setq res '())
(loop for i from 0 to n
do (setq res (append res (list (P i)))))
(print res)))
This makes it easier to spot syntax errors. Again: your usage of PROG is a) wrong and b) not needed.
your code prints twice
There is a print statement inside the function pellnumbers and your testcases also have a print statement.
That's why two values are being printed. The result of pellnumbers is always NIL, so always NIL is printed, for any testcase in your code.
Remember that the last form evaluated is the return value. print returns NIL, and being the last form in the prog, prog returns NIL, which becomes the return value for pellnumbers.
Whether you use prog, progn or let is a matter of taste.
trying to do a dr racket problem to tell if a number is apart of list. getting errors
#lang racket
(mymember (x, l))
if l=?null
then "false"
if x==car(l)
then "true"
mymember(x,l)
mymember 2' (1,3,4,5,6)
Racket uses prefix notation. This makes commas unnecessary. First, some syntax:
How to define a function?
( define ( name variable1 variable2 ) body )
Where name is the name of the function, and the variables are the parameters. Which are followed by the body expression.
Example:
; Number -> Number
; converts from fahrenheit to celsius.
(define (f2c f)
(* 5/9 (- f 32)))
How to call a function?
( name expression1 expression2 )
name is the name of the function and expression1 and expression2 are its arguments.
Example:
(sqr 3)
;; == 9
Similarly, to check if two values are equal: (equal? x y)
How to use the if expressions?
( if question-expression then-answer-expression else-answer-expression )
If the value of the question-expression is not false, the if evaluates the then-answer-expression, otherwise it evaluates the else-answer-expression.
Example:
;; Number -> Number
;; reciprocate all non-zero x, otherwise return 0.
(define (inverse-of-x x)
(if (= x 0) 0 (/ 1 x)))
... and so on. Read the Racket Guide for the essentials on syntax, semantics and datatypes in the language.
Fixing all the syntax still leads to one error: an infinite loop. That is because the recursive call doesn't call cdr on the list. So the recursive call is made on the same list (not a shorter list) forever. Wrapping a cdr and fixing the syntax leads to a correct function.
#lang racket
; [X] [List-of X] -> "true" U "false"
; is x an element of l?
(define (mymember x l)
(if (equal? l null)
"false"
(if (equal? x (car l))
"true"
(mymember x (cdr l)))))
(mymember 2 '()) ; = false
(mymember 2 '(1 3 4 5 6)) ; = false
(mymember 2 '(1 3 2 5 6)) ; = true