|
Project Information
Members
Links
|
Perfection is achieved, not when there is nothing more to add, but when there is nothing left to take away. — Antoine de Saint Exupéry Inside every large program there is a small program trying to get out. — CAR Hoare Less is more. - Ludwig Mies van der Rohe Make the irreducible basic elements as simple and as few as possible without having to surrender the adequate representation of a single datum of experience. - Albert Einstein Simple can be harder than complex: You have to work hard to get your thinking clean to make it simple. But it's worth it in the end because once you get there, you can move mountains." Steve Jobs, BusinessWeek interview, May 1998 Below on this page are sections on: Introductionproto (google code name r-proto) is an R package which facilitates a style of programming known as prototype-based programming. Prototype-based programming is a type of object oriented (OO) programming in which classes and objects are unified into a single concept, prototypes. This makes proto and prototye programming simpler than the usual OO model yet it retains the OO features of inheritance (known as delegation in the prototype model) and OO dispatch. Applications, News, Additional Information sources, Proto Bugs and Avoiding R Bugs sections are given below while associated Links are in the links page. ApplicationsThere are
(The above statistics were gathered on September 26, 2011.) Here are some packages that directly refer to proto or are typically used with proto:
NewsMarch 19, 2011. proto 0.3-9.1 has been uploaded to CRAN. It addresses a minor issue in R CMD check. There is no functional difference from the prior version. March 11, 2011. proto 0.3-9 has been uploaded to CRAN. It fixes the minor known bugs and has been changed to be compatible with the upcoming R 2.13. (It should still work on earlier versions of R as well.) September 19, 2010. Added "Less is more" quote at top. August 13, 2010. Michael Bedward of the Last Resort Software blog has written an article on MCMC sampling for Bayesian regression using proto. July 18, 2010. Added Einstein quote near top of this page and on the links page added a link to Secrets of Simplicity presentation. June 20, 2010. Added reference to the benchmark package above. March 12, 2010. The Appendix of this document on AlgoTrader contains an introduction to proto that could be of interest to anyone wishing to use proto even if the Algotrader package is not applicable to their area. (This may have been there for some time but I just noticed it.) March 2, 2010. An example of a stack in proto was posted on r-help. February 27, 2010. Recently Duncan Murdoch discussed one aspect of R that he would prefer worked differently; namely, that objects were not ultimately looked up in the global environment. If you are using proto you can emulate it. The following are three different variations: p <- proto(as.environment(2), ...) # searches loaded core and user packages but not globalenv()
p <- proto(as.environment("package:Stats"), ...) # searches core packages but not user packages nor globalenv()
p <- proto(baseenv(), ...) # searches baseenv() but not other core packages nor user packages nor globalenv()Note the following R command which shows the R search path: search() The first example starts at the second entry in the search list (which is why it omits the global environment). The next example starts at the Stats entry in the search list and moves forward. The last example starts right at the end of the search list thereby skipping over the rest of it and was suggested by Peter Daneberg in the same thread as appropriate in certain circumstances. For example, one could define a function like this: f <- proto(as.environment(2), f = function(this, x) x)$f f(3) or like this: f <- with(proto(as.environment(2), f = function(x) x), f) f(3) In this case environment(f) will be the proto object and it parent will be the second package on the search list. Jan 18/10. An example of using proto to work with views on matrices can be found here. Jan 15/10. Added traitr to the list of applications above that use proto. Sep 11/09. There is information on command line completion for proto objects here. Sep 7/09. Added AlgoTrader package to the list of applications above that use proto. Sep 3/09. Added the Things Every Programmer Should Know link in the links page. Aug 28/09. Wrote out abbreviated arguments in full in the svn to avoid build warnings. Aug 19/09. Added the Dog Food link in the links page. Aug 8/09. Added the Bad Programming link in the links page. Jun 5/09. Added information (see above) on the sqldf R package which uses proto internally. Apr 5/09. Added information (see above) on the ascii R package which uses proto internally. Oct 3/08. Updated links to Lieberman (1986) and Taivalsaari (1996) papers in the links page. Oct 3/08. Confirmed that the LazyLoad bug in R is still present. See the first point in the Avoiding R Bugs section below and this r-devel post. July 5/08. Added a fifth point in the Avoiding R Bugs section. May 19/08. Added quotations to top of this page. Mar 7/08. In the development version of proto the parent argument to the proto function may now be a function in which case its environment is used as the parent. This facilitates constructing proxy proto objects: with(proto(f, f = f, a = 1), f) wedges an anonymous proto object between f and its environment inserting a into the proxy so that it can be accessed as a free variable from within f. Mar 7/08. The method of proto proxies was illustrated in an r-devel post. Feb 25/08. A dput.proto routine was posted on r-devel. Jan 26/08. Just noticed that there was a modification to the R development source made on Jan 24, 2008, see r44139 in r-devel log, which indicates that a bug in R related to promises has been fixed. Since proto 0.4, the current development version, depends heavily on promises this should be beneficial. The following code, which is not dependent on proto, previously failed under R but now it works: # code below previously triggered errors but now works - R 2.6.2 (2008-01-26 r44181) f <- function(x) environment() z <- as.list(f(7)) dput(z) structure(list(x = 7), .Names = "x") z[[1]] == 7 # should return TRUE force(z[[1]]) == 7 # should return TRUE Jan 09/08. Added a second paragraph to the LazyLoad subsection of the Avoiding R Bugs list at the bottom based on a recent discussion on the r-devel list. Also added a new section Proto Bugs below. Note that all known bugs are fixed in the development version of proto. Dec 07/07. as.proto.data.frame method added to the devel version of proto. Its just a synonym for as.proto.list. as.proto.data.frame <- as.proto.list Dec 06/07. print bug added to bug list below. Dec 01/07. Added a new argument, eval.env = parent.frame() to the proto function in the devel version of proto. It defines the environment in which promises in the ... arguments are evaluated. The default value of eval.env is normally what one wants; however, in the case of wrappers around proto one would generally want the calling frame of the wrapper rather than the frame which directly calls proto and this argument facilitates that. The need for this is related to the problem in R described in point #4 of Avoiding R Bugs at the end of this page. Oct 28/07. Added a reference to pmg in the Applications section above as it uses proto internally. Oct 17/07. Added a reference to this r-devel post and discussion to the LazyLoad subsection of the Avoiding R Bugs section at the end of this page. (This applies to packages that have proto objects at top level. Also see ReleaseNotes.txt.) Sep 30/07. A workaround for the R bug where promises in lists do not get evaluated was developed. (This never affected the released version of proto on CRAN.) See Avoiding R Bugs section below. Sep 25/07. Added ReleaseNotes.txt describing new features of the development version (proto 0.4-0) also found on Source tab above. To try out, after installing from the Source Repository run this (under R 2.6.2): library(proto)
example(proto)
demo(proto)
demo("proto-vignette")
demo("proto-gWidgets") # needs gWidgets package to be installedor to try it without installing anything (other than CRAN version of proto): library(proto) # loads CRAN version of proto
source("http://r-proto.googlecode.com/svn/trunk/R/proto.R") # load changed code
demo(proto)
source("http://r-proto.googlecode.com/svn/trunk/demo/demo-vignette.R")
source("http://r-proto.googlecode.com/svn/trunk/demo/demo-gWidgets.R")Sep 20/07. John Verzani has added another proto/gWidgets user interface example here. It is in addition to his others here and here. Also see this r-devel post for another proto/gWidgets example. Sep 15/07. proto 0.3-8 uploaded to CRAN. Only changes are those needed to satisfy R 2.6.0. CitationTo get the citation for this package use the R command: citation("proto")Additional InformationAdditional information is available at:
Proto BugsThe following are bugs in the released version of proto on CRAN. They are all fixed in the development version already. 1. str.proto. This will not affect most users but one user was redefining print and that caused name.proto (hence str.proto) to break. The call to print has been replaced with a call to print.default in name.proto to avoid this in the devel version of proto. Here are three workarounds in the meantime: Run this code: name.proto <- proto(print.proto = print.default, f = proto::name.proto)$f or, source the new version of graph.proto.R which is the file that contains name.proto: source("http://r-proto.googlecode.com/svn/trunk/R/proto.R") # load changed codeor, ensure that your proto object has a ..Name component. For example, this works even if print is redefined: print <- function(x, ...) 1 p <- proto(..Name = "proto object: p", x = 1) name.proto(p) str(p) rm(print) 2. A proto object could not have the name x. Avoiding R BugsDue to the fundamental nature of proto, it makes use of portions of R that may not be commonly accessed in other packages; therefore, it has uncovered a number of R bugs or deficencies that were not previously known or at least are less known. Fortunately there are simple workarounds to deal with them provided you know about them. 1. LazyLoad If a package uses lazyloading then R will erroneously change the class of all proto objects at top level to "environment". This r-devel post from the R development team confirms that it is a bug in R and that there is an intention to fix it (however, as of R version 2.12.1 it had still not been fixed.) See this r-devel post for details and info on how to test it.) To avoid this bug use LazyLoad: false in the DESCRIPTION file of any package that has proto objects at top level. In older versions of R it was possible to use SaveImage: true in the DESCRIPTION file; however, SaveImage is not available in recent versions of R. One gotcha is that not specifying LazyLoad is not the same as LazyLoad: false. As mentioned in R News 4/2 if LazyLoad is not specified then R will use lazy loading if there is more than 25K of R code in the package and otherwise not. See this: r-devel discussion. There is some information on LazyLoad and SaveImage in this r-devel post and there is an article on lazy loading in R News 4/2. (There was discussion that this behavior will change in R 2.9.0 where true will be the default and the odd 25K criterion will be eliminated but am not sure if that happened.) One can test this by creating an R package with only two files which are (1) this DESCRIPTION file: Package: testlazy Version: 1.0-0 Date: 2008-10-03 Title: Test lazy loading Author: G Grothendieck Maintainer: G Grothendieck <ggrothendieck@gmail.com> Description: Test lazy loading with top level objects. Depends: proto LazyLoad: yes License: GPL-2 and (2) this R/testlazy.R file: TopLevel <- proto() We test it like this: library(testlazy) class(TopLevel) If the class of TopLevel is just environment then the proto component of the class has been stripped by R. One related problem is that if you use LazyLoad: false to overcome the problem above then proto will not be available during the package load unless it is specifically loaded so add: require(proto) to your code if any top level proto objects are created at load time. See: this r-devel post and this related post . 2. Promises and Lists R is supposed to evaluate promises that are stored in lists but, in fact, it does not -- see this thread in r-devel. It is currently believed that this has never affected the released version of proto on CRAN nor does it affect the most recent devel version of proto. It did affect earlier devel versions of proto. Even though it seems to currently have no consequence we are leaving this item here just in case it comes up in some new form and needs to be revisited. (This may be fixed already in the R 2.9.0 development version.) # No longer a problem but recorded here just in case.
# ensure proto 0.4-0 is installed from Source tab
# or just load the CRAN version of proto and over top
# of it source proto.R from the repository as discussed
# in the Sep 25th News item above
#
# in the code below:
# - p is a proto object
# - x a child of p created by invoking p$new
# - y is a copy of x formed by converting the
# the proto object to a list and back to proto
#
# The problem is that although ls(y) says that gg is in y
# when we try to evaluate it, R says its not there.
p <- proto(, {
Name <- gg <- "m" # for debugging. Can omit this line.
new <- function(., gg) proto(., Name = "n", gg = gg)
})
# one clue is that if we
# uncomment next line and comment one after it error disappears
# x <- proto(gg = "g")
x <- p$new(gg = "g") # x is a child of p
x$Name <- "x" # for debugging. Can omit this line.
y <- as.proto(as.list(x)) # y is a copy of x
y$Name <- "y" # for debugging. Can omit this line.
ls(y) # shows that gg in y
# next line gives error saying gg not found
with(y, gg)3. Subclassing environments Operating locally on an environment attribute changes its value globally which seems undesirable. The proto class is an S3 subclass of the environment class. Unfortunately if e is a variable holding an environment and f is a copy of it then if you set an attribute on f then e gets it too: f <- e attr(f, "abc") <- 3 After the above e will gain attribute abc with a value of 3 as well. This occurs even if 3 is assigned within a function. "class" is an attribute so it also applies to the class. 4. Limitations on Use of Promises Using pure R, there is currently no way to copy promises without evaluating them nor is there any way to discover the environment associated with a promise. For the proto clone function it would be desirable to be able to copy promises without evaluating them while preserving their environments. Although the preceding are not possible in pure R it is possible to do this using C. 5. [[ Does Not Work Well with Promises This is no longer a problem in R but is being left here in case it comes up again in some other form. In the code below test fails. Note that this code does not use proto and this is a general problem in R. idx <- 2
# Error !!!
test <- function(pf = parent.frame()) BOD[[pf$idx]]
test()
# Returns expected result by avoiding [[
test2 <- function(pf = parent.frame()) .subset2(BOD, pf$idx)
test2()
# Also works as expected by forcing pf so its not a promise
test3 <- function(pf = parent.frame()) { force(pf); BOD[[pf$idx]] }
test3()
# Also works as expected. Surprisingly [[.data.frame gives different result than [[
# See https://stat.ethz.ch/pipermail/r-devel/2008-July/050126.html
test4 <- function(pf = parent.frame()) "[[.data.frame"(BOD, pf$idx)
test4()
TestsThe following tests use quite a few features of proto: library(ggplot2)
qplot(carat, price, data=diamonds, facet = color ~ clarity)
qplot(carat, price, data=diamonds, colour = interaction(color, clarity, cut))
qplot(carat, price, data=diamonds, geom=rep("point", 10))
|