Reputation: 7317
I'm trying to learn Lisp (elisp, actually), and I tried writing the following function as an exercise Project Euler Problem 2
(defun sumfib (n fn1 fn2 sum)
"Calculate Fibonacci numbers up to 4,000,000 and sum all the even ones"
(if (< 4000000 (+ fn1 fn2))
sum
(if (equal n 3)
(sumfib 1 (+ fn1 fn2) fn1 (+ sum (+fn1 fn2)))
(sumfib (+ n 1) (+ fn1 fn2) fn1 sum)))
When I evaluate it I get the following error:
Debugger entered--Lisp error: (void-variable fn1)
(+ fn1 fn2)
(< 4000000 (+ fn1 fn2))
...
Why wouldn't it recognize fn1? If I try to put (+ fn1 fn2) before the 'if' it doesn't complain about it there, so why the error here?
Also, I realize the function may not actually be correct, but for now I'm not worried about the logic - I'll figure that out later. For now, I'm only interested in understanding this error.
Upvotes: 4
Views: 2347
Reputation: 18399
(+fn1 fn2)
should be (+ fn1 fn2)
. ELisp otherwise reads it as passing fn2
to a function named +fn1
.Couple of other style issues:
cond
is a lot easier to read than nested ifs, especially using ELisp indentation style.=
is the normal predicate used for comparing numbers, not equal
. Although equal
will work, it looks funny to the reader. (At least it does in all the other Lisps I know, I could be wrong because I don't know ELisp as well.)Here's how I'd restructure the function.
(defun sumfib (n fn1 fn2 sum)
"Calculate Fibonacci numbers up to 4,000,000 and sum all the even ones"
(cond
((< 4000000 (+ fn1 fn2)) sum)
((= n 3) (sumfib 1 (+ fn1 fn2) fn1 (+ sum (+ fn1 fn2))))
(t (sumfib (1+ n) (+ fn1 fn2) fn1 sum))))
I ran it, and it returns an answer, but I don't know if it's right according to the project euler specification.
Upvotes: 4
Reputation: 2609
Not sure if this solves your problem (I don't have an elisp interpreter handy), but you're missing a right paren. There should be one at the end of the first 'if' statement, after 'sum'.
(if (< 4000000 (+ fn1 fn2))
sum)
instead of:
(if (< 4000000 (+ fn1 fn2))
sum
I also think there might be some other issues in there.
Upvotes: 2