[racket] How to use abstract classes?
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)