Re: [R] How to change the value of a class slot

2005-06-09 Thread Ross Boylan
On Wed, 2005-06-08 at 14:15 +0200, Thomas Petzoldt wrote:
...
 Hello Ross,
 
 I see that your question was related to S4, but I just noticed a
 solution based on the R.oo package so I thought I would add a solution
 based on the proto package too. We had similar problems several times
 ago and (to my surprise) found R to be an extremely flexible language
 even for these things. Our favorite solution is available as
 package(proto). It requires R 2.1, because of several subtle
 improvements regarding environments, which made our implementation more
 streamlined.
 
 Does the following example do what you intended?

Certainly looks like it.  It seems R has an embarrassment of object
systems.  R.oo, which someone else mentioned, also has the semantics I
was thinking of.  There's an interesting paper here
http://www.ci.tuwien.ac.at/Conferences/DSC-2003/Proceedings/Bengtsson.pdf
which contrasts what I was looking for, which it calls
class-object-oriented programming (COOP) with what R does, which it
calls functional-object-oriented programming (FOOP).

The paper also notes that call-by-value vs call-by-reference, which is
the root of the slot update problem, is really orthogonal to the
FOOP/COOP distinction.  It's easy to imagine FOOP with
call-by-reference.  R.oo uses references.

That paper also mentions that Omegahat has on OOP package, which
apparently is similar in spirit to R.oo while taking a more low-level
approach to the implementation.

Ross

 
 ##=
 library(proto)
 
 ## 1) define an object
 CompletePathMaker - proto(
   index = 0,
   bumpIndex = function(., dindex = 1)
 .$index - .$index + as.integer(dindex)
 )
 
 ## 2) create a child object of CompletePathMaker
 cpm - CompletePathMaker$proto()
 
 ## 3) set the index component to 3
 cpm$index - 3
 
 ## 4) iterate the index
 cpm$bumpIndex(2)
 
 ## print the result
 cpm$index
 
 ##=

__
R-help@stat.math.ethz.ch mailing list
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide! http://www.R-project.org/posting-guide.html


Re: [R] How to change the value of a class slot

2005-06-09 Thread Ross Boylan
On Wed, 2005-06-08 at 09:13 +0200, Uwe Ligges wrote:
[extensive deletions.  Discussion concerned my desire to have a function change 
the value
 of an object in a way that had effects outside of the function, without 
returning the object.]

 You have to think about scoping rules and it 
 will be clear that the approach you are expecting is not a clean one in S.
  
  Could you say a bit more about that?  
 
 I meant the following simple example (not related to any object oriented 
 programming from the S point of view, but maybe well from your point of 
 view?):
 
 Say you want a function foo() that simply incements the argument:
 
 a - 1
 foo(a)
 a # now is 2
 
 But what happens if there is (more than) one a (in different 
 environments), but no a in the environment foo(a) is called from. 
 Which a do you want to change in this case? Seems to be rather dangerous.
 
 Uwe Ligges
 
I believe your example assumes that foo is updating the outer a by
cheating and directly modifying enclosing environments.  (I figure it
also needs to get the name of its actual argument to do this, which
would also involve slightly dirty tricks.) This does seem to be the only
way to do it in standard R.

In contrast, I wanted something like
foo-function(formalArg){ 
  formalArg - new value
  return something  else
}
so that if I call foo(a), a has the new value after the call.
Unfortunately for me, that doesn't work.  Call-by-value semantics imply
that it can't.

__
R-help@stat.math.ethz.ch mailing list
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide! http://www.R-project.org/posting-guide.html


Re: [R] How to change the value of a class slot

2005-06-09 Thread Thomas Petzoldt

Ross Boylan wrote:


I believe your example assumes that foo is updating the outer a by
cheating and directly modifying enclosing environments.  (I figure it
also needs to get the name of its actual argument to do this, which
would also involve slightly dirty tricks.) This does seem to be the only
way to do it in standard R.

In contrast, I wanted something like
foo-function(formalArg){ 
  formalArg - new value

  return something  else
}
so that if I call foo(a), a has the new value after the call.
Unfortunately for me, that doesn't work.  Call-by-value semantics imply
that it can't.


What about call by reference like this:

library(proto)

arg - proto(x=1)

foo-function(formalArg){
  formalArg$x - formalArg$x + 1.23
  #return something  else
}

foo(arg)

arg$x

[1] 2.23

Best regards

Thomas P.

__
R-help@stat.math.ethz.ch mailing list
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide! http://www.R-project.org/posting-guide.html


Re: [R] How to change the value of a class slot

2005-06-09 Thread Duncan Murdoch

On 6/9/2005 3:04 PM, Ross Boylan wrote:

On Wed, 2005-06-08 at 09:13 +0200, Uwe Ligges wrote:
[extensive deletions.  Discussion concerned my desire to have a function change 
the value
 of an object in a way that had effects outside of the function, without 
returning the object.]

You have to think about scoping rules and it 
will be clear that the approach you are expecting is not a clean one in S.
 
 Could you say a bit more about that?  

I meant the following simple example (not related to any object oriented 
programming from the S point of view, but maybe well from your point of 
view?):


Say you want a function foo() that simply incements the argument:

a - 1
foo(a)
a # now is 2

But what happens if there is (more than) one a (in different 
environments), but no a in the environment foo(a) is called from. 
Which a do you want to change in this case? Seems to be rather dangerous.


Uwe Ligges


I believe your example assumes that foo is updating the outer a by
cheating and directly modifying enclosing environments.  (I figure it
also needs to get the name of its actual argument to do this, which
would also involve slightly dirty tricks.) This does seem to be the only
way to do it in standard R.

In contrast, I wanted something like
foo-function(formalArg){ 
  formalArg - new value

  return something  else
}
so that if I call foo(a), a has the new value after the call.
Unfortunately for me, that doesn't work.  Call-by-value semantics imply
that it can't.


Here are some dirty ways to do it:

 foo - function(FormalArg, value) {
+   assign(as.character(substitute(FormalArg)), value, 
envir=sys.frame(sys.parent()))

+ }
 x
Error: Object x not found
 foo(x, 4)
 x
[1] 4

That one does the assignment in the caller's frame, not necessarily the 
place that FormalArg was found.  If you want to change a value that you 
know exists, you could do something like this:


which.env - function(name, envir = sys.frame(sys.parent())) {
if (!exists(name, envir)) stop('not found')
result - envir
while (!is.null(result)  !exists(name, result, inherits = FALSE))
  result - parent.env(result)
return(result)
}

