Subject: Re: R5RS Implementors Pitfalls
From: rpw3@rpw3.org (Rob Warnock)
Date: Sat, 01 Mar 2003 05:56:23 -0600
Newsgroups: comp.lang.scheme
Message-ID: <-wGdnV790tR6Av2jXTWc-w@speakeasy.net>
William D Clinger <cesura@qnci.net> wrote:
+---------------
| Scott G. Miller wrote:
| > Here are the results for the Schemes in the pitfall test, except for 
| > Larceny which I still don't have access to:
| 
| Here are the results for all versions of Larceny:
|                      Expected Value
|                   256    524289 2097156
|  Larceny:         Pass   Pass   Fail
+---------------

Not wishing to start any language wars, but just because I'm doing
a lot of CL programming these days and seem to be comparing stuff I
used to do in Scheme to CL, I rewrote "bignumtest" in CL and ran it
in CLISP & CMUCL [that is, this is an *implementation* comparison,
not a language comparison]:

	(defun bignumtest (A)
	  (labels ((bntrecursion (B C D)
		     (cond ((> D A)   A)
		           ((or (not (integerp B)) (> C B)) (- D 1))
		           (t (bntrecursion (* 2 B) B (1+ D))))))
	    (let* ((two^a (expt 2 A))
		   (two^a-1 (floor two^a 2)))
	      (if (and (integerp two^a)
		       (integerp two^a-1)
		       (< two^a-1 two^a)
		       (= two^a (+ two^a-1 two^a-1)))  
		a 
		(bntrecursion 2 0 1)))))

For those not familiar with CL, I had to make these substitutions
when tranliterating:

	Internal define a.k.a. letrec => labels
	(exact?	x)                    => (integerp x)
	(inexact? x)                  => (not (integerp x))
	(quotient x y)                => (floor x y)  ;ignore 2nd return val

After compiling "bignumtest", I ran this loop in the REPL:

	(loop for i from 10 to 30 do
          (let ((n (expt 2 i)))
            (format t "~a => ~a~%" n (bignumtest n)))
          (force-output))	; print as much as possible before crashing

Results from CLISP (in under 2 sec.):

	1024 => 1024
	2048 => 2048
	4096 => 4096
	8192 => 8192
	16384 => 16384
	32768 => 32768
	65536 => 65536
	131072 => 131072
	262144 => 262144
	524288 => 524288
	1048576 => 1048576
	*** - overflow during multiplication of large numbers
	1. Break [14]> 

Initial results from CMUCL ("instantly"):

	1024 => 1024
	2048 => 2048
	4096 => 4096
	8192 => 8192
	Error in function KERNEL::INTEXP:
	   The absolute value of 16384 exceeds *INTEXP-MAXIMUM-EXPONENT*.
	Restarts:
	  0: [CONTINUE] Continue with calculation.
	  1: [ABORT   ] Return to Top-Level.
	Debug  (type H for help)

But then I discovered that giving the continue restart to the debugger
simply bumped the dynamic limit "*intexp-maximum-exponent*" [a CMUCL
non-standard implementation-specific variable] by a factor of two and
kept going, so I changed the test to the following, with somewhat more
useful results (~2 sec, total):

        > (let ((*intexp-maximum-exponent* most-positive-fixnum))
            (loop for i from 10 to 30 do
              (let ((n (expt 2 i)))
                (format t "~a => ~a~%" n (bignumtest n)))
              (force-output)))
	1024 => 1024
	2048 => 2048
	4096 => 4096
	8192 => 8192
	16384 => 16384
	32768 => 32768
	65536 => 65536
	131072 => 131072
	262144 => 262144
	524288 => 524288
	1048576 => 1048576
	2097152 => 2097152
	4194304 => 4194304
	8388608 => 8388608
	16777216 => 16777216
	33554432 => 33554432
	67108864 => 67108864
	134217728 => 134217728
	268435456 => 268435456
	Error in function KERNEL::INTEXP:
	   The absolute value of 536870912 exceeds *INTEXP-MAXIMUM-EXPONENT*.

When I tried to continue, I got:

	Type-error in KERNEL::OBJECT-NOT-FIXNUM-ERROR-HANDLER:
	   536870912 is not of type FIXNUM

so I stopped there.


-Rob

p.s. Almost forgot: 'twas a 1.4 GHz Athlon ("1600+").

-----
Rob Warnock, PP-ASEL-IA		<rpw3@rpw3.org>
627 26th Avenue			<URL:http://rpw3.org/>
San Mateo, CA 94403		(650)572-2607