Interfaces in Scheme

In Scheme, we can define interfaces using generic functions or procedures. We’ll implement a similar concept to demonstrate geometric shapes and their calculations.

(use-modules (ice-9 format))

;; Define generic procedures for our "interface"
(define-generic area)
(define-generic perim)

;; Define a record type for rectangle
(define-record-type <rect>
  (make-rect width height)
  rect?
  (width rect-width)
  (height rect-height))

;; Define a record type for circle
(define-record-type <circle>
  (make-circle radius)
  circle?
  (radius circle-radius))

;; Implement area and perim for rectangle
(define-method (area (r <rect>))
  (* (rect-width r) (rect-height r)))

(define-method (perim (r <rect>))
  (* 2 (+ (rect-width r) (rect-height r))))

;; Implement area and perim for circle
(define-method (area (c <circle>))
  (* 3.14159265358979323846 (square (circle-radius c))))

(define-method (perim (c <circle>))
  (* 2 3.14159265358979323846 (circle-radius c)))

;; Generic measure function
(define (measure shape)
  (format #t "Shape: ~a~%" shape)
  (format #t "Area: ~a~%" (area shape))
  (format #t "Perimeter: ~a~%~%" (perim shape)))

;; Main procedure
(define (main)
  (let ((r (make-rect 3 4))
        (c (make-circle 5)))
    (measure r)
    (measure c)))

;; Run the main procedure
(main)

In this Scheme implementation:

  1. We use generic procedures area and perim to define our “interface”.

  2. We define record types <rect> and <circle> to represent rectangles and circles.

  3. We implement the area and perim methods for both rectangles and circles using define-method.

  4. The measure function takes any shape that implements the area and perim methods and prints its measurements.

  5. In the main procedure, we create instances of a rectangle and a circle, then call measure on each.

To run this program, save it to a file (e.g., geometric-shapes.scm) and execute it using a Scheme interpreter that supports GOOPS (GNU Object-Oriented Programming System), such as Guile:

$ guile geometric-shapes.scm
Shape: #<rect 7f8d5285e7e0>
Area: 12
Perimeter: 14

Shape: #<circle 7f8d5285e820>
Area: 78.5398163397448
Perimeter: 31.4159265358979

This Scheme implementation demonstrates the concept of interfaces using generic functions, allowing us to define a common interface for different shapes and perform calculations on them in a polymorphic manner.