Michael Tiedtke <michele.titke@o2online.de>:
Perhaps it's better to recreate a clean object model without 3,000
lines of C code like GOOPS. But then GOOPS really creates the illusion
of an object oriented environment with a MOP ...
I'd stay away from GOOPS -- it's a leap away from functional
programming, IMO.
Here's a competing, complete object system I wrote last year:
===begin simpleton.scm==================================================
(define-module (pacujo simpleton))
;;; Return the unique serial number of the object.
(define-public (serial-number object)
(procedure-property object '%serial-number))
;(define IMPL 'HTABLE)
(define IMPL 'ALIST)
(define make-lookup-table #f)
(define associate! #f)
(define look-up #f)
(define iterate #f)
(case IMPL
((HTABLE)
(set! make-lookup-table make-hash-table)
(set! associate! hashq-set!)
(set! look-up hashq-ref)
(set! iterate hash-for-each-handle))
((ALIST)
(set! make-lookup-table (lambda () (cons #f '())))
(set! associate! (lambda (table key value)
(set-cdr! table (assq-set! (cdr table) key value))))
(set! look-up (lambda (table key) (assq-ref (cdr table) key)))
(set! iterate (lambda (proc table) (for-each proc (cdr table)))))
(else
(throw 'Huh?)))
;;; Create and return an object. Parentage must be #f, a parent object
;;; (single inheritance), or a list of parent objects (multiple
;;; inheritance).
;;;
;;; Each of the procedures must have a name and becomes a method of the
;;; object. The methods can be invoked as follows:
;;;
;;; (define object
;;; (let ()
;;; (define (my-method a b c) ...)
;;; (make-object #f my-method)))
;;; (object #:my-method 1 2 3)
;;;
;;; Any of the procedures may also be cons cells whose car is a keyword
;;; and cdr is a function. The keyword will then be used as the method
;;; name.
(define-public (make-object parentage . procedures)
(let ((methods (make-lookup-table)))
(define (object method . args)
(let ((child (procedure-property object '%child-object)))
(if child
(apply child method args)
(apply-method methods method args))))
(set-procedure-property! object '%methods methods)
(set-procedure-property! object '%serial-number (unique))
(inherit object parentage)
(let register-methods ((procedures procedures))
(cond
((null? procedures) object)
((pair? (car procedures))
(let ((procedure (cdar procedures))
(method (caar procedures)))
(associate! (methods-of object) method procedure)
(register-methods (cdr procedures))))
(else
(let* ((procedure (car procedures))
(method (symbol->keyword (procedure-name procedure))))
(associate! (methods-of object) method procedure)
(register-methods (cdr procedures))))))))
;;; Apply the parent's method, not the child object's implementation.
(define-public (delegate parent method . args)
(apply-method (methods-of parent) method args))
;;;
;;; DESIGN
;;;
;;; A "class" simply a constructor function that calls make-object,
;;; which populates the object structure with methods.
;;;
;;; Each object is a procedure with associated procedure properties
;;; (metainformation):
;;;
;;; * a lookup table ('%methods) containing the method procedures (with
;;; keywords as method keys)
;;;
;;; * an optional child object reference ('%child-object) for virtual
;;; method dispatching
;;;
;;; * a unique serial number ('%serial-number) for the potential
;;; benefit of applications (debugging, logging)
;;;
(define unique
(let ((uniq 0))
(lambda ()
(set! uniq (1+ uniq))
uniq)))
(define (inherit object parentage)
(cond
((not parentage) #f)
((list? parentage) (inherit-multi object parentage))
(else (inherit-single object parentage))))
(define (inherit-single object parent)
(iterate
(lambda (handle)
(associate! (methods-of object) (car handle) (cdr handle)))
(methods-of parent))
(set-procedure-property! parent '%child-object object))
(define (inherit-multi object parents)
(or (null? parents)
(let ((parent (car parents)))
(inherit-single object parent)
(inherit-multi object (cdr parents)))))
(define (methods-of object)
(procedure-property object '%methods))
(define (apply-method methods method args)
(let ((procedure (look-up methods method)))
(if procedure
(apply procedure args)
(error "No such method" method))))
===end simpleton.scm====================================================
All you need is the make-object function.
Marko