# SICP Solutions

### Section - 2.5 - Systems with Generic Operations

#### Exercise 2.85

Creating ‘projection’ is similar to creating ‘raise’ operation. Just need to set procedures in the respective packages. ‘drop’ is simple to implement. But as soon as I put ‘drop’ in ‘apply-generic’ the trouble started which took me quite some time debugging. Here are the problems that I faced after putting ‘drop’:

Note: I am using only 3 types in my hierarchy: rational -> scheme-number(real number) -> ‘complex. Update: Later, in ex-2.88, I have added the integer package too.

• Even drop itself stopped working! Not only ‘apply-generic’ but direct calls to ‘drop’ not working. Reason was ‘drop’ is using ‘equ?’. When it was called for ‘complex type the ‘equ?’ calls ‘equ?’ again to compare real and imaginary part. So ‘real-part is called using apply-generic. That means drop is called on the ‘real-part returned by the procedure. Now our drop, drops this to rationa-number.Thus the ‘equ of complex number should call ‘equ of rational numbers to compare the real and imag parts. But it was using =. So changed this call to call ‘equ using apply-generic.

• Now since ‘equ is also using apply-generic that means drop is evoked on the result of ‘equ. Thus drop is called on boolean!. And to add to the trouble there was a bug in my type-tag which is silently ignoring the error when (type-tag <boolean>) or any other non-typed argument is used. This is the reason why I think that static typed languages are better. Well, I fixed the type-tag and also created a proc has-type-tag? and drop first checks if that is true only then it tries to drop.

• Now the next problem happens as I try operation add to complex numbers. The problem is that now since drop is getting called on ‘real-part the real and imag part of complex numbers can be rational too! So I can not directly add two complex numbers by adding their real and imag parts. But now, ‘add’ should be used instead on ‘+’. Thus replaced all the operations +,-,*,/ with add,sub,mul, and div.

• Well thats it!

Initially I was thinking that its not a good idea that the procedures that are used by apply-generic should themselves be invoked using apply-generic(Eg: raise and projection). Because it was causing circular dependency and may go into infinite recursion. Now after implementing this procedure - and as per the requirement of this exercise operation ‘equ can not be avoided to implement and ‘equ can not work without apply-generic - that helped me in understanding that it apply-generic can also internally use itself as long as we are clear how things are working. In case of drop the recursion stops as drop drops the type to last-type possible!

So, I think now raise and projection can also be used with ‘apply-generic’ - something that I avoided for the sake of circular dependency. Another thing to wonder here is: Did I evade complexity or enhanced it by creating new table for raise/project operations? I think I should do it only with the old table but this exercise has already taken a lot of time. Probably will try later if I revisit sicp.

So here goes the complete code:

Example/Output: