1%\VignetteIndexEntry{proto: An R Package for Prototype Programming} 2%\VignetteDepends{} 3%\VignetteKeywords{object oriented, prototype programming, S3, R} 4%\VignettePackage{proto} 5 6\documentclass[nojss]{jss} 7\usepackage{Sweave} 8\DeclareGraphicsExtensions{.pdf, .eps, .png} 9 10\newlength{\half} 11\setlength{\half}{70mm} 12 13\author{Louis Kates\\GKX Associates Inc. \And 14 Thomas Petzoldt\\Technische Universit\"at Dresden} 15\Plainauthor{Louis Kates, Thomas Petzoldt} 16 17\title{\pkg{proto}: An \proglang{R} Package for Prototype Programming} 18%% \Shorttitle{\pkg{proto}: An \proglang{R} Package for Prototype Programming} 19 20\Plaintitle{proto: An R Package for Prototype Programming} 21 22\Keywords{prototype programming, delegation, inheritance, clone, 23 object orientated, \proglang{S3}, \proglang{R}} 24\Plainkeywords{object oriented, prototype programming, S3, R} 25 26\Abstract{ 27 28 \pkg{proto} is an \proglang{R} package which facilitates a style 29 of programming known as prototype 30 programming. Prototype programming is a type of object 31 oriented programming in which there are no classes. 32 \pkg{proto} is simple yet retains the object oriented features of 33 delegation (the prototype counterpart to inheritance) 34 and object oriented dispatch. \code{proto} can be used 35 to organize the concrete data and procedures in statistical studies 36 and other applications 37 without the necessity of defining classes while still providing convenient 38 access to an object oriented style of programming. Furthermore, it 39 can be used in a class-based style as well so that incremental design can 40 begin with defining the concrete objects and later transition to abstract 41 classes, once the general case is understood, without having to change to 42 object-oriented frameworks. 43 The key goals of the package are to integrate into \proglang{R} 44 while providing nothing more than a thin layer on top of it. 45} 46 47\hyphenation{ma-ni-pu-lating} 48 49\begin{document} 50\SweaveOpts{concordance=TRUE} 51 52 53 54 55\section{Introduction} \label{sec:intro} 56 57\subsection[Object Oriented Programming in R]{Object Oriented Programming in \proglang{R}} 58\label{sec:oo} 59 60The \proglang{R} system for statistical computing 61\citep[\url{http://www.R-project.org/}]{Rcore2005} ships with two 62systems for object oriented programming referred to as \proglang{S3} 63and \proglang{S4}. With the increased interest in object oriented 64programming within \proglang{R} over the last years additional object 65oriented programming packages emerged. These include the \pkg{R.oo} 66package \citep{Bengtsson2003} and the \pkg{OOP} package 67\citep[\url{http://www.omegahat.net/OOP/}]{Rnews:Chambers+Lang:2001a}. 68All these packages have the common thread that they use 69classes as the basis of inheritance. When a message is sent to an 70object the class of the object is examined and that class determines the 71specific function to be executed. In prototype programming there 72are no classes making it simple yet it retains much of the power of 73class-based programming. In the fact, \pkg{proto} is so simple that 74there is only one significant new routine name, \code{proto}. The 75other routines are just the expected support routines such as 76\code{as.proto} to coerce objects to proto objects, \code{\$} to 77access and set proto object components and \code{is.proto} to check 78whether an object is a proto object. In addition, \code{graph.proto} 79will generate a graphical ancestor tree showing the parent-child 80relationships among generated \code{proto} objects. 81 82The aim of the package is to provide a lightweight layer for prototype 83programming in \proglang{R} written only in \proglang{R} leveraging the 84existing facilities of the language rather than adding its own. 85 86\subsection{History} 87\label{sec:history} 88 89The concept of 90prototype programming 91\citep{Lieberman1986, Taivalsaari1996a, Noble1999} 92has developed over a number of years with the \proglang{Self} 93language \citep{Agesen1992} 94being the key evolved programming language to demonstrate 95the concept. In statistics, the \proglang{Lisp}-based 96\proglang{LispStat} programming language \citep{Tierney1990} was 97the first and possibly only statistical system to feature prototype 98programming. 99 100Despite having been developed over 20 years ago, and some attempts to 101enter the mainstream (e.g. \proglang{Newtonscript} 102on the Newton computer, which 103is no longer available, and \proglang{Javascript} where 104it is available but whose 105domain of application largely precluses use of prototype programming) 106prototype programming is not well known due to lack of language 107support in popular programming languages such as \proglang{C} and 108\proglang{Java}. It tends 109to be the domain of research languages or \proglang{Lisp}. 110 111Thus the 112the availability of a popular language, 113\proglang{R} \footnote{Some indications of the popularity of R are 114the high volume mailing lists, international development team, the 115existence of over 500 addon packages, conferences and numerous books 116and papers devoted to R.}, 117that finally does provide the key infrastructure 118is an important development. 119 120This work grew out of the need to organize multiple scenarios of model 121simulations in ecological modelling \citep{Rnews:Petzoldt:2003} and 122was subsequently generalized to the present package. A number of 123iterations of the code, some motivated by the ever increasing feature 124set in \proglang{R}, resulted in a series of utilities and ultimately 125successive versions of an \proglang{R} package developed over the last 126year. An initial version used \proglang{R} lists as the basis of the 127package. Subsequently the package was changed to use \proglang{R} 128environments. The first version to use environments stored the 129receiver object variable in a proxy parent environment which was 130created on-the-fly at each method call. The present version of 131the \pkg{proto} package passes the receiver object through the argument list, 132while hiding this from the caller. It defines the \code{proto} class 133as a subclass of the \code{environment} class so that 134functionality built into \proglang{R} for the environment class is 135automatically inherited by the \code{proto} class. 136 137\subsection{Overview} 138\label{sec:overview} 139 140It is assumed that the reader has some general 141familiarity with object oriented programming concepts and with 142\proglang{R}. 143 144The paper will proceed primarily by example focusing on illustrating 145the package \code{proto} through such demonstration. The remainder of 146the paper is organized as follows: Section~\ref{sec:proto-class} 147explains how \code{"proto"} objects are created and illustrates the 148corresponding methods for setting and getting components. It further 149discusses how object oriented delegation (the prototype programming 150analogue of inheritance) is handled and finally discusses the 151internals of the package. This section uses small examples chosen for 152their simplicity in illustrating the concepts. In 153Section~\ref{sec:examples} we provide additional examples of prototype 154programming in action. Four examples are shown. The first involves 155smoothing of data. Secondly we demonstrate the calculation of 156correlation confidence intervals using classical (Fisher Transform) 157and modern (bootstrapping) methods. Thirdly we demonstrate the 158development of a binary tree as would be required for a dendrogram. 159Fourthly, we use the solution of linear equations to illustrate 160program evolution from object-based to class-based, all 161within the \pkg{proto} framework. 162Section~\ref{sec:summary} gives a few summarizing remarks. Finally, 163an appendix provides a reference card that summarizes the 164functionality contained in \pkg{proto} in terms of its constituent 165commands. 166 167%% \pagebreak[4] 168 169\section[The class "proto" and its methods]{The class \code{"proto"} and its methods} 170\label{sec:proto-class} 171 172\subsection[Creation of "proto" objects]{Creation of \code{"proto"} objects} 173\label{sec:proto} 174 175In this section we shall show, by example, the creation of two 176prototype objects and related operations. The simple idea is that 177each \code{"proto"} object is a set of components: functions (methods) 178and variables, which are tightly related in some way. 179 180A prototype object is an environment holding the variables and 181methods of the object. \footnote{In particular this implies that 182\code{"proto"} objects have single inheritance, follow ordinary 183environment scoping rules and have mutable state as environments 184do.} 185 186A prototype object is created using the constructor function 187\code{proto} (see Appendix~\ref{sec:ref} at the end of this paper or 188\pkg{proto} package help for complete syntax of commands). 189 190\begin{Scode} 191addProto <- proto( x = rnorm(5), add = function(.) sum(.$x) ) 192\end{Scode} 193 194In this simple example, the \code{proto} function defines two 195components: a variable \code{x} and a method \code{add}. The variable 196\code{x} is a vector of 5 numbers and the method sums those numbers. 197The \code{proto} object \code{addProto} contains the variable and the 198method. Thus the \code{addProto} \code{proto} object can be used to compute 199the sum of the values stored in it. 200As shown with the \code{add} method in this example, formal argument 201lists of methods must always have a first argument of dot 202(i.e. \code{.}) which signifies the object on which the method is 203operating. The dot refers to the current object in the same way that 204a dot refers to the current directory in UNIX. Within the method one 205must refer to other variables and methods in the object by prefacing 206each with \code{.\$}. For example, in the above we write 207\code{sum(.\$x)}. Finally, note that the data and the method are very 208closely related. Such close coupling is important in order to create 209an easily maintained system. 210 211To illustrate the usage of \code{proto}, we first load the package and 212set the random seed to make the examples in this paper exactly 213reproducible. 214 215\begin{Schunk} 216\begin{Sinput} 217> library(proto) 218> set.seed(123) 219\end{Sinput} 220\end{Schunk} 221 222Then, we create the \code{proto} object from above 223and call its \code{add} method. 224\begin{Schunk} 225\begin{Sinput} 226> addProto <- proto(x = rnorm(5), add = function(.) sum(.$x)) 227> addProto$add() 228\end{Sinput} 229\begin{Soutput} 230[1] 0.9678513 231\end{Soutput} 232\end{Schunk} 233We also create another object, \code{addProto2} 234with a different \code{x} vector and 235invoke its \code{add} method too. 236\begin{Schunk} 237\begin{Sinput} 238> addProto2 <- addProto$proto(x = 1:5) 239> addProto2$add() 240\end{Sinput} 241\begin{Soutput} 242[1] 15 243\end{Soutput} 244\end{Schunk} 245In the examples above, we created a prototype object \code{addProto} 246and then called its \code{add} method as just explained. 247The notation \code{addProto\$add} 248tells the system to look for the \code{add} method 249in the \code{addProto} object. In the expression \code{addProto\$add}, 250the \code{proto} object to the left 251of the dollar sign, \code{addProto} here, is referred to as the 252\emph{receiver} object. This expression 253also has a second purpose which is to 254pass the receiver object implicitly as the first argument of \code{add}. 255Note that we called \code{add} as if it had zero arguments but, in fact, 256it has one argument because the receiver is automatically and implicitly 257supplied as the first argument. In general, 258the notation \code{object\$method(arguments)} is 259used to invoke the indicated method of the receiver object using the 260object as the implicit first argument along with the indicated 261arguments as the subsequent arguments. 262As with the \code{addProto} example, the receiver 263object not only determines where to find the 264method but also is implicitly passed to the method through 265the first argument. The motivation for this notation 266is to relieve the user of 267specifying the receiver object twice: 268once to locate the method in the object and a second 269time to pass the object itself to the method. 270The \code{\$} is overloaded by the \code{proto} 271class to automatically do both with one reference to the receiver object. 272Even though, as with the \code{addProto} example, the first 273argument is not listed in the call 274it still must be listed among the formal arguments 275in the definition of the method. It 276is conventional to use 277a dot \code{.} as the first formal argument in the method/function 278definition. That is, we call \code{add} using \code{addProto\$add()} 279displaying zero arguments 280but we define \code{add} in \code{addProto} displaying 281one argument \code{add <- function(.)}, the dot. 282 283In this example, 284we also created a second object, \code{addProto2}, 285which has the first object, \code{addProto} as its parent. 286Any reference to a 287component in the second object that is unsuccessful will cause 288search to continue in the parent. Thus the call \code{addProto2\$add()} 289looks for \code{add} in \code{addProto2} and not finding it there 290searches its parent, \code{addProto}, where it is, indeed, found. 291\code{add} is invoked with the receiver object, \code{addProto2}, as 292the value of dot. 293The call \code{addProto2\$add()} actually causes the \code{add} 294in \code{addProto} to run but it still uses the \code{x} from 295\code{addProto2} since dot (\code{.}) is \code{addProto2} here 296and \code{add} references \code{.\$x}. 297Note that the reference to \code{.\$x} in the 298\code{add} found in \code{addProto} 299does not refer to the \code{x} in \code{addProto} itself. 300The \code{x} in \code{addProto2} has overridden the \code{x} in its parent. 301This point is important so the reader should take care to absorb this 302point. 303 304This simple example already shows the key elements of the system 305and how \emph{delegation} (the prototype programming term for inheritance) 306works without classes. 307 308We can add new components or replace components in an object and 309invoke various methods like this: 310\begin{Schunk} 311\begin{Sinput} 312> addProto2$y <- seq(2, 10, 2) 313> addProto2$x <- 1:10 314> addProto2$add3 <- function(., z) sum(.$x) + sum(.$y) + sum(z) 315> addProto2$add() 316\end{Sinput} 317\begin{Soutput} 318[1] 55 319\end{Soutput} 320\begin{Sinput} 321> addProto2$add3(c(2, 3, 5)) 322\end{Sinput} 323\begin{Soutput} 324[1] 95 325\end{Soutput} 326\begin{Sinput} 327> addProto2$y 328\end{Sinput} 329\begin{Soutput} 330[1] 2 4 6 8 10 331\end{Soutput} 332\end{Schunk} 333 334In this example, we insert variable \code{y} into the object \code{addProto2} 335with a value of \code{seq(2,10,2)}, 336reset variable \code{x} to a new value and insert a new method, 337\code{add3}. Then we invoke 338our two methods and display \code{y}. Again, note that in the case of 339\code{protoAdd2\$add} the \code{add} method is not present in 340\code{protoAdd2} and so search continues to the parent \code{addProto} 341where it is found. 342 343\subsection{Internals} 344\label{sec:internals} 345 346So far, we have used simple examples to illustrate the basic manipulation 347of objects: construction, getting and setting components and method 348invocation. We now discuss the internals of the package and how it relates 349to \proglang{R} constructs. 350\code{proto} is actually an \proglang{S3} class which is a subclass 351of the \code{environment} class. Every \code{proto} object is an 352environment and its class is \code{c("proto", "environment")}. The \code{\$} 353accessor is similar to the same accessor in environments except it will 354use the \proglang{R} \code{get} function to 355search up parent links if it cannot otherwise find the object (unlike 356environments). When accessing a method, \code{\$} 357automatically supplies the 358first argument to the method 359unless the object is \code{.that} or \code{.super}. \code{.that} 360is a special variable which \code{proto} adds to every \code{proto} object 361denoting the object itself. \code{.super} is also added to every 362proto object and is the parent of \code{.that}. \code{.that} 363and \code{.super} are normally used 364within methods of an object to refer to other components of the same 365or parent object, respectively, 366as opposed to the receiver (\code{.}). For example, 367suppose we want \code{add} in \code{addProto2} to add the elements 368of \code{x} together and the elements of 369\code{y} together and then add these two sums. We could redefine add like this: 370 371\begin{Schunk} 372\begin{Sinput} 373> addProto2$add <- function(.) .super$add(.) + sum(.$y) 374\end{Sinput} 375\end{Schunk} 376 377making use of the \code{add} already defined in the parent. 378One exception should be noted here. When one uses \code{.super}, 379as above, or \code{.that} to specify a method then the receiver 380object must be explicitly specified 381in argument one (since in those cases the receiver 382is possibly different than 383\code{.super} or \code{.that} so the system cannot automatically supply it 384to the call.) 385 386Setting a value is similar to the corresponding operation for 387environments except that any function, i.e method, which is 388inserted has its environment set to the environment of the object 389into which it is being inserted. This is necessary so that such 390methods can reference \code{.that} and \code{.super} using 391lexical scoping. 392 393In closing this section a few points should be re-emphasized and 394expanded upon. A 395\code{proto} object is an environment whose parent object is the 396parent environment of the \code{proto} object. The methods in the \code{proto} 397objects are ordinary functions that have the containing object as their 398environment. 399 400The \proglang{R} \code{with} function can be used with environments and 401therefore can be used with \code{proto} objects since \code{proto} 402objects are environments too. Thus \code{with(addProto, x)} refers 403to the variable \code{x} in \code{proto} object \code{addProto} 404and \code{with(addProto, add)} refers to the method \code{add} 405in the same way. \code{with(addProto, add)(addProto)} can be used 406to call \code{add}. These constructs all follow from their corresponding 407use in environments from which they are inherited. 408 409Because the \code{with} expressions are somewhat verbose, two common 410cases can be shortened using the \code{\$} operator. \code{addProto\$x} 411can be used to refer to variable \code{x} in \code{proto} object 412\code{addProto} and has the same meaning as \code{with(addProto, x)}. 413In particular like \code{with} but 414unlike the the behavior of the \code{\$} operator on 415environments, when used with \code{proto} objects, \code{\$} will 416search not only the object itself but also its ancestors. 417Similarly \code{addProto\$add()} can be used to call 418method \code{add} in \code{addProto} also searching through ancestors 419if not found in \code{addProto}. Note that \code{addProto\$add} 420returns an object of class 421 422\code{c("instantiatedProtoMethod", "function")} 423which is derived from \code{add} such that the first argument, 424the \code{proto} object, 425is already inserted. Note that there is a \code{print} method for 426class \code{"instantiatedProtoMethod"} so printing such objects will 427display the underlying function but returning such objects 428is not the same as returning the function without slot one inserted. 429Thus, if one wants exactly the original \code{add} 430as a value one should use \code{with(addProto, add)} or 431\code{addProto\$with(add)}. 432 433Within a method, if a variable is referred to without 434qualification simply as \code{x}, say, then its meaning is 435unchanged from how it is otherwise used in \proglang{R} and 436follows the same scope rules as any variable to resolve its name. If it is 437desired that the variable have object scope, i.e. looked up 438in the receiver object and its ancestors, then \code{.\$x} 439or similar \code{with} notation, i.e. \code{with(., x)}, should be used. 440Similarly \code{.\$f(x)} calls 441method \code{f} automatically inserting the receiver object 442into argument one and using \code{x} for argument two. It 443looks for \code{f} first in the receiver object and then its 444ancestors. 445 446\subsection{Traits} 447\label{sec:traits} 448 449Let us look at the definition of a child object once again. 450In the code below, 451\code{addProto} is the previously defined parent object 452and the expression \code{addProto\$proto(x = 1:5)} defines 453a child object of \code{addProto} and assigns it to variable 454\code{addProto2a}. 455 456\begin{Schunk} 457\begin{Sinput} 458> addProto2a <- addProto$proto(x = 1:5) 459> addProto2a$add() 460\end{Sinput} 461\begin{Soutput} 462[1] 15 463\end{Soutput} 464\end{Schunk} 465 466That is, \code{proto} can be used to create a new child of 467an existing object by writing the 468parent object on the left of the \code{\$} and 469\code{proto} on its right. Any contents to 470be added to the new child are listed in arguments of \code{proto} 471as shown. 472 473For example, first let us create a class-like structure. In the 474following \code{Add} is an object that behaves very much like a class 475with an \code{add} method and a method \code{new} which constructs 476new objects. In the line creating object \code{add1} the expression 477\code{Add\$new(x = 1:5)} invokes the \code{new} constructor of the 478receiver object \code{Add}. The method \code{new} has an argument of 479\code{x = 1:5} which defines an \code{x} variable in the \code{add1} 480object being instantiated. We similarly create another object 481\code{add2}. 482 483\begin{Schunk} 484\begin{Sinput} 485> Add <- proto(add = function(.) sum(.$x), new = function(., x) .$proto(x = x)) 486> add1 <- Add$new(x = 1:5) 487> add1$add() 488\end{Sinput} 489\begin{Soutput} 490[1] 15 491\end{Soutput} 492\begin{Sinput} 493> add2 <- Add$new(x = 1:10) 494> add2$add() 495\end{Sinput} 496\begin{Soutput} 497[1] 55 498\end{Soutput} 499\end{Schunk} 500 501An object which contains only methods and variables that are 502intended to be shared by all its children (as opposed to an 503object whose purpose is to have its own methods and variables) 504is known as a \emph{trait} \citep{Agesen1992}. It 505is similar to a class in class-based 506object oriented programming. 507Note that the objects \code{add1} and \code{add2} have the trait 508\code{Add} as their parent. We could implement subclass-like and 509superclass-like objects by simply defining similar trait objects to 510be the parent or child of \code{Add}. For example, suppose we 511want a class which calculates the sum of the logarithms of the data. We 512could define: 513 514\begin{Schunk} 515\begin{Sinput} 516> Logadd <- Add$proto(logadd = function(.) log(.$add())) 517> logadd1 <- Logadd$new(1:5) 518> logadd1$logadd() 519\end{Sinput} 520\begin{Soutput} 521[1] 2.70805 522\end{Soutput} 523\end{Schunk} 524 525Here the capitalized objects are traits. 526\code{Logadd} is a trait. It is a child of \code{Add} 527which is also a trait. \code{logadd1} is an ordinary object, 528not a trait. 529One possible design is to create a tree of traits and other objects 530in which the leaves are ordinary objects and the remaining nodes 531are traits. This would closely correspond to class-based 532object oriented programming. 533 534Note that the delegation of methods from 535one trait to another as in 536\code{new} which is inherited by \code{Logadd} from \code{Add} 537is nothing more than the same mechanism by which traits delegate 538methods to 539objects since, of course, traits are just objects no different 540from any other object other than by the conventions we impose on them. 541This unification of subclassing and instantiation beautifully 542shows the simplification that prototype programming represents. 543 544\subsection{Utilities} 545\label{sec:utilities} 546The fact that method calls automatically insert the first argument 547can be used to good effect in leveraging existing \proglang{R} 548functions while allowing an object-oriented syntax. 549 550For example, \code{ls()} can be used to list the components of 551\code{proto} objects: 552 553\begin{Schunk} 554\begin{Sinput} 555> addProto$ls() 556\end{Sinput} 557\begin{Soutput} 558[1] "add" "x" 559\end{Soutput} 560\end{Schunk} 561 562Functions like: 563 564\begin{Schunk} 565\begin{Sinput} 566> addProto$str() 567> addProto$print() 568> addProto$as.list() 569> addProto2a$parent.env() 570\end{Sinput} 571\end{Schunk} 572 573show additional information about the elements. \code{eapply} 574can be used to explore more properties such as the 575the length of each component of an object: 576 577\begin{Schunk} 578\begin{Sinput} 579> addProto$eapply(length) 580\end{Sinput} 581\end{Schunk} 582 583Another example of some interest in any object oriented system 584which allows multiple references to one single object is that 585object identity 586can be tested using the respective base function: 587 588\begin{Schunk} 589\begin{Sinput} 590> addProto$identical(addProto2) 591\end{Sinput} 592\begin{Soutput} 593[1] FALSE 594\end{Soutput} 595\end{Schunk} 596 597\code{proto} does contain a special purpose \code{str.proto} function 598but in the main it 599is important to notice here, that 600\code{proto} has no code that is specific to \code{ls} or 601any of the other ordinary \proglang{R} 602functions listed. We are simply making use of the 603fact that \code{obj\$fun(...)} is transformed into \code{get("fun", 604obj)(obj, ...)} by the proto \code{\$} operator. For example, in the 605case of \code{addProto\$ls()} the system looks for \code{ls} in object 606\code{addProto}. It cannot find it there so it looks to its parent, 607which is the global environment. It does not find it there so it 608searches the remainder of the search path, i.e. the path shown by 609running the \proglang{R} command \code{search()}, and finally finds it 610in the base package, invoking it with an argument of \code{addProto}. 611Since all \code{proto} objects are also environments 612\code{ls(addProto)} interprets \code{addProto} as an environment and 613runs the \code{ls} command with it. In the \code{ls} example there 614were no arguments other than \code{addProto}, and even that one was 615implicit, but if there were 616additional arguments then they would be passed as shown in the 617\code{eapply} and \code{identical} examples above. 618 619\subsection{Plotting} 620\label{sec:plot} 621 622The \code{graph.proto} function can be used to create 623graphs that can be rendered by the \code{Rgraphviz} package 624creating visual representations of ancestor trees (figure 625\ref{fig:proto-dot}). 626That package provides an interface to the 627\proglang{GraphViz} \code{dot} program \citep{Ganser+North:1999}. 628 629\code{graph.proto} takes three arguments, all of which are 630usually omitted. The first argument is a \code{proto} object 631(or an environment) out of which all contained \code{proto} objects 632and their parents (but not higher order ancestors) are graphed. 633If it is omitted, the current environment is assumed. 634The second argument is a graph (in the sense of the \code{graph} 635package) to which the nodes and edges are added. If it is omitted 636an empty graph is assumed. The last argument is a logical variable 637that specifies the orientation of arrows. If omitted arrows are 638drawn from children to their parents. 639 640 641\input{proto-dot} 642 643\begin{figure}[htbp] 644\begin{center} 645\includegraphics{proto-dot} 646\caption{\label{fig:proto-dot} Ancestor tree generated using graph.proto. Edges 647point from child to parent.} 648\end{center} 649\end{figure} 650 651\pagebreak[4] 652 653\section{Examples} 654\label{sec:examples} 655 656\subsection{Smoothing} 657\label{sec:smooth} 658 659In the following we create a \code{proto} object named \code{oo} 660containing a vector of data \code{x} (generated from a simulated 661autoregressive model) and time points 662\code{tt}, an intermediate result 663\code{x.smooth}, some plotting parameters \code{xlab}, \code{ylab}, 664\code{pch}, \code{col} and three methods \code{smooth}, \code{plot} 665and \code{residuals} which smooth the data, plot the data and 666calculate residuals, respectively. We also define \code{..x.smooth} 667which holds intermediate results. Names beginning with two dots 668prevent them from being delegated to children. If we override 669\code{x} in a child we would not want an out-of-sync \code{x.smooth}. 670Note that the components of an object can be specified using a code 671block in place of the argument notation we used previously in the 672\code{proto} command. 673 674\begin{Schunk} 675\begin{Sinput} 676> oo <- proto(expr = { 677+ x <- rnorm(251, 0, 0.15) 678+ x <- filter(x, c(1.2, -0.05, -0.18), method = "recursive") 679+ x <- unclass(x[-seq(100)]) * 2 + 20 680+ tt <- seq(12200, length = length(x)) 681+ ..x.smooth <- NA 682+ xlab <- "Time (days)" 683+ ylab <- "Temp (deg C)" 684+ pch <- "." 685+ col <- rep("black", 2) 686+ smooth <- function(., ...) { 687+ .$..x.smooth <- supsmu(.$tt, .$x, ...)$y 688+ } 689+ plot <- function(.) with(., { 690+ graphics::plot(tt, x, pch = pch, xlab = xlab, ylab = ylab, 691+ col = col[1]) 692+ if (!is.na(..x.smooth[1])) 693+ lines(tt, ..x.smooth, col = col[2]) 694+ }) 695+ residuals <- function(.) with(., { 696+ data.frame(t = tt, y = x - ..x.smooth) 697+ }) 698+ }) 699\end{Sinput} 700\end{Schunk} 701 702Having defined our \code{proto} object we can inspect it, as shown 703below, using 704\code{print} which is automatically invoked if the 705name of the object, \code{oo}, is entered on a line by itself. 706In this case, there is no proto print method so we inherit the 707environment print method which displays the environment hash code. 708Although it produces too much output to show here, 709we could have displayed a 710list of the entire contents of the object \code{oo} 711via \code{oo\$as.list(all.names = TRUE)}. 712We can get a list of the names of the 713components of the object using \code{oo\$ls(all.names = TRUE)} and will look 714at the contents of one component, \code{oo\$pch}. 715 716\begin{Schunk} 717\begin{Sinput} 718> oo 719\end{Sinput} 720\begin{Soutput} 721<environment: 0x01fbd8c8> 722attr(,"class") 723[1] "proto" "environment" 724\end{Soutput} 725\begin{Sinput} 726> oo$ls(all.names = TRUE) 727\end{Sinput} 728\begin{Soutput} 729 [1] "..x.smooth" ".super" ".that" "col" "pch" 730 [6] "plot" "residuals" "smooth" "tt" "x" 731[11] "xlab" "ylab" 732\end{Soutput} 733\begin{Sinput} 734> oo$pch 735\end{Sinput} 736\begin{Soutput} 737[1] "." 738\end{Soutput} 739\end{Schunk} 740 741Let us illustrate a variety of manipulations. We will set up the 742output to plot 2 plots per screen using \code{mfrow}. We change the 743plotting symbol, smooth the data, invoke the \code{plot} method to 744display a plot of the data and the smooth and then plot the residuals 745in the second plot (figure \ref{fig:proto-smooting03}). 746 747 748\input{proto-smoothing03} 749 750\begin{figure}[h!] 751\begin{center} 752\includegraphics[width=\textwidth]{proto-smoothing03} 753\end{center} 754\caption{Data and smooth from \code{oo\$plot()} (left) and plot of 755\code{oo\$residuals()} (right).} 756\label{fig:proto-smooting03} 757\end{figure} 758 759 760Now let us illustrate the creation of a child object and delegation. 761We create a new child object of \code{oo} called \code{oo.res}. We 762will override the \code{x} value in its parent by setting \code{x} in 763the child to the value of the residuals in the parent. We will also 764override the \code{pch} and \code{ylab} plotting parameters. We will 765return to 1 plot per screen and run \code{plot} using the 766\code{oo.res} object as the receiver invoking the \code{smooth} and 767\code{plot} methods (which are delegated from the parent \code{oo}) 768with the data in the child (figure \ref{fig:smoothing04}). 769 770\input{proto-smoothing04} 771% \begin{figure}[tp] 772\begin{figure}[h!] 773\begin{center} 774\includegraphics[width=\half]{proto-smoothing04} 775\end{center} 776\caption{Output of \code{oo.res\$plot()}. 777\code{oo.res\$x} contains the residuals from \code{oo}.} 778\label{fig:smoothing04} 779\end{figure} 780Now we make use of delegation to change the parent 781and child in a consistent way with respect to certain plot characteristics. 782We have been using a numeric time axis. 783Let us interpret these numbers as the number of days since the Epoch, 784January 1, 1970, and let us also change the plot colors. 785 786\begin{Schunk} 787\begin{Sinput} 788> oo$tt <- oo$tt + as.Date("1970-01-01") 789> oo$xlab <- format(oo.res$tt[1], "%Y") 790> oo$col <- c("blue", "red") 791\end{Sinput} 792\end{Schunk} 793 794 795We can introduce a new method, \code{splot}, into 796the parent \code{oo} and have it automatically 797inherited by its children. In this example 798it smooths and then plots and we use it with 799both \code{oo} and \code{oo.res} (figure \ref{fig:smoothing06}). 800 801 802\input{proto-smoothing06} 803 804\begin{figure}[tbp] 805\begin{center} 806\includegraphics[width=\textwidth]{proto-smoothing06} 807\caption{Plotting options and \code{splot} function applied 808to both parent (left) and child (right) object} 809\label{fig:smoothing06} 810\end{center} 811\end{figure} 812 813Numerous possibilities exist to make use of the 814mechanisms shown, so one may create different child objects, apply 815different smoothing parameters, overwrite the smoothing function with 816a lowess smoother and finally compare fits and residuals. 817 818Now lets change the data and repeat the analysis. Rather than 819overwrite the data we will preserve it in \code{oo} and create a child 820\code{oos} to hold an analysis with sinusoidal data. 821 822\begin{Schunk} 823\begin{Sinput} 824> oos <- oo$proto(expr = { 825+ tt <- seq(0, 4 * pi, length = 1000) 826+ x <- sin(tt) + rnorm(tt, 0, 0.2) 827+ }) 828> oos$splot() 829\end{Sinput} 830\end{Schunk} 831 832Lets perform the residual analysis with \code{oos}. 833We will make a deep copy of \code{oo.res}, i.e. duplicate its 834contents and not merely delegate it, by copying \code{oo.res} 835to a list from which we create the duplicate, or cloned, 836\code{proto} object (figure \ref{fig:smoothing10} and \ref{fig:cloning}): 837 838\begin{Schunk} 839\begin{Sinput} 840> oos.res <- as.proto(oo.res$as.list(), parent = oos) 841> oos.res$x <- oos$residuals()$y 842> oos.res$splot() 843\end{Sinput} 844\end{Schunk} 845 846 847\begin{figure}[tbp] 848\begin{center} 849\includegraphics[width=\textwidth]{proto-smoothing10} 850\caption{Smoothing of sinusoidal data (left) 851and of their residuals (right)}\label{fig:smoothing10} 852\end{center} 853\end{figure} 854 855\begin{figure}[h!] 856\begin{center} 857\includegraphics[width=50mm]{cloning3.pdf} 858\caption{Cloning (dashed line) and delegation (solid line). Edges point 859from child to parent.}\label{fig:cloning} 860\end{center} 861\end{figure} 862 863We have delegated variables 864and methods and overridden both. 865Thus, even with such a simple analysis, object orientation 866and delegation came into play. 867The reader can plainly see that smoothing and residual 868analysis were not crucial to the example and this example 869could be replaced with any statistical analysis including 870likelihood or other estimation techniques, time series, survival 871analysis, stochastic processes and so on. The key aspect is 872just that we are performing one-of analyses and do not want to 873set up an elaborate class infrastructure but just want to 874directly create objects to organize our calculations while 875relying on delegation and dispatch to eliminate redundancy. 876 877\subsection{Correlation, Fisher's Transform and Bootstrapping} 878\label{sec:corr} 879 880The common approach to 881confidence intervals for the correlation coefficient is to 882assume normality of the underlying data and then use Fisher's transform 883to transform the correlation coefficient to an approximately normal 884random variable. 885Fisher showed that with the above normality assumption, transforming 886the correlation coefficient using 887the hyperbolic arc tangent function 888yields a random variable 889approximately distributed with an 890$\frac{N(p, 1)}{\sqrt(n-3)}$ distribution. The transformed random 891variable can be used to create normal distribution confidence intervals 892and the procedure can be back transformed to get confidence intervals 893for the original correlation coefficient. 894 895A more recent approach to confidence intervals for the correlation 896coefficient is to use bootstrapping. This does not require the 897assumption of normality of the underlying distribution and requires 898no special purpose theory devoted solely to the correlation coefficient, 899 900Let us calculate the 95\% 901confidence intervals using Fisher's transform 902first. We use \code{GNP} and \code{Unemployed} from the Longley data 903set. First we retrieve the data set and extract the required columns 904into \code{x}. Then we set \code{n} to the number of cases 905and \code{pp} to the percentiles 906of interest. Finally we calculate the sample correlation and 907create a function to calculate the confidence interval using 908Fisher's Transform. This function not only returns the confidence 909interval but also stores it in \code{CI} in the receiver object. 910 911\begin{Schunk} 912\begin{Sinput} 913> longley.ci <- proto(expr = { 914+ data(longley) 915+ x <- longley[, c("GNP", "Unemployed")] 916+ n <- nrow(x) 917+ pp <- c(0.025, 0.975) 918+ corx <- cor(x)[1, 2] 919+ ci <- function(.) (.$CI <- tanh(atanh(.$corx) + qnorm(.$pp)/sqrt(.$n - 920+ 3))) 921+ }) 922\end{Sinput} 923\end{Schunk} 924 925Now let us repeat this analysis using the bootstrapping approach. We 926derive a new object \code{longley.ci.boot} as child of 927\code{longley.ci}, setting the number of replications, \code{N}, and 928defining the procedure, \code{ci} which does the actual bootstrap 929calculation. 930 931\begin{Schunk} 932\begin{Sinput} 933> longley.ci.boot <- longley.ci$proto({ 934+ N <- 1000 935+ ci <- function(.) { 936+ corx <- function(idx) cor(.$x[idx, ])[1, 2] 937+ samp <- replicate(.$N, corx(sample(.$n, replace = TRUE))) 938+ (.$CI <- quantile(samp, .$pp)) 939+ } 940+ }) 941\end{Sinput} 942\end{Schunk} 943 944In the example code below the first line runs the Fisher Transform 945procedure and the second runs the bootstrap procedure. Just to check 946that we have performed sufficient bootstrap iterations we rerun it in 947the third line, creating a delegated object on-the-fly running its 948\code{ci} method and then immediately throwing the object away. 949The fact that 4,000 950replications give roughly the same result as 1,000 replications 951satisfies us that we have used a sufficient number of replications. 952 953\begin{Schunk} 954\begin{Sinput} 955> longley.ci$ci() 956\end{Sinput} 957\begin{Soutput} 958[1] 0.1549766 0.8464304 959\end{Soutput} 960\begin{Sinput} 961> longley.ci.boot$ci() 962\end{Sinput} 963\begin{Soutput} 964 2.5% 97.5% 9650.2299395 0.8211854 966\end{Soutput} 967\begin{Sinput} 968> longley.ci.boot$proto(N = 4000)$ci() 969\end{Sinput} 970\begin{Soutput} 971 2.5% 97.5% 9720.2480999 0.8259276 973\end{Soutput} 974\end{Schunk} 975 976We now have the results stored in two objects nicely organized for the 977future. Note, again, that despite the simplicity of the example we 978have used the features of object oriented programming, coupling the 979data and methods that go together, while relying on delegation and 980dispatch to avoid duplication. 981 982\subsection{Dendrograms} 983\label{sec:tree} 984 985In \cite{Gentleman2002} there is an \proglang{S4} 986example of creating a binary tree 987for use as a dendrogram. Here we directly define a binary tree with no 988setup at all. To keep it short we will create a binary tree of only 989two nodes having a root whose left branch points to a leaf. The leaf 990inherits the \code{value} and \code{incr} components from the root. 991The attractive feature is that the leaf be defined as a child of the 992parent using \code{proto} before the parent is even finished 993being defined. Compared to the cited \proglang{S4} example where it 994was necessary to create an extra class to introduce the required level of 995indirection there is no need to take any similar action. 996 997\code{tree} is the root node of the tree. It has four components. A 998method \code{incr} which increments the \code{value} component, a 999\code{..Name}, the \code{value} component itself and the left branch 1000\code{..left}. \code{..left} is itself a proto object which is a 1001child of \code{tree}. The leaf inherits the \code{value} component 1002from its parent, the root. As mentioned, at the time we define 1003\code{..left} we have not even finished defining \code{tree} yet we 1004are able to implicitly reference the yet to be defined parent. 1005 1006\begin{Schunk} 1007\begin{Sinput} 1008> tree <- proto(expr = { 1009+ incr <- function(., val) .$value <- .$value + val 1010+ ..Name <- "root" 1011+ value <- 3 1012+ ..left <- proto(expr = { 1013+ ..Name = "leaf" 1014+ }) 1015+ }) 1016\end{Sinput} 1017\end{Schunk} 1018 1019Although this is a simple structure we could have embedded additional 1020children into \code{root} and \code{leaf} and so on recursively making 1021the tree or dendrogram arbitrarily complex. 1022 1023Let us do some computation with this structure. We display the 1024\code{value} fields in the two nodes, increment the value field in the 1025root and then display the two nodes again to show .that the leaf 1026changed too. 1027 1028\begin{Schunk} 1029\begin{Sinput} 1030> cat("root:", tree$value, "leaf:", tree$..left$value, "\n") 1031\end{Sinput} 1032\begin{Soutput} 1033root: 3 leaf: 3 1034\end{Soutput} 1035\begin{Sinput} 1036> tree$incr(1) 1037> cat("root:", tree$value, "leaf:", tree$..left$value, "\n") 1038\end{Sinput} 1039\begin{Soutput} 1040root: 4 leaf: 4 1041\end{Soutput} 1042\end{Schunk} 1043 1044If we increment \code{value} in \code{leaf} directly (see the example 1045below where we increment it by 10) then it receives its own copy of 1046\code{value} so from that point on \code{leaf} no longer inherits 1047\code{value} from \code{root}. Thus incrementing the root by 5 no 1048longer increments the \code{value} field in the leaf. 1049 1050\begin{Schunk} 1051\begin{Sinput} 1052> tree$..left$incr(10) 1053> cat("root:", tree$value, "leaf:", tree$..left$value, "\n") 1054\end{Sinput} 1055\begin{Soutput} 1056root: 4 leaf: 14 1057\end{Soutput} 1058\begin{Sinput} 1059> tree$incr(5) 1060> cat("root:", tree$value, "leaf:", tree$..left$value, "\n") 1061\end{Sinput} 1062\begin{Soutput} 1063root: 9 leaf: 14 1064\end{Soutput} 1065\end{Schunk} 1066 1067\subsection{From Prototypes to Classes} 1068\label{sec:increment} 1069 1070In many cases we will use \pkg{proto} for a design that uses prototypes 1071during the full development cycle. In other cases we may use it in an 1072incremental way starting with prototypes but ultimately transitioning 1073to classes. 1074As shown in Section~\ref{sec:traits} the \pkg{proto} package is 1075powerful enough to handle class-based as well as class-free programming. 1076Here we illustrate this process of incremental design 1077starting with 1078concrete objects and then over time classifing them into classes, 1079evolving a class-based program. \pkg{proto} provides a smooth 1080transition path since it can handle both the class-free and the class-based 1081phases -- there is no need to switch object systems part way through. 1082In this example, we define an object which holds a linear equation, \code{eq}, 1083represented as a character string in terms of the unknown variable \code{x} 1084and a \code{print} and a \code{solve} method. We execute the 1085\code{print} method 1086to solve it. We also create child object \code{lineq2} 1087which overrides \code{eq} and execute its \code{print} method. 1088 1089\begin{Schunk} 1090\begin{Sinput} 1091> lineq <- proto(eq = "6*x + 12 - 10*x/4 = 2*x", solve = function(.) { 1092+ e <- eval(parse(text = paste(sub("=", "-(", .$eq), ")")), 1093+ list(x = 0+1i)) 1094+ -Re(e)/Im(e) 1095+ }, print = function(.) cat("Equation:", .$eq, "Solution:", .$solve(), 1096+ "\n")) 1097> lineq$print() 1098\end{Sinput} 1099\begin{Soutput} 1100Equation: 6*x + 12 - 10*x/4 = 2*x Solution: -8 1101\end{Soutput} 1102\begin{Sinput} 1103> lineq2 <- lineq$proto(eq = "2*x = 7*x-12+x") 1104> lineq2$print() 1105\end{Sinput} 1106\begin{Soutput} 1107Equation: 2*x = 7*x-12+x Solution: 2 1108\end{Soutput} 1109\end{Schunk} 1110 1111We could continue with enhancements but at this point we decide that we 1112have a general case and so wish 1113to abstract \code{lineq} into a class. Thus we define a trait, 1114\code{Lineq}, which is just \code{lineq} minus \code{eq} plus 1115a constructor \code{new}. The key difference between \code{new} 1116and the usual \code{proto} function 1117is that with \code{new} the initialization of \code{eq} is mandatory. 1118Having completed this definition 1119we instantiate an object of 1120class/trait \code{Lineq} and execute it. 1121 1122\begin{Schunk} 1123\begin{Sinput} 1124> Lineq <- lineq 1125> rm(eq, envir = Lineq) 1126> Lineq$new <- function(., eq) proto(., eq = eq) 1127> lineq3 <- Lineq$new("3*x=6") 1128> lineq3$print() 1129\end{Sinput} 1130\begin{Soutput} 1131Equation: 3*x=6 Solution: 2 1132\end{Soutput} 1133\end{Schunk} 1134 1135Note how we have transitioned from a prototype style of programming 1136to a class-based style of programming all the while staying within 1137the \pkg{proto} framework. 1138 1139\section{Summary} \label{sec:summary} 1140 1141\subsection{Benefits} 1142\label{sec:benefits} 1143 1144The key benefit of the \pkg{proto} package is to provide 1145access to a style of programming that has not been conveniently 1146accessible within \proglang{R} or any other mainstream language today. 1147 1148\pkg{proto} can be used in two key ways: class-free object oriented programming 1149and class-based object oriented programming. 1150 1151A key application for \pkg{proto} in class-free programming is to wrap the code 1152and data for each run of a particular statistical study into an object for 1153purposes of organization and reproducibility. It provides such organization 1154directly and without the need and overhead of class definitions 1155yet still provides the 1156inheritance and dispatch advantages of object oriented programming. 1157We provide examples of this style of programming in 1158Section~\ref{sec:smooth} 1159and 1160Section~\ref{sec:corr}. 1161A third example in 1162Section~\ref{sec:tree} illustrates a beneficial use of \pkg{proto} with 1163recursive data structures. 1164 1165Another situation where prototype programming is of interest is in the initial 1166development stages of a program. In this case, the design may not be fully 1167clear so it is more convenient to create concrete objects individually rather 1168than premature abstractions through classes. The \code{graph.proto} 1169function can be used to generate visual representations of the object 1170tree suggesting classifications of objects so that 1171as the program evolves the general case becomes clearer and 1172in a bottom up fashion the objects are incrementally abstracted into 1173classes. In this case, 1174\pkg{proto} provides a smooth transition path since it not only supports 1175class-free programming but, as explained in the Section~\ref{sec:traits}, is 1176sufficiently powerful to support class-based programming, as well. 1177 1178 1179\subsection{Conclusion} 1180\label{sec:conclusion} 1181 1182The package \pkg{proto} provides an \proglang{S3} subclass of the 1183\code{environment} class for constructing and manipulating object 1184oriented systems without classes. It can also emulate classes even 1185though classes are not a primitive structure. Its key design goals 1186are to provide as simple and as thin a layer as practically possible 1187while giving the user convenient access to this alternate object 1188oriented paradigm. This paper describes, by example, how prototype 1189programming can be carried out in \proglang{R} using \pkg{proto} and 1190illustrates such usage. Delegation, cloning traits and general 1191manipulation and incremental development are all reviewed by example. 1192 1193\section*{Computational details} 1194\label{sec:compute} 1195 1196The results in this paper were obtained using \proglang{R} 2.1.0 with 1197the package \pkg{proto} 0.3--2. \proglang{R} itself and the 1198\pkg{proto} package are available from CRAN at 1199\url{http://CRAN.R-project.org/}. The GraphViz software is available 1200from \url{http://www.graphviz.org}. 1201 1202\phantomsection 1203\addcontentsline{toc}{section}{References} 1204\bibliography{proto} 1205%\input{proto.bbl} 1206 1207\newpage\mbox{} 1208\begin{appendix} 1209\section{Frequently Asked Questions} 1210\label{sec:faq} 1211\begin{enumerate} 1212\item{What scope do unqualified object references within methods use? 1213 1214A \pkg{proto} object is an environment and that environment 1215is the environment 1216of the methods in it (by default). 1217That is, unqualified object references 1218within a \pkg{proto} method look first in the method itself and secondly in the 1219\pkg{proto} object containing the method. 1220This is referred to as object 1221scope as opposed to lexical scope or dynamic scope. It allows simple 1222situations, where delegation is not used, to use unqualified names. Thus 1223simple situations remain simple. 1224\citep{Kates2004} 1225discusses the fragile base class problem which 1226relates to this question. Also note that if a \pkg{proto} object is created 1227via the \code{proto} function using an argument of \code{funEnvir = FALSE} 1228then the environment of the function/method will not be set as just 1229described (but rather it will retain its original environment) so the 1230above does not apply. This can be used for instances when non-default 1231processing is desirable.} 1232\item{Why does \code{obj\$meth} not return the method, \code{meth}? 1233 1234Conceptually \code{obj\$meth} returns \code{meth} but with 1235\code{obj} already inserted into its first argument. 1236This is termed an instantiated 1237\pkg{proto} 1238method and is of \proglang{S3} class \code{"instantiatedProtoMethod"}. 1239 1240In contrast, the method itself (i.e. the uninstantited method) 1241would not have the first argument already 1242inserted. To return the method itself use \code{with(obj, meth}. 1243 1244The main advantage of a design that makes the distinction between instantiated 1245and uninstantiated methods is that uninstantiated methods are never 1246changed so 1247debugging can be more readily carried out (as discussed in the next 1248question and answer). 1249} 1250\item{How does one debug a method? 1251 1252\pkg{proto} does not dynamically redefine methods. This has the advantage 1253that the ordinary \proglang{R} \code{debug} and \code{undebug} commands can be 1254used. When using these be sure that to use them with the uninstantiated method 1255itself and not the instantiated method derived from it. That is, 1256use: 1257\begin{verbatim} 1258 with(obj, debug(meth)) 1259\end{verbatim} 1260 1261and not 1262\begin{verbatim} 1263 debug(obj$meth) # wrong 1264\end{verbatim} 1265} 1266\item{Is multiple inheritance supported? 1267 1268No. \pkg{proto} is just a thin layer on top of \proglang{R} 1269environments and \proglang{R} environments 1270provide single inheritance only. \citep{Kates2004} 1271discusses some ways of handling situations which would otherwise require 1272multiple inheritance.} 1273\item{Does \pkg{proto} support lazy evaluation? 1274 1275Since \code{proto} methods are just \proglang{R} functions they do support 1276lazy evaluation; however, the \code{proto} function itself 1277does evaluate its arguments. To get the 1278effect of lazy evaluation when using the \code{proto} 1279function replace any properties with a function. 1280 1281If the caller is the parent of the \code{proto} object then its 1282particularly simple. Note how we got the equivalent of lazy evaluation 1283in the second example where f is a function: 1284 1285\begin{verbatim} 1286# eager evaluation 1287x <- 0 1288p <- proto(f = x, g = function(.) $x) 1289x <- 1 1290p$f # 0 1291 1292# versus making f a function 1293 1294# simulates lazy evaluation 1295x <- 0 1296p <- proto(f = function(.) x, g = function(.) .$x) 1297x <- 1 1298p$f() # 1 1299\end{verbatim} 1300 1301If we cannot guarantee that the proto object has the caller 1302as its parent then ensure that the environment of the function 1303has not been reset. If no method needs to reference \code{.that} 1304or \code{.super} then we can arrange for that using 1305\code{funEnvir=FALSE} as seen here in the second example: 1306\begin{verbatim} 1307 1308# does not work as intended 1309x <- 0 1310p <- proto(x = 99) 1311q <- p$proto(f = function(.) x, g = function(.) .$x) 1312x <- 1 1313q$f() # 99 1314 1315# does work 1316x <- 0 1317p <- proto(x = 99) 1318q <- p$proto(f = function(.) x, g = function(.) .$x, funEnvir = FALSE) 1319x <- 1 1320q$f() # 1 1321\end{verbatim} 1322 1323If we wish only to not reset the function used to simulate 1324lazy evaluation then we can do it using either of the 1325two equivalent alternatives below. \code{g} 1326is an ordinary method whose environment is reset to \code{q} 1327whereas \code{f} is a function whose environment is not reset and 1328serves to provide lazy evaluation for \code{x} found in the caller. 1329 1330\begin{verbatim} 1331x <- 0 1332p <- proto(x = 99) 1333# g will use q's y in children of q even if those children 1334# override y 1335q <- p$proto(y = 25, g = function(.) .that$y + .$x) 1336q[["f"]] <- function(.) x 1337x <- 1 1338q$f() # 1 1339 1340# equivalent alternative 1341 1342x <- 0 1343p <- proto(x = 99) 1344q <- proto(f = function(.) x, funEnvir = FALSE, 1345 envir = p$proto(y = 25, g = function(.) .that$y + .$x)) 1346x <- 1 1347q$f() # 1 1348\end{verbatim} 1349} 1350\end{enumerate} 1351\newpage{} 1352\section{Reference Card} 1353\label{sec:ref} 1354\input{protoref-raw} 1355\end{appendix} 1356 1357\end{document} 1358 1359