guile-user
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: GOOPS constructors


From: Marko Rauhamaa
Subject: Re: GOOPS constructors
Date: Fri, 25 Jul 2014 13:26:34 +0300
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/23.3 (gnu/linux)

Barry Fishman <address@hidden>:

> I am probably not the best person to go into this. I am more familiar
> with CLOS.
>
> As Tobias Brandt previous described, you can do what you want with
> overriding the initialization method.  I just find the resulting
> code harder to read, and conceptually a bit fuzzy.

I'm actually making a realization that GOOPS is probably not what I
want. The answer is much closer:

  <URL: https://www.gnu.org/software/guile/manual/html_node/OO-C
  losure.html#OO-Closure>

I have written a tiny (= 61 lines at the moment) object system based on
that idea. Namely, I don't need classes, I only need objects and
convenient dispatching.

Python is notorious for ducktyping: an object is judged by its personal
behavior and not by its membership in a class. However, even Python is
keen on the "class" keyword, and it assigns each object a type or class.
For the most part, Python's classes are equivalent to (constructor)
functions. So why not take that principle further and renounce the
existence of classes altogether?

In practice, Python's classes are very good. The only downside is that
when you need to construct one-off objects with special methods, you
must first create an one-off inner class and then construct your object.
It would be much cleaner and Scheme-like to just construct your one-off
object with a lambda constructor that sets the methods without bothering
to name a class.

This becomes a practical issue in network programming, where you deal
with state machines. You could of course organize your state machine
matrix in functions that dispatch on states:

   (define (received-eof)
      (case state
       ((#:IDLE) ...)
       ((#:READY) ...)
       ((#:SHUTTING-DOWN) ...)
       (else ...)))

   (set! state #:IDLE)

(which Python couldn't do, BTW). However, I find it elegant to employ
the state pattern:

   (define (<IDLE>)
     (define (received-eof)
        ...)
     (make-object #f #f received-eof)))

   (set! state (<IDLE>))

where "make-object" is from my tiny object system.

What's specially appealing with this kind of object system (as opposed
to GOOPS or Python) is that slot handling is more natural, IMO. For
example:

   (define (<point> .x .y)
     (define (x) .x)
     (define (y) .y)
     (define (reset! x y) (set! .x x) (set! .y y))
     (define (clear!) (reset! 0 0))
     (make-object #f #f x y reset! clear!))

Now,

   (let ((p (<point> 3 4)))
     (-> p x))
   =>
   3

(I'm still looking for the most elegant syntax for method dispatching. I
don't particularly like the looks of (p 'x). Maybe (p #:x).)


Marko



reply via email to

[Prev in Thread] Current Thread [Next in Thread]