foo - function(FormalArg, value) {
name - as.character(substitute(FormalArg))
assign(name, value, which.env(name, sys.frame(sys.parent(
}

Duncan Murdoch

__
R-help@stat.math.ethz.ch mailing list
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide! http://www.R-project.org/posting-guide.html


Re: [R] How to change the value of a class slot

2005-06-09 Thread Thomas Petzoldt

Ross Boylan wrote:


The paper also notes that call-by-value vs call-by-reference, which is
the root of the slot update problem, is really orthogonal to the
FOOP/COOP distinction.  It's easy to imagine FOOP with
call-by-reference.  R.oo uses references.


Yes, it can be found on http://www.maths.lth.se/help/R/R.oo/



That paper also mentions that Omegahat has on OOP package, which
apparently is similar in spirit to R.oo while taking a more low-level
approach to the implementation.

Ross


The Omegahat related article was in R News:

Object-Oriented Programming in R by John M. Chambers  Duncan Temple 
Lang. R News Vol. 1/3, September 2001, p 17.

http://cran.r-project.org/doc/Rnews/Rnews_2001-3.pdf


Thomas

__
R-help@stat.math.ethz.ch mailing list
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide! http://www.R-project.org/posting-guide.html


Re: [R] How to change the value of a class slot

2005-06-08 Thread Uwe Ligges

Ross Boylan wrote:


On Tue, 2005-06-07 at 08:36 +0200, Uwe Ligges wrote:


Ross Boylan wrote:



On Sat, Jun 04, 2005 at 07:08:56PM +0200, Martin Maechler wrote:



  Ross nextPath - function(pm){ #pm is a CompletePathMaker
  Ross[EMAIL PROTECTED] - [EMAIL PROTECTED](1)
  Ross [etc]

If your nextPath   function has  'pm' as its last statement it
will return the updated object, and if you call it
as
mypm - nextPath(mypm)

you are
  1) updating  mypm
  2) in a proper S way (i.e. no cheating).

Regards,
Martin



Wow.  This is almost the exact inverse of the usual object behavior,
in which only the class itself can update the slots (aka instance
variables).  None of the methods of the class can update instances of
the class persistently without the help of outsiders, and only
outsiders can change the slot values.

(Yes, I realize that using the idiom you suggest of returning a new
object one can have only class methods actually fiddling with the
slots.)

The inability of a class method to change a class object without
outside help seems unfortunate.

It looks as if instances of class objects are best thought of as
immutable once created.


Obviously, there are many definition of object oriented programming, 
and yours seems to be different from the S4 definition.


Yes. And though there are many definitions of object oriented (at
least, many implementations),  I'd say the minimum requirement to be
object oriented is to have objects that encapsulate both state (instance
variables/slots) and behavior (methods).

S4 objects do not fully encapsulate state because they require outside
assistance to alter the state of the object (with the exception of
assignment operators).  The smalltalker in me also gets nervous that
code outside the class can access the slots, but there are many object
systems that act that way.

The way in which names of methods of unrelated classes interfere with
each other seems a break-down of the encapsulation of behavior, though
the problem strictly is not with the behavior but just with the name.
To return to the concrete problem that got me started, if class
Specification defines a method likelihood taking as arguments instances
of class Specification, Path and Parameters, then it is awkward to
define a method likelihood for the class Model when that method has
arguments of class Model, Specification, data.frame, and vector,
particularly if different names for the formal arguments are desired.
(I think technically it could be done, but only in a very ugly
way--i.e., better to use different method names for the two classes).


I was going to answer your first question at first, but you have not 
given enough details - in particular it was not clear to me why your 
approach did not work. 
I assumed that you are assigning the new object 
again, which is the S way. 


I wasn't, which is why it didn't work.  I wanted the function to return
some other value than the object it was operating on.

You have to think about scoping rules and it 
will be clear that the approach you are expecting is not a clean one in S.


Could you say a bit more about that?  


I meant the following simple example (not related to any object oriented 
programming from the S point of view, but maybe well from your point of 
view?):


Say you want a function foo() that simply incements the argument:

a - 1
foo(a)
a # now is 2

But what happens if there is (more than) one a (in different 
environments), but no a in the environment foo(a) is called from. 
Which a do you want to change in this case? Seems to be rather dangerous.


Uwe Ligges



I had thought of the issue more in
terms of function calls in S being call by value, preventing updates to
the original arguments.  So the issue isn't so much the scope of the
names of function arguments (that scope being limited to the function
body), but the properties of the thing they refer to (conceptually, a
copy of the argument, not the original).

__
R-help@stat.math.ethz.ch mailing list
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide! http://www.R-project.org/posting-guide.html


__
R-help@stat.math.ethz.ch mailing list
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide! http://www.R-project.org/posting-guide.html


Re: [R] How to change the value of a class slot

2005-06-08 Thread Thomas Petzoldt

Ross Boylan wrote:

I defined an S4 class with a slot i.  Then I wrote a regular function
that attempted to increment i.


[... details deleted ...]


What do I need to do to update slot values?

Here are some possibly relevant code fragments
setClass(CompletePathMaker,
 representation(i=integer,
timeOffset=numeric, # to avoid 0's
truePaths=TruePaths)
 )
nextPath - function(pm){ #pm is a CompletePathMaker
  [EMAIL PROTECTED] - [EMAIL PROTECTED](1)
[etc]

I'm trying to make the class behave like an iterator, with i keeping
track of its location.  I'm sure there are more R'ish ways to go, but
I'm also pretty sure I'm going to want to be able to update slots.


Hello Ross,

I see that your question was related to S4, but I just noticed a
solution based on the R.oo package so I thought I would add a solution
based on the proto package too. We had similar problems several times
ago and (to my surprise) found R to be an extremely flexible language
even for these things. Our favorite solution is available as
package(proto). It requires R 2.1, because of several subtle
improvements regarding environments, which made our implementation more
streamlined.

Does the following example do what you intended?

##=
library(proto)

## 1) define an object
CompletePathMaker - proto(
 index = 0,
 bumpIndex = function(., dindex = 1)
   .$index - .$index + as.integer(dindex)
)

## 2) create a child object of CompletePathMaker
cpm - CompletePathMaker$proto()

## 3) set the index component to 3
cpm$index - 3

## 4) iterate the index
cpm$bumpIndex(2)

## print the result
cpm$index

##=

This approach is very compact and needs only one new function: proto.
Also note how simple it is conceptually. We did not even create any
classes. We just created a parent object CompletePathMaker and a child
to it, cpm, and got everything else via delegation (i.e. inheritance).


Hope it helps

Thomas P.

__
R-help@stat.math.ethz.ch mailing list
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide! http://www.R-project.org/posting-guide.html


Re: [R] How to change the value of a class slot

2005-06-07 Thread Uwe Ligges

Ross Boylan wrote:


On Sat, Jun 04, 2005 at 07:08:56PM +0200, Martin Maechler wrote:


   Ross nextPath - function(pm){ #pm is a CompletePathMaker
   Ross[EMAIL PROTECTED] - [EMAIL PROTECTED](1)
   Ross [etc]

If your nextPath   function has  'pm' as its last statement it
will return the updated object, and if you call it
as
mypm - nextPath(mypm)

you are
   1) updating  mypm
   2) in a proper S way (i.e. no cheating).

Regards,
Martin



Wow.  This is almost the exact inverse of the usual object behavior,
in which only the class itself can update the slots (aka instance
variables).  None of the methods of the class can update instances of
the class persistently without the help of outsiders, and only
outsiders can change the slot values.

(Yes, I realize that using the idiom you suggest of returning a new
object one can have only class methods actually fiddling with the
slots.)

The inability of a class method to change a class object without
outside help seems unfortunate.

It looks as if instances of class objects are best thought of as
immutable once created.


Obviously, there are many definition of object oriented programming, 
and yours seems to be different from the S4 definition.


I was going to answer your first question at first, but you have not 
given enough details - in particular it was not clear to me why your 
approach did not work. I assumed that you are assigning the new object 
again, which is the S way. You have to think about scoping rules and it 
will be clear that the approach you are expecting is not a clean one in S.


Uwe Ligges



Ross

__
R-help@stat.math.ethz.ch mailing list
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide! http://www.R-project.org/posting-guide.html


__
R-help@stat.math.ethz.ch mailing list
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide! http://www.R-project.org/posting-guide.html


RE: [R] How to change the value of a class slot

2005-06-07 Thread Ross Boylan
On Mon, 2005-06-06 at 14:15 -0700, Berton Gunter wrote:
 I'm puzzled:
 
  It looks as if instances of class objects are best thought of as
  immutable once created.
  
 
 what then is setReplaceMethod() for? 
assignment operators do the whole object replacement behind the scenes,
at least conceptually, as far as I can tell.  I agree: they are
mutators.  But outside of this special case, it seems mutation of slots
is difficult (i.e., requires the assistance of the caller).

By the way, the documentation on setReplaceMethod does not actually say
what it does.  I found out by looking at the code.

Second, in my experiments I couldn't get setReplacementMethod to work:

bumpIndex- - function(pm, value) {
  [EMAIL PROTECTED] - [EMAIL PROTECTED](value)
  pm
}

# I get an error without the next function definition
bumpIndex - function(pm) [EMAIL PROTECTED]

setReplaceMethod(bumpIndex,
 signature=signature(pm=CompletePathMaker,
   value=numeric), bumpIndex) 

When I try to load this, I get
arguments in definition changed from (spec) to (object)
arguments in definition changed from (self) to (object)
arguments in definition changed from (self) to (object)
Creating a new generic function for 'bumpIndex-' in '.GlobalEnv'
Error in conformMethod(signature, mnames, fnames, f) : 
In method for function bumpIndex-: formal arguments omitted in the
method definition cannot be in the signature (value = numeric)

All the errors are triggered by setReplaceMethod.  Can anyone help me
interpret them?  Or, maybe better, tell me how to debug the
compilation?


 I leave it to language experts to say whether S4 formal classes and
 methods are wise or not in comparison to others. From my fairly ignorant
 perspective, that always seems to be a matter of taste.

There are actually two related issues on that score: first, whether the
complex of expectation set up by talking about objects and classes
are met by what R/S does, and second the wisdom of what R/S does in its
own right.

 
 Cheers,
 Bert
 
 
-- 
Ross Boylan  wk:  (415) 502-4031
530 Parnassus Avenue (Library) rm 115-4  [EMAIL PROTECTED]
Dept of Epidemiology and Biostatistics   fax: (415) 476-9856
University of California, San Francisco
San Francisco, CA 94143-0840 hm:  (415) 550-1062

__
R-help@stat.math.ethz.ch mailing list
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide! http://www.R-project.org/posting-guide.html


Re: [R] How to change the value of a class slot

2005-06-07 Thread Ross Boylan
On Tue, 2005-06-07 at 08:36 +0200, Uwe Ligges wrote:
 Ross Boylan wrote:
 
  On Sat, Jun 04, 2005 at 07:08:56PM +0200, Martin Maechler wrote:
  
 Ross nextPath - function(pm){ #pm is a CompletePathMaker
 Ross[EMAIL PROTECTED] - [EMAIL PROTECTED](1)
 Ross [etc]
 
 If your nextPath   function has  'pm' as its last statement it
 will return the updated object, and if you call it
 as
 mypm - nextPath(mypm)
 
 you are
 1) updating  mypm
 2) in a proper S way (i.e. no cheating).
 
 Regards,
 Martin
  
  
  Wow.  This is almost the exact inverse of the usual object behavior,
  in which only the class itself can update the slots (aka instance
  variables).  None of the methods of the class can update instances of
  the class persistently without the help of outsiders, and only
  outsiders can change the slot values.
  
  (Yes, I realize that using the idiom you suggest of returning a new
  object one can have only class methods actually fiddling with the
  slots.)
  
  The inability of a class method to change a class object without
  outside help seems unfortunate.
  
  It looks as if instances of class objects are best thought of as
  immutable once created.
 
 Obviously, there are many definition of object oriented programming, 
 and yours seems to be different from the S4 definition.
Yes. And though there are many definitions of object oriented (at
least, many implementations),  I'd say the minimum requirement to be
object oriented is to have objects that encapsulate both state (instance
variables/slots) and behavior (methods).

S4 objects do not fully encapsulate state because they require outside
assistance to alter the state of the object (with the exception of
assignment operators).  The smalltalker in me also gets nervous that
code outside the class can access the slots, but there are many object
systems that act that way.

The way in which names of methods of unrelated classes interfere with
each other seems a break-down of the encapsulation of behavior, though
the problem strictly is not with the behavior but just with the name.
To return to the concrete problem that got me started, if class
Specification defines a method likelihood taking as arguments instances
of class Specification, Path and Parameters, then it is awkward to
define a method likelihood for the class Model when that method has
arguments of class Model, Specification, data.frame, and vector,
particularly if different names for the formal arguments are desired.
(I think technically it could be done, but only in a very ugly
way--i.e., better to use different method names for the two classes).

 
 I was going to answer your first question at first, but you have not 
 given enough details - in particular it was not clear to me why your 
 approach did not work. 
 I assumed that you are assigning the new object 
 again, which is the S way. 
I wasn't, which is why it didn't work.  I wanted the function to return
some other value than the object it was operating on.
 You have to think about scoping rules and it 
 will be clear that the approach you are expecting is not a clean one in S.
Could you say a bit more about that?  I had thought of the issue more in
terms of function calls in S being call by value, preventing updates to
the original arguments.  So the issue isn't so much the scope of the
names of function arguments (that scope being limited to the function
body), but the properties of the thing they refer to (conceptually, a
copy of the argument, not the original).

__
R-help@stat.math.ethz.ch mailing list
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide! http://www.R-project.org/posting-guide.html


RE: [R] How to change the value of a class slot

2005-06-07 Thread Berton Gunter
 Second, in my experiments I couldn't get setReplacementMethod to work:
 
 bumpIndex- - function(pm, value) {
   [EMAIL PROTECTED] - [EMAIL PROTECTED](value)
   pm
 }
 
 # I get an error without the next function definition
 bumpIndex - function(pm) [EMAIL PROTECTED]
 
 setReplaceMethod(bumpIndex,
  signature=signature(pm=CompletePathMaker,
value=numeric), bumpIndex) 
 


'bumpIndex' is apparently not a generic function (created by setGeneric)
signature is not an argument to setReplaceMethod 
The ... argument to setReplaceMethod must include a function to do the
replacement, which is why you need the bumpIndex function (I agree that this
is not cleanly documented, but it's fairly easy to see since
setReplaceMethod calls setMethod and that requires the function argument).

so I don't see why you expect this to work at all. At the very least,
shouldn't you do what the documentation tells you to? I think that you are
expecting R to work according to your paradigm rather than trying to
understand how it actually works. If you feel that R's paradigm (and/or
documentation) is too awful to bother with, you might consider the R.oo
package, which does OOP an entirely different way.

-- Bert Gunter



 When I try to load this, I get
 arguments in definition changed from (spec) to (object)
 arguments in definition changed from (self) to (object)
 arguments in definition changed from (self) to (object)
 Creating a new generic function for 'bumpIndex-' in '.GlobalEnv'
 Error in conformMethod(signature, mnames, fnames, f) : 
   In method for function bumpIndex-: formal arguments 
 omitted in the
 method definition cannot be in the signature (value = numeric)
 
 All the errors are triggered by setReplaceMethod.  Can anyone help me
 interpret them?  Or, maybe better, tell me how to debug the
 compilation?
 
 
  I leave it to language experts to say whether S4 formal 
 classes and
  methods are wise or not in comparison to others. From my 
 fairly ignorant
  perspective, that always seems to be a matter of taste.
 
 There are actually two related issues on that score: first, 
 whether the
 complex of expectation set up by talking about objects and classes
 are met by what R/S does, and second the wisdom of what R/S 
 does in its
 own right.
 
  
  Cheers,
  Bert
  
  
 -- 
 Ross Boylan  wk:  (415) 502-4031
 530 Parnassus Avenue (Library) rm 115-4  [EMAIL PROTECTED]
 Dept of Epidemiology and Biostatistics   fax: (415) 476-9856
 University of California, San Francisco
 San Francisco, CA 94143-0840 hm:  (415) 550-1062
 


__
R-help@stat.math.ethz.ch mailing list
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide! http://www.R-project.org/posting-guide.html


Re: [R] How to change the value of a class slot

2005-06-07 Thread Henrik Bengtsson

Berton Gunter wrote:

Second, in my experiments I couldn't get setReplacementMethod to work:

bumpIndex- - function(pm, value) {
 [EMAIL PROTECTED] - [EMAIL PROTECTED](value)
 pm
}

# I get an error without the next function definition
bumpIndex - function(pm) [EMAIL PROTECTED]

setReplaceMethod(bumpIndex,
signature=signature(pm=CompletePathMaker,
  value=numeric), bumpIndex) 





'bumpIndex' is apparently not a generic function (created by setGeneric)
signature is not an argument to setReplaceMethod 
The ... argument to setReplaceMethod must include a function to do the

replacement, which is why you need the bumpIndex function (I agree that this
is not cleanly documented, but it's fairly easy to see since
setReplaceMethod calls setMethod and that requires the function argument).

so I don't see why you expect this to work at all. At the very least,
shouldn't you do what the documentation tells you to? I think that you are
expecting R to work according to your paradigm rather than trying to
understand how it actually works. If you feel that R's paradigm (and/or
documentation) is too awful to bother with, you might consider the R.oo
package, which does OOP an entirely different way.


