-
Notifications
You must be signed in to change notification settings - Fork 42
Draft blog post for v0.2.0 release #464
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
t-kalinowski
wants to merge
8
commits into
main
Choose a base branch
from
release-0-2-0-blog-post
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
8 commits
Select commit
Hold shift + click to select a range
355e162
initial draft blog post
t-kalinowski b0ee189
Update vignettes/release-announcement-0-2-0.Rmd
t-kalinowski f1f861d
Update vignettes/release-announcement-0-2-0.Rmd
t-kalinowski 83ca42c
Update vignettes/release-announcement-0-2-0.Rmd
t-kalinowski 2ce84f8
Update vignettes/release-announcement-0-2-0.Rmd
t-kalinowski f31bb5d
move `library(S7)` earlier
t-kalinowski 5167ecc
remove gremlins
t-kalinowski 647faa2
Add "Who should use S7" section
t-kalinowski File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -18,3 +18,4 @@ | |
| ^compile_commands\.json$ | ||
| ^\.cache$ | ||
| ^\.vscode$ | ||
| ^vignettes/release-announcement-0-2-0\.Rmd$ | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,141 @@ | ||
| ```{r} | ||
| #| include: false | ||
| knitr::opts_chunk$set(collapse = TRUE, comment = "#>") | ||
| ``` | ||
|
|
||
| We're excited to announce that the S7 0.2.0 is now available on CRAN! | ||
| S7 is a new object-oriented programming (OOP) system designed to succeed both S3 and S4. | ||
| You might wonder why R needs a new OOP system when we already have two. | ||
| The reason lies in the history of R's OOP journey: S3 is a simple and effective system for single dispatch, while S4 adds formal class definitions and multiple dispatch, but at the cost of complexity. | ||
| This has forced developers to choose between the simplicity of S3 and the sophistication of S4. | ||
|
|
||
| The goal of S7 is to unify the OOP landscape by building on S3's existing dispatch system and incorporating the most useful features of S4 (along with some new ones), all with a simpler syntax. | ||
| S7's design and implementation have been a collaborative effort by a working group from the [R Consortium](https://www.r-consortium.org), including representatives from R-Core, Bioconductor, tidyverse/Posit, ROpenSci, and the wider R community. | ||
| Since S7 builds on S3, it is fully compatible with existing S3-based code. | ||
| It's also been thoughtfully designed to work with S4, and as we learn more about the challenges of transitioning from S4 to S7, we'll continue to add features to ease this process. | ||
|
|
||
| Our long-term goal is to include S7 in base R, but for now, you can install it from CRAN: | ||
|
|
||
| ```{r, eval = FALSE} | ||
| install.packages("S7") | ||
| ``` | ||
|
|
||
| ## What's new in the second release | ||
|
|
||
| The second release of S7 brings refinements and bug fixes. | ||
| Key new features include: | ||
|
|
||
| - The ability to define classes with lazy property default values. | ||
| - Initialization logic for properties with custom setters. | ||
| - Substantial speed improvements for property setting and getting with `@` and `@<-`. | ||
| - Expanded support for base S3 classes. | ||
| - `convert()` now has a default method for transforming a parent class instance into a subclass. | ||
|
|
||
| Additionally, there are numerous bug fixes and quality-of-life improvements, such as better error messages, improved support for base Ops methods, and compatibility improvements for using `@` in R versions prior to 4.3. | ||
|
|
||
| ## Who should use S7 | ||
|
|
||
| S7 is a great fit for R users who like to try new things but don't need to be the first. It's already used in several CRAN packages, and the tidyverse team is applying it in new projects. While you may still run into a few issues, many early problems have been resolved. | ||
|
|
||
| ## Usage | ||
|
|
||
| ```{r} | ||
| library(S7) | ||
| ``` | ||
|
|
||
| Let's dive into the basics of S7. | ||
| To learn more, check out the package vignettes, including a more detailed introduction in [`vignette("S7")`](https://rconsortium.github.io/OOP-WG/articles/S7.html), and coverage of generics and methods in [`vignette("generics-methods")`](https://rconsortium.github.io/OOP-WG/articles/generics-methods.html), and classes and objects in [`vignette("classes-objects")`](https://rconsortium.github.io/OOP-WG/articles/classes-objects.html). | ||
|
|
||
|
|
||
| ### Classes and Objects | ||
|
|
||
| S7 classes have formal definitions, specified by `new_class()`, which includes a list of properties and an optional validator. | ||
| For example, the following code creates a `range` class with `start` and `end` properties, and a validator to ensure that `start` is always less than `end`: | ||
|
|
||
| ```{r} | ||
| range <- new_class("range", | ||
| properties = list( | ||
| start = class_double, | ||
| end = class_double | ||
| ), | ||
| validator = function(self) { | ||
| if (length(self@start) != 1) { | ||
| "@start must be length 1" | ||
| } else if (length(self@end) != 1) { | ||
| "@end must be length 1" | ||
| } else if (self@end < self@start) { | ||
| "@end must be greater than or equal to @start" | ||
| } | ||
| } | ||
| ) | ||
| ``` | ||
|
|
||
| `new_class()` returns the class object, which also serves as the constructor to create instances of the class: | ||
|
|
||
| ```{r} | ||
| x <- range(start = 1, end = 10) | ||
| x | ||
| ``` | ||
|
|
||
| ### Properties | ||
|
|
||
| The data an object holds are called its **properties**. | ||
| Use `@` to get and set properties: | ||
|
|
||
| ```{r} | ||
| x@start | ||
| x@end <- 20 | ||
| x | ||
| ``` | ||
|
|
||
| Properties are automatically validated against the type declared in `new_class()` (in this case, `double`) and checked by the class **validator**: | ||
|
|
||
| ```{r, error = TRUE} | ||
| x@end <- "x" | ||
| x@end <- -1 | ||
| ``` | ||
|
|
||
| ### Generics and Methods | ||
|
|
||
| Like S3 and S4, S7 uses **functional OOP**, where methods belong to **generic** functions, and method calls look like regular function calls: `generic(object, arg2, arg3)`. | ||
| A generic uses the types of its arguments to automatically pick the appropriate method implementation. | ||
|
|
||
| You can create a new generic with `new_generic()`, specifying the arguments to dispatch on: | ||
|
|
||
| ```{r} | ||
| inside <- new_generic("inside", "x") | ||
| ``` | ||
|
|
||
| To define a method for a specific class, use `method(generic, class) <- implementation`: | ||
|
|
||
| ```{r} | ||
| method(inside, range) <- function(x, y) { | ||
| y >= x@start & y <= x@end | ||
| } | ||
|
|
||
| inside(x, c(0, 5, 10, 15)) | ||
| ``` | ||
|
|
||
| Printing the generic shows its methods: | ||
|
|
||
| ```{r} | ||
| inside | ||
| ``` | ||
|
|
||
| And you can retrieve the method for a specific class: | ||
|
|
||
| ```{r} | ||
| method(inside, range) | ||
| ``` | ||
|
|
||
| ## Known Limitations | ||
|
|
||
| While we are pleased with S7's design, there are still some limitations: | ||
|
|
||
| - S7 objects can be serialized to disk (with `saveRDS()`), but the current implementation saves the entire class specification with each object. This may change in the future. | ||
| - Support for implicit S3 classes `"array"` and `"matrix"` is still in development. | ||
|
|
||
| We expect the community will uncover more issues as S7 is more widely adopted. | ||
| If you encounter any problems, please file an issue at <https://github.com/RConsortium/OOP-WG/issues>. | ||
| We appreciate your feedback in helping us make S7 even better! | ||
| 😃 | ||
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.