Methods in Racket

Racket supports methods defined on struct types, which are similar to object-oriented programming concepts in other languages.

#lang racket

(struct rect (width height) #:transparent)

; This `area` method is defined for the `rect` struct.
(define (area r)
  (* (rect-width r) (rect-height r)))

; Methods can be defined for structs. Here's another example.
(define (perim r)
  (+ (* 2 (rect-width r)) (* 2 (rect-height r))))

(define (main)
  (let ([r (rect 10 5)])
    ; Here we call the 2 functions defined for our struct.
    (printf "area: ~a\n" (area r))
    (printf "perim: ~a\n" (perim r))

    ; In Racket, we don't need to worry about pointers.
    ; The same functions work for both the struct and a reference to it.
    (printf "area: ~a\n" (area r))
    (printf "perim: ~a\n" (perim r))))

(main)

To run the program, save it as methods.rkt and use the racket command:

$ racket methods.rkt
area: 50
perim: 30
area: 50
perim: 30

In this Racket version:

  1. We define a rect struct with width and height fields.

  2. We define area and perim functions that take a rect as an argument. These are analogous to methods in object-oriented programming.

  3. In the main function, we create a rect instance and call our defined functions on it.

  4. Unlike Go, Racket doesn’t distinguish between value and pointer receivers. The same functions work for both the struct and references to it.

  5. Racket’s functional programming paradigm means we don’t need to worry about mutating the receiving struct. If we needed to modify the struct, we would typically create a new instance with the modified values.

Next, we’ll look at Racket’s mechanism for grouping and naming related sets of functions, which is typically done through modules rather than interfaces.