proto and baseenv()

classic Classic list List threaded Threaded
27 messages Options
12
Reply | Threaded
Open this post in threaded view
|

Re: proto and baseenv()

Duncan Murdoch
On 26/02/2010 7:09 AM, Gabor Grothendieck wrote:

> On Fri, Feb 26, 2010 at 12:41 AM, Peter Danenberg <[hidden email]> wrote:
>>> Also other object systems which are alternatives to proto seem less
>>> relevant than basic scoping and free variable lookup in functions.
>> Sorry, but that seems absurd; object systems are less relevant to each
>> other than the totally orthogonal question of scope?
>
> Yes, if you are using one then obviously you have decided to use it in
> place of the other.  Also your example of S3 was misleading since it
> used lists which do not have inheritance and did not truly illustrate
> S3.  Free variables in S3 methods follow the same lookup procedure as
> ordinary functions and using S3 together with proto works well.  In
> fact, proto uses two S3 classes.
>
>>> proto does that but uses the consistent default rather than the
>>> inconsistent default that you prefer.
>> $.proto falls back upon get(), I presume, because the authors didn't
>> feel like recursing up the parent hierarchy themselves; I'll continue
>> to believe that the scope pollution was an oversight until they
>> contradict me. At which point I'll probably switch object systems.
>
> Here I think you are admitting that the basic facilities of R do work
> in the way proto does.
>
> Also, your alternative likely would be unusable due to performance
> whereas proto is fast enough to be usable (see list of applications
> that use it at http://r-proto.googlecode.com/#Applications).  Its not
> as fast as S3 (though sometimes you can get it that fast by optimizing
> your code).  The development version of proto is even faster than the
> current version of proto due to the addition of lazy evaluation.
>
>> Vague appeals to consistency, when you're really only talking about
>> naive get() semantics, don't mean much; especially after you've spent
>> hours debugging mysterious bugs resulting from scope pollution.
>
> In end it seems that your real beef is with R so perhaps you should be
> using a different language.
>
> With respect to proto its really just discussing whether to use
>
> proto(baseenv(), ...) vs proto(...)

I would say the default behaviour makes more sense.  There are very few
circumstances in R where scoping makes locals and base variables
visible, *but nothing else*.  I think users would be surprised that

a$ls()

works, but

a$str()

fails (because str() is in utils, ls() is in base).  Effectively what
the current default says is that objects inherit from the current
environment.  That's how environments work in R.

One thing that I dislike about scoping in R is the fact that even in a
namespace, searches eventually get to the global environment.  I'd
prefer if namespace searches went through the imported namespaces and
nothing else.  If that were the case, then the a$z example would never
find a z in the global environment, and that example would only be a
problem for people fiddling around in the console, not programming
carefully in a package.  But again, this is a criticism of R, not of
proto.  (I believe the reason for the current behaviour is to support
finding S3 methods:  a user should be able to define a new class and an
S3 method for it, and R should find it even if the writer of the
original generic knew nothing about the new class or method.  This
outside-the-namespace search is needed for that, but I'd prefer it if it
were more limited.)

Duncan Murdoch

>
> since the former gives you everything you want and the distinction
> seems pretty trivial given how easy it is to use one or the other.  If
> you used iolanguage or similar you would have to specify Object so
> there is not even a penalty in terms of compactness.
>
> There have also been threads on how to "fix" scoping in R for
> individual functions and various manipulations of environments have
> been suggested but in the end no one does this in practice.  In proto
> at least you can do the part you want and its trivial to do so.
>
> ______________________________________________
> [hidden email] mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel

______________________________________________
[hidden email] mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel
Reply | Threaded
Open this post in threaded view
|

Re: proto and baseenv()

Ben Escoto
In reply to this post by Gabor Grothendieck

> In end it seems that your real beef is with R so perhaps you should
> be using a different language.

In my case you may be right.  I do think there are a million things
wrong with R.  For instance, I was looking for a package that
overcomes two of the problems R IMHO has: namespace pollution and the
lack of an easy-to-use standard object system.

Should I be using R?  I do keep asking myself that same question...

> With respect to proto its really just discussing whether to use
> proto(baseenv(), ...) vs proto(...)

Unfortunately this doesn't fix the problem as was noted earlier:

> z <- 1
> proto(baseenv(), expr={a <- z})$a
Error in eval(expr, envir, enclos) : object "z" not found

> Also, your alternative likely would be unusable due to performance
> whereas proto is fast enough to be usable (see list of applications
> that use it at http://r-proto.googlecode.com/#Applications).  Its
> not as fast as S3 (though sometimes you can get it that fast by
> optimizing your code).  The development version of proto is even
> faster than the current version of proto due to the addition of lazy
> evaluation.

This make sense to me.


--
Ben Escoto

______________________________________________
[hidden email] mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel
Reply | Threaded
Open this post in threaded view
|

Re: proto and baseenv()

Gabor Grothendieck
On Fri, Feb 26, 2010 at 9:01 AM, Ben <[hidden email]> wrote:

>
>> In end it seems that your real beef is with R so perhaps you should
>> be using a different language.
>
> In my case you may be right.  I do think there are a million things
> wrong with R.  For instance, I was looking for a package that
> overcomes two of the problems R IMHO has: namespace pollution and the
> lack of an easy-to-use standard object system.
>
> Should I be using R?  I do keep asking myself that same question...
>
>> With respect to proto its really just discussing whether to use
>> proto(baseenv(), ...) vs proto(...)
>
> Unfortunately this doesn't fix the problem as was noted earlier:
>
>> z <- 1
>> proto(baseenv(), expr={a <- z})$a
> Error in eval(expr, envir, enclos) : object "z" not found
>

As already mentioned lets not confuse user error with actual problems
pertaining to proto and R.  It should have been written like this if
that is what was wanted:

> z <- 1
> proto(baseenv(), a = z)$a
[1] 1

______________________________________________
[hidden email] mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel
Reply | Threaded
Open this post in threaded view
|

Re: proto and baseenv()

Ben Escoto
Maybe I'm still not getting something fundamental, but I didn't intend
my "proto(baseenv(), expr={a <- z})$a" example to be realistic.  In
practice "a <- z" would be replaced with hundreds of lines of code,
where many functions are called.  In theory you could track down every
function that's global or from another package and track them down,
but then you would have to put dozens of extra lines of boilerplate.
It's actually worse than that, as this example shows:

> proto(baseenv(), f = function(.) sd(1:3))$f()
Error in get("f", env = proto(baseenv(), f = function(.) sd(1:3)), inherits = TRUE)(proto(baseenv(),  :
  could not find function "sd"
> proto(baseenv(), sd = sd, f = function(.) sd(1:3))$f()
Error in sd(1:3) : could not find function "var"

Not only would every external function have to be specifically
declared with a separate argument, even unused functions may need to
be declared.  That means any change in the implementation of an
external function could break this code.

Again, I may be missing something since I'm new to proto, but I don't
see why you're dismissing this example as "user error".


--
Ben Escoto

----------------- Original message -----------------
From: Gabor Grothendieck <[hidden email]>
To: Ben <[hidden email]>
Date: Fri, 26 Feb 2010 09:28:46 -0500
On Fri, Feb 26, 2010 at 9:01 AM, Ben <[hidden email]> wrote:

>
>> In end it seems that your real beef is with R so perhaps you should
>> be using a different language.
>
> In my case you may be right.  I do think there are a million things
> wrong with R.  For instance, I was looking for a package that
> overcomes two of the problems R IMHO has: namespace pollution and the
> lack of an easy-to-use standard object system.
>
> Should I be using R?  I do keep asking myself that same question...
>
>> With respect to proto its really just discussing whether to use
>> proto(baseenv(), ...) vs proto(...)
>
> Unfortunately this doesn't fix the problem as was noted earlier:
>
>> z <- 1
>> proto(baseenv(), expr={a <- z})$a
> Error in eval(expr, envir, enclos) : object "z" not found
>

As already mentioned lets not confuse user error with actual problems
pertaining to proto and R.  It should have been written like this if
that is what was wanted:

> z <- 1
> proto(baseenv(), a = z)$a
[1] 1

______________________________________________
[hidden email] mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel
Reply | Threaded
Open this post in threaded view
|

Re: proto and baseenv()

Gabor Grothendieck
On Fri, Feb 26, 2010 at 8:46 PM, Ben <[hidden email]> wrote:
> Maybe I'm still not getting something fundamental, but I didn't intend

I think you are missing the R search path.  Try this:

search()

That shows you the search path.  Normally it starts searching at the
beginning and moves forward.

> my "proto(baseenv(), expr={a <- z})$a" example to be realistic.  In
> practice "a <- z" would be replaced with hundreds of lines of code,
> where many functions are called.  In theory you could track down every
> function that's global or from another package and track them down,
> but then you would have to put dozens of extra lines of boilerplate.
> It's actually worse than that, as this example shows:
>
>> proto(baseenv(), f = function(.) sd(1:3))$f()
> Error in get("f", env = proto(baseenv(), f = function(.) sd(1:3)), inherits = TRUE)(proto(baseenv(),  :
>  could not find function "sd"
>> proto(baseenv(), sd = sd, f = function(.) sd(1:3))$f()
> Error in sd(1:3) : could not find function "var"

That's because sd is in stats, not in base and you told it to start
searching at the end of the search path rather than the beginning.
Try this:

> Object <- as.environment("package:stats")
> proto(Object, f = function(.) sd(1:3))$f()
[1] 1

>
> Not only would every external function have to be specifically
> declared with a separate argument, even unused functions may need to
> be declared.  That means any change in the implementation of an
> external function could break this code.
>
> Again, I may be missing something since I'm new to proto, but I don't
> see why you're dismissing this example as "user error".
>
>
> --
> Ben Escoto
>
> ----------------- Original message -----------------
> From: Gabor Grothendieck <[hidden email]>
> To: Ben <[hidden email]>
> Date: Fri, 26 Feb 2010 09:28:46 -0500
> On Fri, Feb 26, 2010 at 9:01 AM, Ben <[hidden email]> wrote:
>>
>>> In end it seems that your real beef is with R so perhaps you should
>>> be using a different language.
>>
>> In my case you may be right.  I do think there are a million things
>> wrong with R.  For instance, I was looking for a package that
>> overcomes two of the problems R IMHO has: namespace pollution and the
>> lack of an easy-to-use standard object system.
>>
>> Should I be using R?  I do keep asking myself that same question...
>>
>>> With respect to proto its really just discussing whether to use
>>> proto(baseenv(), ...) vs proto(...)
>>
>> Unfortunately this doesn't fix the problem as was noted earlier:
>>
>>> z <- 1
>>> proto(baseenv(), expr={a <- z})$a
>> Error in eval(expr, envir, enclos) : object "z" not found
>>
>
> As already mentioned lets not confuse user error with actual problems
> pertaining to proto and R.  It should have been written like this if
> that is what was wanted:
>
>> z <- 1
>> proto(baseenv(), a = z)$a
> [1] 1
>
>

______________________________________________
[hidden email] mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel
Reply | Threaded
Open this post in threaded view
|

Re: proto and baseenv()

Gabor Grothendieck
Added one other comment below.

On Fri, Feb 26, 2010 at 9:41 PM, Gabor Grothendieck
<[hidden email]> wrote:

> On Fri, Feb 26, 2010 at 8:46 PM, Ben <[hidden email]> wrote:
>> Maybe I'm still not getting something fundamental, but I didn't intend
>
> I think you are missing the R search path.  Try this:
>
> search()
>
> That shows you the search path.  Normally it starts searching at the
> beginning and moves forward.
>
>> my "proto(baseenv(), expr={a <- z})$a" example to be realistic.  In
>> practice "a <- z" would be replaced with hundreds of lines of code,
>> where many functions are called.  In theory you could track down every
>> function that's global or from another package and track them down,
>> but then you would have to put dozens of extra lines of boilerplate.
>> It's actually worse than that, as this example shows:
>>
>>> proto(baseenv(), f = function(.) sd(1:3))$f()
>> Error in get("f", env = proto(baseenv(), f = function(.) sd(1:3)), inherits = TRUE)(proto(baseenv(),  :
>>  could not find function "sd"
>>> proto(baseenv(), sd = sd, f = function(.) sd(1:3))$f()
>> Error in sd(1:3) : could not find function "var"
>
> That's because sd is in stats, not in base and you told it to start
> searching at the end of the search path rather than the beginning.
> Try this:
>
>> Object <- as.environment("package:stats")

or if you just want to exlude the global environment but still include
any loaded packages:

Object <- as.environment(2)

(If you have not loaded any packages then the two Object<- statements
have the same effect but if there are loaded packages the second
includes them while the first excludes them.)

>> proto(Object, f = function(.) sd(1:3))$f()
> [1] 1
>
>>
>> Not only would every external function have to be specifically
>> declared with a separate argument, even unused functions may need to
>> be declared.  That means any change in the implementation of an
>> external function could break this code.
>>
>> Again, I may be missing something since I'm new to proto, but I don't
>> see why you're dismissing this example as "user error".
>>
>>
>> --
>> Ben Escoto
>>
>> ----------------- Original message -----------------
>> From: Gabor Grothendieck <[hidden email]>
>> To: Ben <[hidden email]>
>> Date: Fri, 26 Feb 2010 09:28:46 -0500
>> On Fri, Feb 26, 2010 at 9:01 AM, Ben <[hidden email]> wrote:
>>>
>>>> In end it seems that your real beef is with R so perhaps you should
>>>> be using a different language.
>>>
>>> In my case you may be right.  I do think there are a million things
>>> wrong with R.  For instance, I was looking for a package that
>>> overcomes two of the problems R IMHO has: namespace pollution and the
>>> lack of an easy-to-use standard object system.
>>>
>>> Should I be using R?  I do keep asking myself that same question...
>>>
>>>> With respect to proto its really just discussing whether to use
>>>> proto(baseenv(), ...) vs proto(...)
>>>
>>> Unfortunately this doesn't fix the problem as was noted earlier:
>>>
>>>> z <- 1
>>>> proto(baseenv(), expr={a <- z})$a
>>> Error in eval(expr, envir, enclos) : object "z" not found
>>>
>>
>> As already mentioned lets not confuse user error with actual problems
>> pertaining to proto and R.  It should have been written like this if
>> that is what was wanted:
>>
>>> z <- 1
>>> proto(baseenv(), a = z)$a
>> [1] 1
>>
>>
>

______________________________________________
[hidden email] mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel
Reply | Threaded
Open this post in threaded view
|

Re: proto and baseenv()

Peter Danenberg-3
In reply to this post by Duncan Murdoch
> One thing that I dislike about scoping in R is the fact that even in a
> namespace, searches eventually get to the global environment.  I'd prefer
> if namespace searches went through the imported namespaces and nothing
> else.  If that were the case, then the a$z example would never find a z in
> the global environment, and that example would only be a problem for people
> fiddling around in the console, not programming carefully in a
> package.

Amazing, Duncan; I think you hit upon the perfect compromise. Though
the issues you're bringing up are bigger than proto; at least in the
case of proto, deriving from as.environment(2) is an interesting
stop-gap solution.

Thanks to Gabor for suggesting it.

______________________________________________
[hidden email] mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel
12