Posts

Showing posts from July, 2018

SICP Exercise 2.86 complex numbers with abstract parts

Exercise 2.86.   Suppose we want to handle complex numbers whose real parts, imaginary parts, magnitudes, and angles can be either ordinary numbers, rational numbers, or other numbers we might wish to add to the system. Describe and implement the changes to the system needed to accommodate this. You will have to define operations such as   sine   and   cosine   that are generic over ordinary numbers and rational numbers. SOLUTION The code and tests are here . Here I have changed the generic procedures (real-part) and (imag-part) to (REAL-PART) and  (IMAG-PART) in order to avoid name-conflicts with the Racket primitives (real-part) and (imag-part). I  am using these primitives to understand more about Racket numbers.

SICP Exercise 2.85 simplify with drop

Exercise 2.85.    This section mentioned a method for ``simplifying'' a data object by lowering it in the tower of types as far as possible. Design a procedure  drop  that accomplishes this for the tower described in exercise  2.83 . The key is to decide, in some general way, whether an object can be lowered. For example, the complex number 1.5 + 0 i  can be lowered as far as  real , the complex number 1 + 0 i  can be lowered as far as  integer , and the complex number 2 + 3 i cannot be lowered at all. Here is a plan for determining whether an object can be lowered: Begin by defining a generic operation  project  that ``pushes'' an object down in the tower. For example, projecting a complex number would involve throwing away the imaginary part. Then a number can be dropped if, when we  project  it and  raise  the result back to the type we started with, we end up with something equal to what we started with. Show how to implement this idea in detail, by writing a  drop

SICP Exercise 2.84 apply-generic with raise

Image
Exercise 2.84.    Using the  raise  operation of exercise  2.83 , modify the  apply-generic  procedure so that it coerces its arguments to have the same type by the method of successive raising, as discussed in this section. You will need to devise a way to test which of two types is higher in the tower. Do this in a manner that is ``compatible'' with the rest of the system and will not lead to problems in adding new levels to the tower. SOLUTION The code and tests are here .

SICP Exercise 2.83 raise within the tower

Exercise 2.83.    Suppose you are designing a generic arithmetic system for dealing with the tower of types shown in figure  2.25 : integer, rational, real, complex. For each type (except complex), design a procedure that raises objects of that type one level in the tower. Show how to install a generic  raise  operation that will work for each type (except complex). SOLUTION The code and tests are here .

SICP Exercise 2.82 coercion with multiple arguments

Image
Exercise 2.82.    Show how to generalize  apply-generic  to handle coercion in the general case of multiple arguments. One strategy is to attempt to coerce all the arguments to the type of the first argument, then to the type of the second argument, and so on. Give an example of a situation where this strategy (and likewise the two-argument version given above) is not sufficiently general. (Hint: Consider the case where there are some suitable mixed-type operations present in the table that will not be tried.) SOLUTION The code and tests are here . Explanation of why this strategy is not sufficiently general Let's assume that we need to support the following operation on three arguments. This  function expects the first two arguments x and y to be of any types and the third one "factor"  to be an ordinary number. It multiples c1 and c2 and scales the result to the value of factor. Suppose the following implementations exist in the op-table for the operation

SICP Exercise 2.81 coercion

Exercise 2.81.    Louis Reasoner has noticed that  apply-generic  may try to coerce the arguments to each other's type even if they already have the same type. Therefore, he reasons, we need to put procedures in the coercion table to "coerce" arguments of each type to their own type. For example, in addition to the  scheme-number->complex  coercion shown above, he would do: (define (scheme-number->scheme-number n) n) (define (complex->complex z) z) (put-coercion 'scheme-number 'scheme-number               scheme-number->scheme-number) (put-coercion 'complex 'complex complex->complex) a. With Louis's coercion procedures installed, what happens if  apply-generic  is called with two arguments of type  scheme-number  or two arguments of type  complex  for an operation that is not found in the table for those types? For example, assume that we've defined a generic exponentiation operation: (define (exp x y) (apply-generic 'exp