I have not followed the thread before, but here is an how it could look 
like with R.oo:


setConstructorS3(CompletePathMaker, function(index=0) {
  extend(Object(), CompletePathMaker,
index = as.integer(index)
  )
})

setMethodS3(increase, CompletePathMaker, function(this, dindex=+1) {
  this$index - this$index + as.integer(dindex);
  # You do not have to return anything here
})

cpm - CompletePathMaker()
cpm$index - 3
increase(cpm, 2)
print(cpm$index)

To add some control of what type of values you can assign to 'index', 
you can define a virtual field function setField(), e.g.


setMethodS3(setIndex, CompletePathMaker, function(this, index) {
  if (!is.numeric(index) || length(index) != 1)
stop(Argument 'index' must be a single numeric: , mode(index));
  if (index  0)
stop(Argument 'index' must be non-negative: , index);
  this$index - as.integer(index);
  # ... or here.
})

cpm$index - 4
cpm$index - -3  # Gives an error as wanted!

(Again...) note that setConstructorS3() and setMethodS3() are 
conveniency wrappers to define the CompletePathMaker(), 
increaseBumpIndex.CompletePathMaker() and 
setBumpIndex.CompletePathMaker(). The implementation of references is 
taken care of by the special class Object, which also implements support 
for virtual fields.


