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))