From: smallpond on
On Sep 19, 8:38 am, "J. I. Gyasu" <j.i.gyasu(a)nospam> wrote:
> qikink wrote:
> > On Sep 18, 9:18 pm, "J. I. Gyasu" <j.i.gyasu(a)nospam> wrote:
> >> After a bit of effort, my first working lisp code which is slightly more
> >> complex than printing "hello", it returns the nth fibonacci number.
> >> How would you lisp gurus have written the code in the proper lisp way.
> > <code>
> > (defun fib (n)
> > (cond
> > ((= n 0) 1)
> > ((= n 1) 1)
> > (t (+ (fib (- n 1)) (fib (- n 2))))
> > )
> > )
> > </code>
>
> The above one hangs while computing (fib 200)


It may be hung or it may be just pensive. Perhaps you
could write a short program that tells whether it will
eventually complete.
-- S

From: Thomas A. Russ on
"J. I. Gyasu" <j.i.gyasu(a)nospam> writes:
>
> In case you nitpick was about the count starting from 0.
>
> [1]> (defun fib (n)
> (if (= n 0) (return-from fib 0))
> (let ( (f0 0) (f1 1) (counter 1) )
> (loop
> (if (>= counter n) (return-from fib f1) )
> (let* ( (tmp f0) )
> (setf f0 f1) (setf f1 (+ f1 tmp)) (incf counter)))))

A slightly more compact version, that uses a few more of Lisp's built-in
functions:

(defun fib (n)
(if (zerop n)
0
(let ((f0 0) (f1 1))
(dotimes (i (1- n))
(psetq f0 f1
f1 (+ f1 f0)))
f1)))


--
Thomas A. Russ, USC/Information Sciences Institute
From: Giorgos Keramidas on
On Wed, 19 Sep 2007 01:22:22 -0400,
D Herring <dherring(a)at.tentpost.dot.com> wrote:
> J. I. Gyasu wrote:
>> After a bit of effort, my first working lisp code which is slightly
>> more complex than printing "hello", it returns the nth fibonacci
>> number.
>>
>> How would you lisp gurus have written the code in the proper lisp way.
>>
>> (defun fib (n)
>> (let ( (f0 0) (f1 1) (counter 1) )
>> (loop
>> (if (>= counter n) (return-from fib f1) )
>> (let* ( (tmp f0) )
>> (setf f0 f1) (setf f1 (+ f1 tmp)) (incf counter)))))

Hi J.I.,

IMHO there are too many LET forms and RETURN-FROM seems a bit "Un-Lispy"
indeed, but taste is a very personal thing, so if you like things this
way, then who are we to judge your code by our personal definition of
what is "tasteful" or "Lispy"? :-)

> Do any of these follow the proper lisp way?
> Probably not -- I'm not a guru. ;)

Nice collection you have there!

> (defun f (n) ...)
> (defun g (n) ...)
> (defun h (n)
> (loop for x from 1 upto n
> for a = 0 then b
> and b = 1 then (+ a b)
> finally (return b)))

Since [1..n] has the same size as [0..(n-1)] this version looks very
cool already, and "from 1 upto n" can be replaced with "below n":

CL-USER> (defun fib (n)
(loop for x below n
for a = 0 then b
and b = 1 then (+ a b)
finally (return b)))
CL-USER> (mapcar #'fib (loop for x from 1 upto 20 collecting x))
(1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765)
CL-USER>

One version which I didn't see listed is the one using DO, which has the
interesting property of numbering Fibonacci's starting from a 0th number
instead of a 1st:

CL-USER> (defun fib (num)
(do ((a 0 b)
(b 1 (+ a b))
(x 0 (incf x)))
((= x num) b)
nil))
CL-USER> (mapcar #'fib (loop for x below 20 collecting x))
(1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765)
CL-USER>

Then after staring at this for a while and re-ordering only a wee bit
the LOOP-based version it is trivial to also write a LOOP-based version
supporting a 0th Fibonnaci:

CL-USER> (defun fib (num)
(loop for a = 0 then b
and b = 1 then (+ a b)
for x below num
finally (return b)))
CL-USER> (mapcar #'fib (loop for x below 20 collecting x))
(1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765)
CL-USER>

In general, I tend to avoid DO if I can help it, but in this case it
helped me understand more about the way LOOP works, so _thanks_ for
triggerring this with your initial collection :)

- Giorgos

From: Giorgos Keramidas on
On Wed, 19 Sep 2007 08:38:34 -0400, "J. I. Gyasu" <j.i.gyasu(a)nospam> wrote:
> qikink wrote:
>> On Sep 18, 9:18 pm, "J. I. Gyasu" <j.i.gyasu(a)nospam> wrote:
>>> After a bit of effort, my first working lisp code which is slightly more
>>> complex than printing "hello", it returns the nth fibonacci number.
>>> How would you lisp gurus have written the code in the proper lisp way.
>> <code>
>> (defun fib (n)
>> (cond
>> ((= n 0) 1)
>> ((= n 1) 1)
>> (t (+ (fib (- n 1)) (fib (- n 2))))
>> )
>> )
>> </code>
>
> The above one hangs while computing (fib 200)

Try tracing it and watch the recursions unfold in their magnificent
glory :)

From: Giorgos Keramidas on
On 19 Sep 2007 13:27:07 -0700, tar(a)sevak.isi.edu (Thomas A. Russ) wrote:
> A slightly more compact version, that uses a few more of Lisp's
> built-in functions:
>
> (defun fib (n)
> (if (zerop n)
> 0
> (let ((f0 0) (f1 1))
> (dotimes (i (1- n))
> (psetq f0 f1
> f1 (+ f1 f0)))
> f1)))

Nice, but somehow it doesn't feel right when it yields:

CL-USER> (fib -10)
1
CL-USER>

Tweaking it a bit by replacing (zerop n) with (< n 1), may be a good
idea, but that's nit-picking now :)