From: J. I. Gyasu on
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)))))
From: D Herring on
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)))))

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

- Daniel

(defun f (n)
(prog1
(round
(/ (- (expt (/ (+ 1 (sqrt 5)) 2) n)
(expt (/ (- 1 (sqrt 5)) 2) n))
(sqrt 5)))))

(defun g (n)
(if (> n 2)
(+ (g (- n 1))
(g (- n 2)))
1))

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

(defun i (n)
(labels ((iter (n &optional (a 0) (b 1))
(if (<= n 1)
b
(iter (1- n) b (+ a b)))))
(iter n)))


(let ((*table* nil)
(*step* 10))
(defun j (n)
"Overcomplicated memoization"
(cond ((eql n :table)
(return-from j *table*))
((eql n :step)
(return-from j *step*))
((<= n 0)
(return-from j 0))
((= n 1)
(return-from j 1)))
(do ((memos (* (length *table*) *step*)
(* (length *table*) *step*)))
((< (- n 1) memos))
(let* ((last (car (last *table*)))
(new (make-array (list *step*)))
(a (if last
(svref last (- *step* 2))
0))
(b (if last
(svref last (- *step* 1))
1)))
(dotimes (k *step*)
(setf (svref new k) (+ a b)
a b
b (svref new k)))
(setf *table* (append *table* (list new)))))
(multiple-value-bind (q r) (floor (- n 2) *step*)
(svref (nth q *table*) r))))
From: Ken Tilton on


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.

Meaning that it works so our teacher will accept it?

>
> (defun fib (n)
> (let ( (f0 0) (f1 1) (counter 1) )

loop can do let.

> (loop
> (if (>= counter n) (return-from fib f1) )

else?

> (let* ( (tmp f0) )

Where are the dependent clauses of this let*?

> (setf f0 f1) (setf f1 (+ f1 tmp)) (incf counter)))))

Loop can step.

Cool, your homework solution fails on the first fibonnaci number. That
was the only one I got right.

kt

--
http://www.theoryyalgebra.com/

"We are what we pretend to be." -Kurt Vonnegut
From: qikink on
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.
>
> (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)))))
<code>
(defun fib (n)
(cond
((= n 0) 1)
((= n 1) 1)
(t (+ (fib (- n 1)) (fib (- n 2))))
)
)
</code>
That is ur basic fibonacci program. If you want what might be a
slightly nicer textobbk, or just something to help with this, check
out "Common Lisp A gentle introduction to symbolic computation" (for
free!)
at: http://www.cs.cmu.edu/~dst/LispBook/index.html

From: Alan Crowe on
"J. I. Gyasu" <j.i.gyasu(a)nospam> writes:

> 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)))))

SETF takes any even number of arguments, not just two. So
you can write


(let ((tmp f0))
(setf f0 f1
f1 (+ f1 tmp)))

This idiom, of saving data in a temporary variable before
you overwrite it, because you need to use the old value is
supported directly by PSETF

(psetf f0 f1
f1 (+ f1 f0))

and adding another layer, the idiom of setting up some
variables and then repeatedly updating them in parallel

(let ((f0 0)
(f1 1)
(counter 1))
(loop (when (test counter) (return f1))
(psetf f0 f1
f1 (+ f1 f0)
count (+ count 1))))

is supported directly by DO

CL-USER> (dotimes (i 10)
(print (do ((current 1 (+ current previous))
(previous 0 current)
(count i (- count 1)))
((zerop count) current))))

1
1
2
3
5
8
13
21
34
55

Alan Crowe
Edinburgh
Scotland