/Henrik


-- Bert Gunter





When I try to load this, I get
arguments in definition changed from (spec) to (object)
arguments in definition changed from (self) to (object)
arguments in definition changed from (self) to (object)
Creating a new generic function for 'bumpIndex-' in '.GlobalEnv'
Error in conformMethod(signature, mnames, fnames, f) : 
	In method for function bumpIndex-: formal arguments 
omitted in the

method definition cannot be in the signature (value = numeric)

All the errors are triggered by setReplaceMethod.  Can anyone help me
interpret them?  Or, maybe better, tell me how to debug the
compilation?



I leave it to language experts to say whether S4 formal 


classes and

methods are wise or not in comparison to others. From my 


fairly ignorant


perspective, that always seems to be a matter of taste.


There are actually two related issues on that score: first, 
whether the

complex of expectation set up by talking about objects and classes
are met by what R/S does, and second the wisdom of what R/S 
does in its

own right.



Cheers,
Bert




--
Ross Boylan  wk:  (415) 502-4031
530 Parnassus Avenue (Library) rm 115-4  [EMAIL PROTECTED]
Dept of Epidemiology and Biostatistics   fax: (415) 476-9856
University of California, San Francisco
San Francisco, CA 94143-0840 hm:  (415) 550-1062





__
R-help@stat.math.ethz.ch mailing list
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide! http://www.R-project.org/posting-guide.html




