commit 29e2e1bc90c707eb18fe6dd4c8ca7edce64d0fdc
parent c2e48aaa8c37ee29c73b89ccb6945a7774d12a56
Author: DrEntropy <DrEntropy@users.noreply.github.com>
Date:   Tue, 11 Apr 2023 05:31:51 -0700
Chapter 16 Notes Edited for Cohort  7 (#49)
* Adding S7 notes
* Partial draft
* Remove review of oop
* First complete draft
* typos fixed
Diffstat:
2 files changed, 398 insertions(+), 224 deletions(-)
diff --git a/16_Trade-offs.Rmd b/16_Trade-offs.Rmd
@@ -1,206 +1,380 @@
-# Trade-offs
-
-**Learning objectives:**
-
-- Understand the Trade-offs between S3, R6 and S4
-
-
-## Introduction to trade-offs
-
-> “Everything that exists in R is an object”
->
-> -- <cite>John Chambers</cite>
-
-R is a functional language, **functions** made in R are **objects** with special **attributes**, called **classes**.
-
-The **object-oriented system (OOP)** is the **environment** where objects and classes are defined and operate with a **scope**.
-
-The **inheritance** concept in OOP allows one class to derive the features and functionalities of another class. This feature facilitates code-reusability.
-
-```{r 16-Trade-offs-1, echo=FALSE,fig.align='center', fig.cap="[OOP](https://www.javatpoint.com/r-object-oriented-programming#:~:text=What%20is%20Object%2DOriented%20Programming,do%20programming%20in%20oops%20style.)"}
-knitr::include_graphics("images/16-oop.png")
-```
-
-**What is an object?**
-
-An object is a **data structure** that contains some **methods** based on attributes. 
-```{r}
-sloop::otype(1:10)
-sloop::otype(mtcars)
-```
-
-
-An object is also called an **instance** of a class, and the process of object creation is called **instantiation**.[^1]
-
-[^1]: [R – Object Oriented Programming](https://www.geeksforgeeks.org/r-object-oriented-programming/)
-```{r}
-class(1:10)
-class(mtcars)
-```
-
-
-**What is a class?**
-
-A class is where objects are defined and obtained by **encapsulating** data and functions.
-
-
-There are different types of classes in OOP:
-
-- **S3**
-- **R6**
-- **S4**
-
-
-```{r 16-Trade-offs-2, message=FALSE, warning=FALSE, paged.print=FALSE,echo=FALSE}
-library(tidyverse)
-```
-
-
-
-```{r 16-Trade-offs-3, echo=FALSE,fig.align='center',fig.cap="[r object-oriented programming](https://www.geeksforgeeks.org/r-object-oriented-programming/)"}
-knitr::include_graphics("images/16-objects.png")
-```
-
-
-## Understanding the Trade-offs
-
-Here we look to compare and contrast the OOP objects.
-
-
-### S4 versus S3
-
-**Which class to use S4 or S3? **
-
-- **S3** is a flexible class, made of a list with attributes and assigned names, it consists of three main **components**:
-
-     - Generic function
-     - method
-     - attributes
-     
-
-     
-- **S4** has a more structured approach, is more formal, more strict, and more verbose. It contains functions for defining methods and **generics**. 
-
-For example to define a class:
-
-     S3: class() <- ...
-     S4: setClass()
-     
-**S4 is a combination of increased complexity**, as well as S3, it allows for inheritance of both classes and methods.   
-     
-S4 is usually good for larger projects, such as **Bioconductor**, and complex systems of interrelated objects:
-
-It minimizes code duplication (an example is the {Matrix} package), and makes it easy to provide a general method that works for all inputs.
-
-
-
-### R6 versus S3
-
-When starting with OOP the S3 class is suggested as a default for its simplicity. Then, the tendency would be to lean towards **R6**.
-
-Example of S3: 
-    
-     plot(data)
-
-Example of R6:
-
-    data$plot
-    
-**R6** is built on **encapsulated objects**, rather than generic functions.   
-
-
-**Big differences: general trade-offs**
-
-```{r 16-Trade-offs-4, echo=FALSE,fig.align='center'}
-knitr::include_graphics("images/16-trade-offs.png")
-```
-
-#### Namespacing
-
-**Where methods are in the Space?**
-
-- in S3, **Generic functions** are **global**: there is a **global namespace** (same verbs, uniform API). The negatives are related to **homonyms** methods.
-
-- in R6, **Encapsulated methods** are **local**: objects with a **scope**
-
-
-#### Threading state or accumulator programming
-
-
-In S3 the challenge is to return a value and modify the object. This can't be done, it violates set guidelines.
-
-
-As an example, see the **16-example_accumulator_programming.R** in the scripts folder.
-
-
-Or a way to do **multiple assign** operators with the {zeallot} package.
-
-```{r 16-Trade-offs-5, eval=FALSE}
-vignette('unpacking-assignment')
-```
-
-
-#### Method chaining
-
-Useful to compose functions from left-to-right.
-
-Use of the operators:
-
-- S3: `%>%`
-- R6: `$`
-
-
-
-
-## Meeting Videos
-
-### Cohort 1
-
-`r knitr::include_url("https://www.youtube.com/embed/W1uc8HbyZvI")`
-
-### Cohort 2
-
-`r knitr::include_url("https://www.youtube.com/embed/bzo37PHCM1I")`
-
-### Cohort 3
-
-`r knitr::include_url("https://www.youtube.com/embed/_byYFTQHp1Y")`
-
-### Cohort 4
-
-`r knitr::include_url("https://www.youtube.com/embed/vdKDPBcOc6Y")`
-
-### Cohort 5
-
-`r knitr::include_url("https://www.youtube.com/embed/3EvqtVYTFVM")`
-
-### Cohort 6
-
-`r knitr::include_url("https://www.youtube.com/embed/vEButxFIvLw")`
-
-<details>
-<summary> Meeting chat log </summary>
-
-```
-00:11:36	Oluwafemi Oyedele:	I have not built anything with them!!!
-00:16:31	Arthur Shaw:	https://cran.r-project.org/web/packages/sp/index.html
-00:19:05	Arthur Shaw:	Apparently Hadley asked the same question we're asking several years ago: https://stackoverflow.com/questions/5437238/which-packages-make-good-use-of-s4-objects
-00:19:16	Trevin:	HA
-00:23:54	Trevin:	Your audio is breaking up Federica
-01:06:58	Federica Gazzelloni:	https://mastering-shiny.org/reactive-motivation.html?q=R6#event-driven
-01:07:37	Federica Gazzelloni:	https://engineering-shiny.org/common-app-caveats.html?q=R6#using-r6-as-data-storage
-01:10:52	Oluwafemi Oyedele:	Thank you !!!
-```
-</details>
-
-### Cohort 7
-
-`r knitr::include_url("https://www.youtube.com/embed/URL")`
-
-<details>
-
-<summary>Meeting chat log</summary>
-```
-LOG
-```
-</details>
+# Trade-offs
+
+**Learning objectives:**
+
+- Understand the Trade-offs between S3, R6 and S4
+
+- Brief intro to S7 (the object system formerly known as R7)
+
+
+## Introduction
+
+* We have three OOP systems introduced so far (S3, S4, R6) 
+
+* At the current time (pre - S7?) Hadley recommends use S3 by default: It's simple and widely used throughout base R and CRAN.
+
+* If you have experience in other languages,  *Resist* the temptation to use R6 even though it will feel more familiar!
+
+
+## S4 versus S3 
+
+**Which functional object system to use, S4 or S3? **
+
+- **S3** is a simple and flexible system.
+   
+   - Good for small teams who need flexibility and immediate payoffs.
+   
+   - Commonly used throughout base R and CRAN 
+   
+   - Flexibility can cause problems, more complex systems might require formal conventions
+   
+
+- **S4** is a more formal, strict system. 
+
+   - Good for large projects and large teams
+   
+   - Used by Bioconductor project
+   
+   - Requires significant up front investment in design, but payoff is a robust system that enforces conventions.
+   
+   - S4 Documentation is challenging to use. 
+    
+
+
+## R6 versus S3
+
+**R6** is built on **encapsulated objects**, rather than generic functions.   
+
+
+**Big differences: general trade-offs**
+
+```{r 16-Trade-offs-4, echo=FALSE,fig.align='center'}
+knitr::include_graphics("images/16-trade-offs.png")
+```
+
+## Namespacing {-}
+
+**Where methods are found?**
+
+- in S3, **Generic functions** are **global** and live in the **global namespace**
+
+   - Advantage: Uniform API: `summary`, `print`, `predict` etc.
+   
+   - Disadvantage: Must be careful about creating new methods!  Homonyms must be avoided, don't define `plot(bank_heist)`
+ 
+
+- in R6, **Encapsulated methods** are **local**: objects with a **scope**
+
+   - Advantage: No problems with homonyms:  meaning of `bank_heist$plot()` is clear and unambiguous.
+   
+   - Disadvantage: Lack of a uniform API, except by convention.
+   
+
+## Threading state {-}
+
+
+In S3 the challenge is to return a value and modify the object. 
+
+
+```{r}
+new_stack <- function(items = list()) {
+  structure(list(items = items), class = "stack")
+}
+
+push <- function(x, y) {
+  x$items <- c(x$items, list(y))
+  x
+}
+```
+
+No problem with that, but what about when we want to pop a value?  We need to return two things.
+
+```{r}
+pop <- function(x) {
+  n <- length(x$items)
+  
+  item <- x$items[[n]]
+  x$items <- x$items[-n]
+  
+  list(item = item, x = x)
+}
+```
+
+The usage is a bit awkward:
+
+```{r}
+s <- new_stack()
+s <- push(s, 10)
+s <- push(s, 20)
+
+out <- pop(s)
+# Update state:
+s <- out$x
+
+print(out$item)
+```
+
+
+In python and other languages we have structured binding to make this less awkward.  R has the {zeallot} package. For more, see this vignette:
+
+```{r 16-Trade-offs-5, eval=FALSE}
+vignette('unpacking-assignment')
+```
+
+However, this is all easier in R6 due to the reference semantics!
+
+```{r}
+Stack <- R6::R6Class("Stack", list(
+  items = list(),
+  push = function(x) {
+    self$items <- c(self$items, x)
+    invisible(self)
+  },
+  pop = function() {
+    item <- self$items[[self$length()]]
+    self$items <- self$items[-self$length()]
+    item
+  },
+  length = function() {
+    length(self$items)
+  }
+))
+
+s <- Stack$new()
+s$push(10)
+s$push(20)
+s$pop()
+```
+
+
+## Method chaining {-}
+
+Useful to compose functions from left-to-right.
+
+Use of the operators:
+
+- S3: `%>%`
+
+- R6: `$`
+
+```{r}
+s$push(44)$push(32)$pop()
+```
+
+
+## Umm... what about S7 ? {-}
+
+```{r standards, echo = FALSE,  fig.cap = "https://xkcd.com/927/"}
+
+knitr::include_graphics("https://imgs.xkcd.com/comics/standards_2x.png")
+
+```
+
+### Primary references: {-}
+
+* Docs: https://rconsortium.github.io/OOP-WG/
+
+* Talk by Hadley Wickham https://www.youtube.com/watch?v=P3FxCvSueag
+
+## S7 briefly {-}
+
+* S7 is a 'better' version of S3 with some of the 'strictness' of S4.
+
+```
+"A little bit more complex then S3, with almost all of the features, 
+all of the payoff of S4" - rstudio conf 2022, Hadley Wickham
+```
+
+* Compatible with S3: S7 objects are S3 objects!  Can even extend an S3 object with S7
+
+* Somewhat compatible with S4, see [compatability vignette](https://rconsortium.github.io/OOP-WG/articles/compatibility.html) for details. 
+
+* Helpful error messages! 
+
+* Note that it was previously called R7, but it was changed to "S7" to better reflect that it is functional not encapsulated! 
+
+## Abbreviated introduction based on the vignette {-}
+
+To install: 
+```{r, eval=FALSE}
+# install.packages("remotes")
+remotes::install_github("rconsortium/OOP-WG")
+```
+
+
+```{r, eval=FALSE}
+library(S7)
+dog <- new_class("dog", properties = list(
+  name = class_character,
+  age = class_numeric
+))
+dog
+
+
+#> <S7_class>
+#> @ name  :  dog
+#> @ parent: <S7_object>
+#> @ properties:
+#>  $ name: <character>          
+#>  $ age : <integer> or <double>
+```
+
+Note the 'class_character', these are S7 classes corresponding to the base classes.
+
+Now to use it:
+
+```{r, eval = FALSE}
+lola <- dog(name = "Lola", age = 11)
+lola
+
+#> <dog>
+#>  @ name: chr "Lola"
+#>  @ age : num 11
+```
+
+Properties can be set / read with '@', with automatic validation ('safety rails') based on the type!
+
+```{r, eval = FALSE}
+
+lola@age <- 12
+lola@age
+
+#> 12
+
+lola@age <- "twelve"
+
+#> Error: <dog>@age must be <integer> or <double>, not <character>
+
+```
+
+Note thehelpful error message!
+
+Like S3 (and S4) S7 has generics, implemented with `new_generic` and `method` for particular methods:
+
+```{r, eval = FALSE}
+speak <- new_generic("speak", "x")
+
+method(speak, dog) <- function(x) {
+  "Woof"
+}
+  
+speak(lola)
+
+#> [1] "Woof"
+```
+
+If we have another class, we can implement the generic for that too:
+
+```{r, eval = FALSE}
+cat <- new_class("cat", properties = list(
+  name = class_character,
+  age = class_double
+))
+method(speak, cat) <- function(x) {
+  "Meow"
+}
+
+fluffy <- cat(name = "Fluffy", age = 5)
+speak(fluffy)
+
+#> [1] "Meow"
+```
+
+Helpful messages:
+
+```{r, eval = FALSE}
+speak
+
+#> <S7_generic> speak(x, ...) with 2 methods:
+#> 1: method(speak, cat)
+#> 2: method(speak, dog)
+```
+
+
+"most usage of S7 with S3 will just work"
+
+```{r, eval = FALSE}
+method(print, cat) <- function(...) {
+  print("I am a cat.")
+}
+
+print(fluffy)
+#> "I am a cat"
+
+```
+
+*For validators, inheritance, dynamic properties and more,  see the [vignette!](https://rconsortium.github.io/OOP-WG/articles/S7.html)*
+
+https://rconsortium.github.io/OOP-WG/articles/S7.html
+
+## So... switch to S7 ? {-}
+
+$$
+\huge
+\textbf{Soon}^{tm}
+$$
+
+* Not yet... still in development! 
+
+* But consider trying it out:
+
+   * To stay ahead of the curve... S7 will be integrated into base R someday!
+   
+   * To contribute feedback to the S7 team!
+
+   * To get "almost all" of the benefits of S4 without the complexity !  
+   
+* In particular, if you have a new project that might require the complexity of S4, consider S7 instead!
+
+## Meeting Videos
+
+### Cohort 1
+
+`r knitr::include_url("https://www.youtube.com/embed/W1uc8HbyZvI")`
+
+### Cohort 2
+
+`r knitr::include_url("https://www.youtube.com/embed/bzo37PHCM1I")`
+
+### Cohort 3
+
+`r knitr::include_url("https://www.youtube.com/embed/_byYFTQHp1Y")`
+
+### Cohort 4
+
+`r knitr::include_url("https://www.youtube.com/embed/vdKDPBcOc6Y")`
+
+### Cohort 5
+
+`r knitr::include_url("https://www.youtube.com/embed/3EvqtVYTFVM")`
+
+### Cohort 6
+
+`r knitr::include_url("https://www.youtube.com/embed/vEButxFIvLw")`
+
+<details>
+<summary> Meeting chat log </summary>
+
+```
+00:11:36	Oluwafemi Oyedele:	I have not built anything with them!!!
+00:16:31	Arthur Shaw:	https://cran.r-project.org/web/packages/sp/index.html
+00:19:05	Arthur Shaw:	Apparently Hadley asked the same question we're asking several years ago: https://stackoverflow.com/questions/5437238/which-packages-make-good-use-of-s4-objects
+00:19:16	Trevin:	HA
+00:23:54	Trevin:	Your audio is breaking up Federica
+01:06:58	Federica Gazzelloni:	https://mastering-shiny.org/reactive-motivation.html?q=R6#event-driven
+01:07:37	Federica Gazzelloni:	https://engineering-shiny.org/common-app-caveats.html?q=R6#using-r6-as-data-storage
+01:10:52	Oluwafemi Oyedele:	Thank you !!!
+```
+</details>
+
+### Cohort 7
+
+`r knitr::include_url("https://www.youtube.com/embed/URL")`
+
+<details>
+
+<summary>Meeting chat log</summary>
+```
+LOG
+```
+</details>
diff --git a/bookclub-advr.Rproj b/bookclub-advr.Rproj
@@ -1,18 +1,18 @@
-Version: 1.0
-
-RestoreWorkspace: Default
-SaveWorkspace: Default
-AlwaysSaveHistory: Default
-
-EnableCodeIndexing: Yes
-UseSpacesForTab: Yes
-NumSpacesForTab: 2
-Encoding: UTF-8
-
-RnwWeave: Sweave
-LaTeX: pdfLaTeX
-
-AutoAppendNewline: Yes
-StripTrailingWhitespace: Yes
-
-BuildType: Website
+Version: 1.0
+
+RestoreWorkspace: Default
+SaveWorkspace: Default
+AlwaysSaveHistory: Default
+
+EnableCodeIndexing: Yes
+UseSpacesForTab: Yes
+NumSpacesForTab: 2
+Encoding: UTF-8
+
+RnwWeave: Sweave
+LaTeX: pdfLaTeX
+
+AutoAppendNewline: Yes
+StripTrailingWhitespace: Yes
+
+BuildType: Website