Below is an abstraction for complex numbers that is implemented by means of message passing. Note that make-complex is returning a procedure, so the selectors will take in that procedure and apply the appropriate message to extract the real and imaginary components of the complex number.
(define (make-complex a b)
(lambda (message)
(cond ((= message 0) a)
((= message 1) b))))
(define (real complex-number) ; real part
(complex-number 0))
(define (imaginary complex-number) ; imaginary part
(complex-number 1))
(define (print-complex complex-number)
(display (word (real complex-number)
(if (> (imaginary complex-number) 0) '+ "")
(imaginary complex-number)
'i))
(newline))
(define (add-complex n1 n2)
(make-complex (+ (real n1) (real n2)) (+ (imaginary n1) (imaginary n2))))
(define (multiply-complex n1 n2)
(make-complex (+ (* (real n1) (real n2)) (- (* (imaginary n1) (imaginary n2))))
(+ (* (real n1) (imaginary n2)) (* (real n2) (imaginary n1)))))
(define z1 (make-complex 3 -2))
(define z2 (make-complex 1 7))