__
R-help@stat.math.ethz.ch mailing list
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide! http://www.R-project.org/posting-guide.html


RE: [R] How to change the value of a class slot [INFO]

2005-06-07 Thread Ross Boylan
On Tue, 2005-06-07 at 13:49 -0700, Berton Gunter wrote:
  Second, in my experiments I couldn't get setReplacementMethod to work:
  
  bumpIndex- - function(pm, value) {
[EMAIL PROTECTED] - [EMAIL PROTECTED](value)
pm
  }
  
  # I get an error without the next function definition
  bumpIndex - function(pm) [EMAIL PROTECTED]
  
  setReplaceMethod(bumpIndex,
   signature=signature(pm=CompletePathMaker,
 value=numeric), bumpIndex) 
  
...
 
  When I try to load this, I get
  arguments in definition changed from (spec) to (object)
  arguments in definition changed from (self) to (object)
  arguments in definition changed from (self) to (object)
  Creating a new generic function for 'bumpIndex-' in '.GlobalEnv'
  Error in conformMethod(signature, mnames, fnames, f) : 
  In method for function bumpIndex-: formal arguments 
  omitted in the
  method definition cannot be in the signature (value = numeric)
  
With some help from Bert, partly offlist, here's a working version:
setReplaceMethod(bumpIndex,
 signature=signature(pm=CompletePathMaker,
   value=numeric), function(pm, value) {
 [EMAIL PROTECTED] - [EMAIL PROTECTED](value)
 pm
   })
