Re: [R] How to move an internal function to external keeping same environment?

2010-11-15 Thread Gabor Grothendieck
On Mon, Nov 15, 2010 at 7:48 AM, Matthieu Stigler
matthieu.stig...@gmail.com wrote:
 Hi

 I have within a quite big function foo1, an internal function foo2. Now, in
 order to have a cleaner code, I wish to have the internal foo2 as
 external. This foo2 was using arguments within the foo1 environment that
 were not declared as inputs of foo2, which works as long as foo2 is within
 foo1, but not anymore if foo2 is external, as is the case now.

 Now, I could add all those arguments as inputs to foo2, but I feel if foo2
 is called often, I would be copying those objects more than required. Am I
 wrong?

 I then used this to avoid to declare explcitely each argument to foo2:

 foo1-function(x){
  b-x[1]+2
  environment(foo2)-new.env(parent =as.environment(-1))
  c-foo2(x)

 return(c)
 }

 foo2-function(x)  x*b
 #try:
 foo1(1:100)


 This works. But I wanted to be sure:

 -am I right that if I instead declare each element to be passed to foo2,
 this would be more copying than required? (imagine b in my case a heavy
 dataset, foo2 a long computation)
 -is this lines environment(foo2)-new.env(parent =as.environment(-1)) the
 good way to do it or it can have unwanted implications?


This would be good enough (replacing your environment(foo2)-... line):

environment(foo2) - environment()

If you add parameters to foo2 it won't actually copy them unless they
are modified in foo2.


-- 
Statistics  Software Consulting
GKX Group, GKX Associates Inc.
tel: 1-877-GKX-GROUP
email: ggrothendieck at gmail.com

__
R-help@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
and provide commented, minimal, self-contained, reproducible code.


Re: [R] How to move an internal function to external keeping same environment?

2010-11-15 Thread Duncan Murdoch

On 15/11/2010 7:48 AM, Matthieu Stigler wrote:

Hi

I have within a quite big function foo1, an internal function foo2. Now,
in order to have a cleaner code, I wish to have the internal foo2 as
external. This foo2 was using arguments within the foo1 environment
that were not declared as inputs of foo2, which works as long as foo2 is
within foo1, but not anymore if foo2 is external, as is the case now.

Now, I could add all those arguments as inputs to foo2, but I feel if
foo2 is called often, I would be copying those objects more than
required. Am I wrong?

I then used this to avoid to declare explcitely each argument to foo2:

foo1-function(x){
b-x[1]+2
environment(foo2)-new.env(parent =as.environment(-1))
c-foo2(x)

return(c)
}

foo2-function(x)  x*b
#try:
foo1(1:100)


This works. But I wanted to be sure:

-am I right that if I instead declare each element to be passed to foo2,
this would be more copying than required? (imagine b in my case a heavy
dataset, foo2 a long computation)
-is this lines environment(foo2)-new.env(parent =as.environment(-1))
the good way to do it or it can have unwanted implications?



I don't think modifying the environment of a closure could be seen as a 
way to get cleaner code.  I'd just leave foo2 within foo1.


There are several unwanted implications of the way you do it:

 - Setting the environment of foo2 to the foo1 evaluation frame means 
those local variables won't be garbage collected.  If foo1 creates a 
large temporary matrix, it will take up space in memory until you modify 
foo2 again.


 - If we say that foo2 has global scope (it might be limited to your 
package namespace, but let's call that global), then your foo1 has 
global side effects, and those are often a bad idea.  For example, 
suppose next week you define foo3 that also uses and modifies foo2.  
It's very easy for foo1 and foo3 to clash with conflicting use of the 
global foo2.  Don't use globals unless you really have to.


Duncan Murdoch

__
R-help@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
and provide commented, minimal, self-contained, reproducible code.


Re: [R] How to move an internal function to external keeping same environment?

2010-11-15 Thread Matthieu Stigler

Le 15. 11. 10 14:14, Duncan Murdoch a écrit :

On 15/11/2010 7:48 AM, Matthieu Stigler wrote:

Hi

I have within a quite big function foo1, an internal function foo2. Now,
in order to have a cleaner code, I wish to have the internal foo2 as
external. This foo2 was using arguments within the foo1 environment
that were not declared as inputs of foo2, which works as long as foo2 is
within foo1, but not anymore if foo2 is external, as is the case now.

Now, I could add all those arguments as inputs to foo2, but I feel if
foo2 is called often, I would be copying those objects more than
required. Am I wrong?

I then used this to avoid to declare explcitely each argument to foo2:

foo1-function(x){
b-x[1]+2
environment(foo2)-new.env(parent =as.environment(-1))
c-foo2(x)

return(c)
}

foo2-function(x)  x*b
#try:
foo1(1:100)


This works. But I wanted to be sure:

-am I right that if I instead declare each element to be passed to foo2,
this would be more copying than required? (imagine b in my case a heavy
dataset, foo2 a long computation)
-is this lines environment(foo2)-new.env(parent =as.environment(-1))
the good way to do it or it can have unwanted implications?



I don't think modifying the environment of a closure could be seen as 
a way to get cleaner code.  I'd just leave foo2 within foo1.


There are several unwanted implications of the way you do it:

 - Setting the environment of foo2 to the foo1 evaluation frame means 
those local variables won't be garbage collected.  If foo1 creates a 
large temporary matrix, it will take up space in memory until you 
modify foo2 again.


 - If we say that foo2 has global scope (it might be limited to your 
package namespace, but let's call that global), then your foo1 has 
global side effects, and those are often a bad idea.  For example, 
suppose next week you define foo3 that also uses and modifies foo2.  
It's very easy for foo1 and foo3 to clash with conflicting use of the 
global foo2.  Don't use globals unless you really have to.


Duncan Murdoch

Dear Gabor, dear Duncan

Thanks a lot both of you for your fast and interesting answer!

I have limited understanding of Duncan's points but will follow your 
advice not to do it like this. If I am nervertheless quit keen to use 
foo2 externally, is the use of either assign() in foo1, or mget() in 
foo2 more indicated? Or are the same kind of remarks raised against 
environment() also relevant for assign() and mget()?


Thanks a lot!!

Matthieu

__
R-help@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
and provide commented, minimal, self-contained, reproducible code.


Re: [R] How to move an internal function to external keeping same environment?

2010-11-15 Thread Gabor Grothendieck
On Mon, Nov 15, 2010 at 10:49 AM, Matthieu Stigler
matthieu.stig...@gmail.com wrote:
 I have limited understanding of Duncan's points but will follow your advice
 not to do it like this. If I am nervertheless quit keen to use foo2
 externally, is the use of either assign() in foo1, or mget() in foo2 more
 indicated? Or are the same kind of remarks raised against environment() also
 relevant for assign() and mget()?


Another way to approach this, which is safer, is to put it into an OO
framework creating a proto object (package proto) that contains the
shared data and make foo and foo2 its methods.

library(proto) # see http://r-proto.googlecode.com

# create proto object

p - proto()

# add foo method which stores mydata in receiver object
# and runs foo2

p$foo - function(.) { .$mydata - 1:3; .$foo2() }

# add foo2 method which grabs mydata from receiver
# and calculates result

p$foo2 - function(.) sum(.$mydata)

# run foo method - result is 6

p$foo()


-- 
Statistics  Software Consulting
GKX Group, GKX Associates Inc.
tel: 1-877-GKX-GROUP
email: ggrothendieck at gmail.com

__
R-help@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
and provide commented, minimal, self-contained, reproducible code.