From Thomas.Petzoldt at tu-dresden.de  Wed Jan 31 17:11:00 2007
From: Thomas.Petzoldt at tu-dresden.de (Thomas Petzoldt)
Date: Wed, 31 Jan 2007 17:11:00 +0100
Subject: [Rd] S4 initialize or "generating function"
In-Reply-To: <m2r6tbdyqc.fsf@fhcrc.org>
References: <45BFB590.3080405@TU-Dresden.de> <m2r6tbdyqc.fsf@fhcrc.org>
Message-ID: <45C0BF94.9020100@tu-dresden.de>

Dear Seth,

thank you for your suggestions. As I have some (shallow) inheritance I 
found indeed that initialize methods are superior. The reasons are, as 
you wrote, inheritance to subclasses and the possibility to use 
callNextMethod.

My code is now in fact much more compact with initialize in contrast to 
MyClass() constructors ("generating functions").

What I did was to create S4 objects which have an own function  slot 
"initfunc", that is called by the initialize method. In this case also 
the "cloning" behavior of initialize makes sense. It resets the S4 
object, possibly with new random start values, see the simplified example:

setClass("bar", representation(foo="numeric", initfunc="function"))
setMethod("initialize", signature(.Object="bar"),
   function(.Object, ...) {
     .Object <- callNextMethod()
     .Object <- .Object at initfunc(.Object)
     invisible(.Object)
   }
)

foobar <- new("bar",  foo = 0,
                 initfunc  = function(obj) {
                   obj at foo = rnorm(1)
                   invisible(obj)
                 }
)
foobar at foo
foobar <- initialize(foobar)
foobar at foo

One odd thing I found was that initialize does obviously not allow to 
incorporate additional named parameters which are not slots.

In essence I think that one should not use the constructor approach 
(from 2001) anymore, even if the "call is independent of the details of 
the representation".

Thank you

Thomas


Seth Falcon wrote:
 > Thomas Petzoldt <Thomas.Petzoldt at TU-Dresden.de> writes:
 >
 >> Hello,
 >>
 >> apologies if I missed something well known. I'm just revising an own
 >> package and wonder if it is still common to use "generating
 >> functions" which have the same name as the corresponding S4 class as
 >> suggested by Chambers, 2001. "Classes and Methods in the S Language".
 >>
 >> -- or should one consequently use new and initialize to do such
 >>    things?
 >
 > If you have no inheritence between the classes in your system (and are
 > pretty sure you are not going to have any) then I don't think it
 > really matters whether you define MyClass() to create new instances or
 > use new("MyClass",...).
 >
 > There is considerable advantage to having your constructors be real
 > methods when you do have inheritence relations among your classes.
 > This allows you to make use of callNextMethod to reduce code
 > duplication.
 >
 > Defining an "initialize" method and using new seems to be the standard
 > and I suspect is required if you want to plug into the validObject
 > protocol.  The "initialize" setup tries to make some strange
 > assumptions about how objects should be able to be constructed (IMO) 
[*1*].
 > Furthermore, it is a bummer to lose multiple dispatch when defining
 > constructors.
 >
 > + seth
 >
 >
 > [*1*] The default initialize method interprets named arguments as
 > slots which is a reasonable default, but not always sensible.  What I
 > find quite strange is that an un-named argument is interpreted as an
 > instance that should be cloned.
 >
 >
 >


-- 
Thomas Petzoldt
Technische Universitaet Dresden
Institut fuer Hydrobiologie        thomas.petzoldt at tu-dresden.de
01062 Dresden                      http://tu-dresden.de/hydrobiologie/
GERMANY



[Rd] S4 initialize or "generating function"
Thomas Petzoldt