[racket] How to use abstract classes?

From: Matthias Felleisen (matthias at ccs.neu.edu)
Date: Wed Aug 24 11:08:03 EDT 2011

Don't export the class. Instead export a macro that allows class derivation. If you can't trust yourself within a module, re-define the new syntax. That's what Robby says in code. 

#lang racket/load 

(module new racket
  (provide [rename-out [new-again new]] abstract)
  
  (define abstract-classes '())
  
  ;; class -> void 
  (define (abstract c)
    (set! abstract-classes (cons c abstract-classes))
    c)
  
  ;; class -> object
  (define-syntax-rule
    (new-again c r ...)
    ;; ==>>
    (if (memq c abstract-classes)
        (error 'new "~a is an abstract class" (object-name c))
        (new c r ...))))

(module sample racket
  (require 'new)
  (provide inherit-from-a%)
  
  (define a%
    (abstract
     (class object% 
       (super-new)
       (define/public (m) (displayln 'super) (send this mm 42)))))
  
  (define-syntax-rule
    (inherit-from-a% clauses ...)
    (class a% clauses ...))
    
  (define b% 
    (class a% 
      (super-new)
      (define/public (mm x) (displayln `(b ,x)))))
  
  (send (new b%) m)
  
  (define a (with-handlers ((exn:fail? displayln)) (new a%))))

(require 'sample)

(module second-sample racket
  (require 'sample)
  
  (define c% 
    (inherit-from-a% 
     (super-new)
     (define/public (mm x) (displayln `(c ,x)))))
  
  (send (new c%) m))

(require 'second-sample)
       


Posted on the users mailing list.