# sicp-ex-2.83

meteorgan

```

(define (raise x) (apply-generic 'raise x))

(put 'raise 'integer
(lambda (x) (make-rational x 1)))

(put 'raise 'rational
(lambda (x) (make-real (/ (numer x) (denom x)))))

(put 'raise 'real
(lambda (x) (make-from-real-imag x 0)))

```

leafac

One other way to do the same is use the coersion table:

``` (define (integer->rational integer)
(make-rational integer 1))
(define (rational->real rational)
(define (integer->floating-point integer)
(* integer 1.0))
(make-real (/ (integer->floating-point (numer rational))
(denom rational))))
(define (real->complex real)
(make-complex-from-real-imag real 0))
>>>
(put-coersion 'integer 'rational integer->rational)
(put-coersion 'rational 'real rational->real)
(put-coersion 'real 'complex real->complex)

(define (raise number)
(define tower '(integer rational real complex))
(define (try tower)
(if (< (length tower) 2)
(error "Couldn't raise type" number)
(let ((current-type (car tower))
(next-types (cdr tower))
(next-type (car next-types)))
(if (eq? (type-tag number) current-type)
((get-coersion current-type next-type) number)
(try next-types)))))
(try tower))

```

master

I have to say, these exercises are rather difficult because it's not clear to what extent we should be creating a working system. I see that a lot of people here have been implementing everything so that all the code runs, but the feeling I get from the book is that we only need to write procedures which work in theory and y'know leave everything else up to ol' George. So anyway, I have sort of been skimming these exercises and looking at them as puzzles rather than an actual program. Anyway, this procedure doesn't really do anything because I don't have a table and can't look up any procedures, so I decided to just not bother, it is trivial to get the actual procedures, this is just the raising mechanism.

``` (define tower '(integer rational real complex))

(define (raise type)
(let ((position (memq type tower)))
(if (eq? position #f)
(error "No such datatype: " type)
(let ((this-type (car position)))
(let ((rest (cdr position)))
(if (null? rest)
this-type