(((1 2 3)) 4 . #7=(((5 . #7#))))
If so, why? ; Use declarations in math utilities:
(defun sq (x)
(declare (long-float x))
(* x x))
(defun mag (x y z)
(declare (long-float x y z))
(sqrt (+ (sq x) (sq y) (sq z))))
(defun unit-vector (x y z)
(declare (long-float x y z))
(let ((d (mag x y z)))
(declare (long-float d))
(values (/ x d) (/ y d) (/ z d))))
(defstruct (point (:conc-name nil))
x y z)
(defun distance (p1 p2)
(mag (- (x p1) (x p2))
(- (y p1) (y p2))
(- (z p1) (z p2))))
(defun minroot (a b c)
(declare (long-float a b c))
(if (zerop a)
(/ (- c) b)
(let ((disc (- (sq b) (* 4 a c))))
(declare (long-float disc))
(unless (minusp disc)
(let ((discrt (sqrt disc)))
(declare (long-float discrt))
(min (/ (+ (- b) discrt) (* 2 a))
(/ (- (- b) discrt) (* 2 a))))))))
However, the running time slowed down as a result of this change, rather than sped up.Note that I used long-floats, rather than double-floats, because, when I used double-floats, the output was slightly different (only off by 1 on some values) than the original version in which variables were undeclared. However, the output was slightly different with long-floats, too, so I guess that didn't help.
Anyway, should declaring these variables make the program faster, or am I doing the problem incorrectly? And why is the output slightly different if I'm using the largest size floating-points? Below is the diff:
diff "spheres.pgm copy" spheres.pgm
125c125
< 62
---
> 61
179c179
< 62
---
> 61
6837,6838c6837,6838
< 41
< 117
---
> 42
> 118
6866,6867c6866,6867
< 117
< 41
---
> 118
> 42
7028c7028
< 22
---
> 23
7076c7076
< 22
---
> 23
7138c7138
< 114
---
> 113
7166c7166
< 114
---
> 113
7226c7226
< 118
---
> 117
7278c7278
< 118
---
> 117
7416,7417c7416,7417
< 85
< 54
---
> 84
> 53
7434c7434
< 85
---
> 86
7470c7470
< 85
---
> 86
7487,7488c7487,7488
< 54
< 85
---
> 53
> 84
7531c7531
< 19
---
> 18
7539c7539
< 18
---
> 19
7565c7565
< 18
---
> 19
7573c7573
< 19
---
> 18
7831c7831
< 117
---
> 116
7873c7873
< 117
---
> 116
7937c7937
< 19
---
> 18
7967c7967
< 19
---
> 18
8006c8006
< 107
---
> 108
8008c8008
< 128
---
> 127
8018c8018
< 24
---
> 23
8086c8086
< 24
---
> 23
8096c8096
< 128
---
> 127
8098c8098
< 107
---
> 108
8152c8152
< 164
---
> 163
8707c8707
< 110
---
> 111
8797c8797
< 110
---
> 111 (union '(a a) '(a b))
would return (a b)
And, in fact, it does. This led me to think that (union '(a a) '(b))
would also return (A B)
However, it returns: (A A B)
Why does the fact that there is one less 'a in the second argument in the second call mean that there is one more 'a in the result? This is definitely not set-theoretic union. Why is the behavior of Lisp union defined this way?Here is the sequence of calls again:
[1]> (union '(a a) '(a b))
(A B)
[2]> (union '(a a) '(b))
(A A B) (defmacro ntimes (n &rest body)
(let ((h (gensym)))
`(let ((,h ,n))
(if (> ,h 0)
,@body)
(if (zerop ,h)
nil
(ntimes (1- ,h) ,@body)))))
Using GNU CLISP 2.44, this works fine. However, when I use SBCL 1.0.6 via Cusp v0.8.174 and do the following call: (ntimes 10
(princ "."))
I get the following error:Control stack exhausted (no more space for function call frames). This is probably due to heavily nested or infinitely recursive function calls, or a tail call that SBCL cannot or has not optimized away.
What exactly is going on here? Is my solution correct and SBCL is wrong, or is my solution incorrect but it just happens to work on CLISP?