[racket] Type-class-like idiom in Racket?

From: Danny Yoo (dyoo at cs.wpi.edu)
Date: Sun Mar 4 17:33:27 EST 2012

> I see that Racket has generic functions, but they see to work a bit
> differently that CLOS-style generics.  Further, like Haskell's type-classes
> I would like to be able to provide a contract for functions that take a
> Listable type:


Racket provides a general mechanism to associate properties to
structure types.  These structure type properties,

    http://docs.racket-lang.org/reference/structprops.html#(tech._structure._type._property)

allow a structure to define behavior in an extensible way.

For example,


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

#lang racket

;; Define a protocol for speaking.
(define-values (prop:speak prop:speak? prop:speak-ref)
  (make-struct-type-property 'speak))


(struct cat ()
  #:property prop:speak (lambda (x) (printf "Meow\n")))

(struct bird ()
  #:property prop:speak (lambda (x) (printf "Chirp\n")))

(struct person (name)
  #:property prop:speak (lambda (x) (printf "Hi, I'm ~a\n" (person-name x))))


(define (doolittle! entity)
  (cond
    [(prop:speak? entity)
     (printf "~a says: " entity)
     ((prop:speak-ref entity) entity)]
    [else
     (raise-type-error 'speak! "speaking animal" entity)]))

(doolittle! (cat))
(doolittle! (bird))
(doolittle! (person "Danny"))
(doolittle! 'rock)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;



In this way, we can define interfaces and implementation of those
interfaces, without the need for class infrastructure.


Posted on the users mailing list.