Skip to content

Commit

Permalink
Rephrase based on James' suggestion
Browse files Browse the repository at this point in the history
Co-authored-by: James Azam <[email protected]>
  • Loading branch information
Bisaloo and jamesmbaazam authored Jul 5, 2024
1 parent c222a94 commit e65f0f5
Showing 1 changed file with 4 additions and 4 deletions.
8 changes: 4 additions & 4 deletions posts/progressive-enhancement/index.qmd
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ format:
toc: true
---

We are continuing our post series on S3 and interoperability.
We are continuing our post series on S3 object orientation and interoperability in R.
We have previously discussed [what makes a good S3 class and how to choose a good parent for it, as well as when to write or not write a custom method](../parent-class).
We have highlighted in particular how classes inheriting from data.frames can simplify user experience because of familiarity, and reduce developer workload due to the pre-existing S3 methods.

Expand All @@ -22,9 +22,9 @@ We have detailed how to improve compatibility with the tidyverse by explaining:
Here, we are going to explore how to start adding support in the ecosystem for the new S3 classes while minimizing user-facing breaking changes.
We have previously delved into this topic with our post ["Convert Your R Function to an S3 Generic: Benefits, Pitfalls & Design Considerations"](../s3-generic) and this is a wider and higher-level view of the same topic.

The strategy presented here is the variation of a common concept in web development and the web ecosystem: [progressive enhancement](https://developer.mozilla.org/en-US/docs/Glossary/Progressive_Enhancement). This philosophy aims to support browsers with limited range of features, while allowing a slightly richer experience for browsers with extra features.
The strategy presented here is the variation of a common concept in web development and the web ecosystem: [progressive enhancement](https://developer.mozilla.org/en-US/docs/Glossary/Progressive_Enhancement). This philosophy aims to support browsers with a common set of essential features, and even richer features for browser with the most recent updates.
It makes sense to think about this philosophy with the prism of introducing new classes to a new software ecosystem as it has the similar constraints of multiple stakeholders with different interests and timelines.
The application of progressive enhancement in this context means that users or packages that did not (yet) adopt the new classes are not penalized compared to users or packages that did.
The application of progressive enhancement in this context means that users or packages that have not (yet) adopted the new classes are not penalized compared to users or packages that have.

## Adding class support to function inputs via progressive enhancement

Expand Down Expand Up @@ -141,7 +141,7 @@ inherits(data, "data.frame")

For a more realistic example, you can also see the work in progress to integrate the [new `contactmatrix` standard format](https://github.com/socialcontactdata/contactmatrix) for social contact data to the [contactdata package](https://github.com/Bisaloo/contactdata).

This is however only true if code in downstream analysis follows good practices [^1]. If existing code was testing equality of the class to a certain value, it will break when the new class value is appended. This is described in a [post on the R developer blog, when base R was adding a new `array` class value to `matrix` objects](https://developer.r-project.org/Blog/public/2019/11/09/when-you-think-class.-think-again/index.html). Class inheritance should never be tested via `class(x) == "some_class"`. Instead, `inherits(x, "some_class")` or `is(x, "some_class")` should be used to future-proof the code and allow appending an additional in the future.
This is however only true if code in downstream analysis follows good practices in checking for the class of an object [^1]. If existing code was testing equality of the class to a certain value, it will break when the new class value is appended. This is described in a [post on the R developer blog, when base R was adding a new `array` class value to `matrix` objects](https://developer.r-project.org/Blog/public/2019/11/09/when-you-think-class.-think-again/index.html). Class inheritance should never be tested via `class(x) == "some_class"`. Instead, `inherits(x, "some_class")` or `is(x, "some_class")` should be used to future-proof the code and allow appending an additional in the future.

[^1]: This is now [enforced in R packages by R CMD check](https://github.com/r-devel/r-svn/commit/77ebdff5adc200dfe9bc850bc4447088830d2ee0), and via the [`class_equals_linter()`](https://lintr.r-lib.org/reference/class_equals_linter.html) in the [lintr package](https://lintr.r-lib.org/).

Expand Down

0 comments on commit e65f0f5

Please sign in to comment.