This is the mail archive of the guile@cygnus.com mailing list for the guile project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: "Current" solution for generalized set!



mdj@nada.kth.se writes:
> Here's a summary of the properties of generalized dynamic set! as they
> look now:
> 
> 1. <getter-with-setter> is a subclass of <procedure>
> 
> 2. Instances of <getter-with-setter> are created with the constructor
>    (make-getter-with-setter GETTER SETTER), and the selectors `getter'
>    and `setter' are procedures.
> 
> 3. Just as with other primitive types, like <procedure>, it is not
>    possible to create a <getter-with-setter> with `make'.
> 
> 4. Assume that G is an instance of <getter-with-setter>.
>    Then G has the following properties:
>      a) G has no slots
>      b) There exists no mutator which can alter G.
>      c) G =/= (getter G)
>      d) (G A1 ...) <=> ((getter G) A1 ...)
>      e) (set! (G A1 ...) V) <=> ((setter G) V A1 ...)
> 
> 5. The properties in 4 hold independently of Goops.  The classes in 1
>    are "pasted on" afterwards by Goops, just as for the other
>    primitive types (<symbol> etc).
> 
> 6. (define-metod (add-method! ((g <getter-with-setter>) (m <method>)))
>      (add-method! (getter g) m))
                     ^^^^^^

Why is this necessary? WOuldn't applying a getter-with-setter apply
the getter anyway and therefore have the correct semantics?

> 
>    (This assumes that add-method is a generic.  Does anyone know if
>     there is a special reason why add-method isn't a generic in
>     tiny-clos?)
> 



> 7. If the user wants to have a generic function with setters, he:
> 
>    (define g (make-getter-with-setter (make-generic) (make-generic)))
> 

That's the solution I was going to suggest, allong with the following
convenience macro (which would be useful more generally):

(defmacro define-setter (name setter)
  (let ((old-name (gensym)))
    `(let ((,old-name ,name))
       (set! ,name (make-getter-with-setter 
		    (if (getter-with-setter? ,name) 
			(getter ,name) 
			,name) 
		    ,setter)))))

The the user can freely

(define (my-getter blah1 blah2)
  (some code))

(define (my-setter blah1 blah2 value)
  (some other code))

(define-setter my-getter my-setter)

without adversely affecting compliability of the code. A smarter
`define-setter' could work more like define [allowing, e.g.

(define-setter (getter-name arg1 arg2 arg3 value)
  (some code))

] but this may be confusing.


> 8. He can add new methods to the setter with
> 
>    (add-method! (setter G) M)
> 

I am pretty sure this would work without the need for point 6, and
while making use of my above suggestion.

> 9. In order not to compromise the properties of the define-like
>    syntactic form `define-method', we introduce the new syntactic form
>    `define-setter-method' which does the right thing.
> 

Noting my above suggestion, it would even be possibly to have
`define-setter-method' automatically create a setter generic for the
generic by doing a trick like `define-setter' if it is not already a
`setter-with-getter'.

> 10. An implementation in the *current* Guile interpreter could be:
> 
>       i) Add new setter slot to all closures.  (Put a pair where the
>          current procedure properties live.  Let the car be the setter
>          slot and the cdr the property list.)
>      ii) A <getter-with-setter> is a closure with a non-#f setter slot.
> 

So you'd copy the innards of the closure when you call
`make-getter-with-setter'? For correct semantics they would have to
share code and environments....

>     No pre-created <getter-with-setter>:s exist until we have added
>     code for automatic inlining to the interpreter.
> 
> Opinions?
> 

I still think it should be called a <procedure-with-setter> (`getter'
could be interpreted as possibly referring to a macro) but I don't
care too much.

 - Maciej