4

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.

2 Answers 2

4
  1. You need an extra close parenthesis at the end of your function.
  2. You need a space in the first clause of the second if: (+fn1 fn2) should be (+ fn1 fn2). ELisp otherwise reads it as passing fn2 to a function named +fn1.

Couple of other style issues:

  1. A cond is a lot easier to read than nested ifs, especially using ELisp indentation style.
  2. = 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.

Sign up to request clarification or add additional context in comments.

Comments

2

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.

2 Comments

Ooh, I am missing a parenthesis... It's not after the first 'if' though, as that's supposed to be and 'if-else'. Thanks.
Ah, ok. I'm used to Scheme, which does things a bit differently. Glad I was at least somewhat helpful.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.