From: Ken A. <kan...@bb...> - 2004-01-06 22:01:31
|
At 05:19 PM 1/5/2004 -0500, bor...@ko... wrote: >Hi Ken, Timothy > >| Your definition is wrong. Try this: >| (define fact >| (let ((one (BigInteger. "1"))) >| (lambda (n) >| (if (= 0 (.intValue n)) >| one >| (.multiply n (fact (.subtract n one))))))) > >I feel ridiculous...., I typed this quickly just to check whether >BigInteger actually worked well before sending the email. Actually, i didn't see the problem until i ran my own fact in PLT Scheme and as you said, it came back right away. Then i tried yours in JScheme and it took over the machine. I don't see why it didn't run out of stack or memory eventually. > >| >And then I had to stop the evaluation of (fact (BigInteger "1000")) >| >after 20 minutes on a 1.6GHZ, 512MB laptop. Scheme >| implementations that >| >I've played with in the past would return the result almost >| right away >| >on much slower machines. >| > >| >Anyway, the concern is really practical, not just for the >| sake of it. >| >I'm getting integer overflows while trying to solve a very practical >| >problem. >| >| Have you tried using longs? > >No, I will. It may well work in my particular situation....However, in >InputPort.readWholeNumber the U.toNum(long) method is always invoked >regardless of how the number is written. And that method will yield an >Integer object whenever the constant is within the Java int range. Wouldn't >that matter in subsequent calculations? Again, I am only superficially >familiar with the code, I just starated using Jscheme. I don't think so, unless there's a JScheme bug you should report. U.toNum(long) will return an Integer or a Long, but arithmetic will work with mixed Integer and Long values. Just make sure you seed your comutation with a Long, and the result should be a Long. If that overflows, you need BigIntegers. >| >If you have thought about this and have ideas about what to do, I am >| >willing to help with coding, testing etc. >| > >| >BTW, I think Jscheme is great! >| >| Thanks! >| >| I've been thinking there should be an extension library that >| would let you do this. Perhaps we can develop one. Here's a >| simple one that provides big integers and big rational >| numbers, i've been playing with. > >I think this makes sense, but only as a workaround. When typing gets so >fine grained, and in a language without operator/function overloading, it >becomes quite difficult to make a program evolve, reuse libraries with >algorithms that one needs etc. I can't always know in advance whether I >need a big integer, a long or a 32 bit value, I can't use a library written >with longs for my "big integer problem". The fact that if I want to work Perhaps my example code confused you. What i'm proposing is one or more libraries that extend JScheme current math capabilites. You load them and + - * / ... work with all Java Primitive types as well as bignums say. This can be done with (define-method) which can handler case conversion for you. The code i sent you converted everything to BigInteger which is not idea. >with, say, precisely 32-bit integers is really cool, but I shouldn't be >forced to make that decision when I am not getting anything out of it. > >Perhaps there is a problem with the Java interfacing - those number type >distinctions seem important only for that purpose. But probably a sensible Probably, but it isn't required for a Scheme to handle bignums. So while we followed Java for compatibility JScheme is also a Scheme, though maybe not an ideal one. >method resolution can be easily found. Also, wasn't there a type casting >syntax in Jscheme for Java method invokation? I don't understand your question. JScheme lforages at the reflection interface of Java. There is no way to type cast through reflection. Typecasting is a Java issue, not a JScheme one. >I would say that it makes sense to represent integers in Jscheme with a >BigInteger whenever a Java modifier is not used in a number constant. The problem with this is that JScheme has worked hard to be a Scheme but also to snuggle close to Java. To do this we decided to use Java types whenever possible. So, if x is an Integer (.foo bar (* x x)) will work even if it overflows. I agree, that may not be ideal program behavior. But if we took your approach you'd have to write something like (.foo bar (->Integer (* x x)). Perhaps by working with you we can come up with a good approach. I'd start with a JScheme library. k |