At least 2 problems were caused by my original, final argument of
bumpIndex to setReplaceMethod:
1) This looked for the function bumpIndex, not bumpIndex-.  That's why
I had to define the bumpIndex function.  With the above change, it is no
longer necessary to define bumpIndex.  I needed to point it to
bumpIndex-.  I've been unable to find how to quote that properly.

2) The bumpIndex function doesn't have the right arguments.

By the way, the use of value as the name for the final argument to the
assignment function is mandatory.

The info about value, as well as an extensive discussion of issues with
mutating objects, appear in this 2003 tutorial by Gentleman:
http://www.stat.auckland.ac.nz/S-Workshop/Gentleman/S4Objects.pdf
(thanks to Bert for the pointer).

Ross

__
R-help@stat.math.ethz.ch mailing list
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide! http://www.R-project.org/posting-guide.html


Re: [R] How to change the value of a class slot

2005-06-06 Thread Ross Boylan
On Sat, Jun 04, 2005 at 07:08:56PM +0200, Martin Maechler wrote:
 Ross nextPath - function(pm){ #pm is a CompletePathMaker
 Ross[EMAIL PROTECTED] - [EMAIL PROTECTED](1)
 Ross [etc]
 
 If your nextPath   function has  'pm' as its last statement it
 will return the updated object, and if you call it
 as
   mypm - nextPath(mypm)
 
 you are
 1) updating  mypm
 2) in a proper S way (i.e. no cheating).
 
 Regards,
 Martin

