The purpose of this assignment is to help you get acquainted with pure object-oriented programming. The assignment is divided into three parts.
You will find a uSmalltalk interpreter in [[~cs152/bin/usmalltalk]]; useful sources are in [[~cs152/software/bare/usmalltalk]] and are part of the textbook software distribution. This interpreter treats the variable [[&trace]] specially; by defining it, you can trace message sends and answers. It is an invaluable aid to debugging.
The textbook software distribution also includes copies of the initial basis, collection classes, financial history, and other examples from the textbook. These examples can also be found in [[~cs152/software/examples]].
To solve all four problems, you shouldn't need to add or change more than 20 lines of code in total.
Notes and hints:
To implement method caching in an earlier version of uSmalltalk, I had to add or change about 40 lines of ML code.
My [[Natural]] class is over 100 lines of uSmalltalk code; my large-integer classes are 22 lines apiece. My modifications to predefined number classes are about 25 lines.
You will find bignums and the bignum algorithms discussed at some length in Dave Hanson's book and in the article by Per Brinch Hansen. Be aware that your assignment below differs significantly from the implementation in Hanson's book.
1! = 1 2! = 2 3! = 6 4! = 24 5! = 120 6! = 720 7! = 5040 8! = 40320 9! = 362880 10! = 3628800 11! = 39916800 12! = 479001600 13! = 6227020800 14! = 87178291200 15! = 1307674368000 16! = 20922789888000 17! = 355687428096000 18! = 6402373705728000 19! = 121645100408832000 20! = 2432902008176640000 21! = 51090942171709440000 22! = 1124000727777607680000 23! = 25852016738884976640000 24! = 620448401733239439360000 25! = 15511210043330985984000000Be warned that this test by itself is inadequate. You will want other tests.
If you want to make comparisons with a working implementation of bignums, the languages Scheme, Icon, and Haskell all provide such implementations. (Be aware that the real Scheme [[define]] syntax is slightly different from what we use in uScheme.)
For extra credit, try the following variations on your implementation of class [[Natural]]:
Largest base. Change the base to the largest reasonable base, not necessarily a power of 10. You will have to re-implement [[decimal]] using long division. Measure the time needed to compute and print the first 50 factorials. Does the smaller number of digits recoup the higher cost of converting to decimal?
Comparisons. Make sure comparisons work, even with mixed kinds of integers. So for example, make sure comparisons such as [[(< 5 (* 1000000 1000000))]] produce sensible answers.
Space costs. Instrument your [[Natural]] class to keep track of the size of numbers, and measure the space cost of the different bases. Estimate the difference in garbage-collection overhead for computing with the different bases, given a fixed-size heap.
Pi (hard). Use a power series to compute the first 100 digits of pi (the ratio of a circle's circumference to its diameter). Be sure to cite your sources for the proper series approximation and its convergence properties. Hint: I vaguely remember that there's a faster convergence for pi over 4. Check with a numerical analyst.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;; ;;;; solution to Exercise 4 (class Array ... )
Submit code using the submit-small script on nice.