From: Marko Rauhamaa <marko@pacujo.net>
To: Michael Tiedtke <michele.titke@o2online.de>
Cc: "guile-user@gnu.org" <guile-user@gnu.org>
Subject: Re: Message Passing with GOOPS
Date: Thu, 25 Jun 2015 01:07:45 +0300 [thread overview]
Message-ID: <87mvzolpzi.fsf@elektro.pacujo.net> (raw)
In-Reply-To: <558B1158.4020607@o2online.de> (Michael Tiedtke's message of "Wed, 24 Jun 2015 22:21:44 +0200")
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
next prev parent reply other threads:[~2015-06-24 22:07 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-06-24 20:21 Message Passing with GOOPS Michael Tiedtke
2015-06-24 22:07 ` Marko Rauhamaa [this message]
2015-06-25 6:30 ` Michael Tiedtke
2015-06-25 9:07 ` Marko Rauhamaa
2015-06-25 10:59 ` Michael Tiedtke
2015-06-26 8:18 ` Ralf Mattes
2015-06-26 9:26 ` Marko Rauhamaa
2015-06-26 11:13 ` Pascal J. Bourguignon
2015-06-26 12:21 ` Marko Rauhamaa
2015-06-26 10:15 ` Michael Tiedtke
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://www.gnu.org/software/guile/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=87mvzolpzi.fsf@elektro.pacujo.net \
--to=marko@pacujo.net \
--cc=guile-user@gnu.org \
--cc=michele.titke@o2online.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).