Wow.  This is almost the exact inverse of the usual object behavior,
in which only the class itself can update the slots (aka instance
variables).  None of the methods of the class can update instances of
the class persistently without the help of outsiders, and only
outsiders can change the slot values.

(Yes, I realize that using the idiom you suggest of returning a new
object one can have only class methods actually fiddling with the
slots.)

The inability of a class method to change a class object without
outside help seems unfortunate.

It looks as if instances of class objects are best thought of as
immutable once created.

Ross

__
R-help@stat.math.ethz.ch mailing list
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide! http://www.R-project.org/posting-guide.html


Re: [R] How to change the value of a class slot

2005-06-04 Thread Martin Maechler
 Ross == Ross Boylan [EMAIL PROTECTED]
 on Fri, 03 Jun 2005 17:04:08 -0700 writes:

Ross I defined an S4 class with a slot i.  Then I wrote a regular function
Ross that attempted to increment i.

Ross This didn't work, apparently because of the general rule that a 
function
Ross can't change the values of its arguments outside the function.  I 
gather
Ross there are ways around it, but the Green book admonishes cheating on 
the
Ross S evaluation model is to be avoided (p. 190).

Ross Thinking that class methods needed to an exception to this rule, I 
then
Ross tried setMethod with the function I had written.  However, when I 
called
Ross the function I got
 setMethod(nextPath, CompletePathMaker, nextPath)
Ross Creating a new generic function for 'nextPath' in '.GlobalEnv'
Ross [1] nextPath
 nextPath(pm)
Ross Error: protect(): protection stack overflow

Ross I can change the value of the slot interactively, so the problem does
Ross not appear to be that the slots are considered off-limits.

Ross What do I need to do to update slot values?

Ross Here are some possibly relevant code fragments
Ross setClass(CompletePathMaker,
Ross representation(i=integer,
Ross timeOffset=numeric, # to avoid 0's
Ross truePaths=TruePaths)
Ross )

Ross nextPath - function(pm){ #pm is a CompletePathMaker
Ross[EMAIL PROTECTED] - [EMAIL PROTECTED](1)
Ross [etc]

If your nextPath   function has  'pm' as its last statement it
will return the updated object, and if you call it
as
mypm - nextPath(mypm)

you are
1) updating  mypm
2) in a proper S way (i.e. no cheating).

Regards,
Martin

Ross I'm trying to make the class behave like an iterator, with i keeping
Ross track of its location.  I'm sure there are more R'ish ways to go, but
Ross I'm also pretty sure I'm going to want to be able to update slots.

Ross Thanks.
Ross Ross Boylan

__
R-help@stat.math.ethz.ch mailing list
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide! http://www.R-project.org/posting-guide.html