···11# TODO: pull out latter part of statement and rewrite as `is_node(x)`
22node_or_na <- function(value) S7_inherits(value, node) || is.na(value) # predicate to check if `value` is a `node` or `NA`, pulled out to reduce duplication
33+# TODO: change to use unions if possible? `NA | node`?
3445node <- new_class("node",
56 package = "BigNum",
···113114 }
114115)
115116116116-#' Infinite precision natural number using a singly linked list
117117-#'
118118-#' @description
119119-#' TODO: WRITE THIS
120120-#'
121121-#' The `big_num` class is essentially a wrapper around [linked_list]
122122-#' with a custom print method as well as some defined operators such as
123123-#' `+`, `*`, and `^` with an integer.
124124-#'
125125-#' @export
126126-#' @param num A string representation of a num.
127117big_num <- new_class("big_num",
128118 parent = linked_list,
129119 package = "BigNum",
···131121 new_object(linked_list(num))
132122 }
133123)
134134-135135-# is.na <- new_external_generic("base", "is.na", "x")
136136-# method(is.na, node) <- function(x) !S7_inherits(x, node)
137124138125is_even <- new_generic("is_even", c("x"))
139126method(is_even, big_num) <- function(x) x@head@VALUE %% 2 == 0
···179166 append_to_start(node(x), ll)
180167}
181168182182-print <- new_external_generic("base", "print", "x")
183183-method(print, linked_list) <- function(x) {
169169+baseprint <- new_external_generic("base", "print", "x")
170170+method(baseprint, linked_list) <- function(x) {
184171 current <- x@head
185172 while (S7_inherits(current)) {
186173 cat(current@VALUE, "-> ")
···190177191178 invisible(x)
192179}
193193-method(print, big_num) <- function(x) {
180180+method(baseprint, big_num) <- function(x) {
194181 len <- x@length
195182196183 if (len == 0) {
···11+# As the website states, S7 uses this instead of `@export` to register methods.
22+# https://rconsortium.github.io/S7/reference/methods_register.html
13.onLoad <- function(lib, pkg) {
24 S7::methods_register()
35}
4677+# The following is also taken from the website:
58# enable usage of <S7_object>@name in package code
69#' @rawNamespace if (getRversion() < "4.3.0") importFrom("S7", "@")
710NULL
+43-16
README.md
···2233Written for `S7 0.2.0.`
4455+```
66+pak::pkg_install("VisruthSK/BigNum")
77+```
88+99+## Why S7?
1010+1111+This package was created for a number of reasons. Chief among those is to provide a worked example of S7 in a package context, but it was also written to purvey the benefits of S7. So here I wish to address some reasons why S7 is best, and why you should seriously consider using S7 the next time you need a class for something. This is almost entirely subjective, and as an op-ed, the points I make are personal. There are certainly many contexts where S7 is not appropriate (one could argue that this package is best suited to R6), but there are also many places where you *could* use S7; I'm more focused on the latter.
1212+1313+S7 is formal. I first encountered S3 when speaking to Dr Bodwin; the topic came up somehow and she showed me how flexible S3 is with an example, something like:
1414+1515+```{r}
1616+x <- 1:10
1717+class(x) <- "test"
1818+mean.test <- function(x){
1919+ "HELLO WORLD"
2020+}
2121+2222+mean(x)
2323+#> [1] "HELLO WORLD"
2424+```
2525+2626+I was shocked at how easy it was to defined a class and write its method for a generic, especially since my knowledge of OOP was mostly in Java (which is very verbose.) The flexibility offers a lot of obvious benefits, but it does come with some drawbacks. Firstly, I think it can be a bit hard to understand; I still find S3 object construction a bit strange. For example, if I wanted to skip `x`'s declaration, I could've written instead:
2727+2828+```{r}
2929+mean.test <- function(x){
3030+ "HELLO WORLD"
3131+}
3232+3333+mean(structure(1:10, class = "test"))
3434+```
3535+3636+but I think this is harder to reason about. The idea of just giving `1:10` a class without really defining what that class is, is strange to me. S7 makes it very clear what things are; I find this easier to reason about.
3737+538## Overview
639740***This project is a work in progress, needs reviews and revisions to check for consistency and such. Some best practices for S7 development (e.g. [documentation](https://github.com/RConsortium/S7/issues/315)) haven't been established yet though.***
···14471548["The S7 package is a new OOP system designed to be a successor to S3 and S4." - R Consortium Object-Oriented Programming Working Group.](https://rconsortium.github.io/S7/)
16491717-S7 is a new way to do OOP in R, and it is fantastic. That quote links to the official S7 website, which contains a great deal of information regarding S7--its origins, features, compatibility, specifications, etc. Any developer who wishes to use S7 should certainly study that website. It is quite cogent and detailed, and I use it as a reference all the time–its practically an extra chapter of Advanced R. This package is meant to be used in conjunction with the S7 website, hopefully serving as a (slightly non-contrived) total which can be used to understand how S7 can work in practice. Since S7 is so new, and is still technically experimental, major changes to the API aren't unusual. As such, for this project to be effective, it must be kept in time with S7 as the OOP system matures. Best practice, as and when they are developed, should be implemented to serve as an effective, worked out example for S7 package development.
5050+S7 is a new way to do OOP in R, and I think it is fantastic. The quote above links to the official S7 website, which contains a great deal of information regarding S7--its origins, features, compatibility, specifications, etc. I think any developer who wishes to use S7 should certainly study that website. It is quite cogent and detailed, and I use it as a reference all the time–its practically an extra chapter of Advanced R. This package is meant to be used in conjunction with the S7 website, hopefully serving as a (slightly non-contrived) implementation which can be used to understand how S7 can work in practice.
5151+5252+Some goals of the project, viz. with regards to S7:
18531919-S7 is in use by a number of people already–some are writing about their experiences as well. One I happened upon is this [blog post](https://blog.djnavarro.net/posts/2024-02-25_s7/) by Dr. Navarro detailing how they used S7 to make some of her latest artwork. Like all of Dr Navarro's posts, it is well worth a read.
5454+Since S7 is so new, and is still technically experimental, major changes to the API [aren't off the table](https://rconsortium.github.io/S7/index.html?q=experimental#s7). As such, for this project to be effective, it will be updated with S7 as the OOP system matures. The package's major version will follow S7, which is why this (will) release into 2.0.0. Best practices, as and when they are developed, will be implemented to serve as an effective, worked out example for S7 package development.
20552156### BigNum
22572358So what is BigNum? And why this project?
24592525-Firstly, it is important to note that this is a *toy* package. Whilst the package will build, and expose an API one can use to create `big_num` objects, I do not think one *should* use these as infinite precision numbers (for that purpose, look towards packages like [Rmpfr](https://cran.r-project.org/web/packages/Rmpfr/index.html).) This package's implementation is very rough and many properties one would expect from "numbers" are missing–negative numbers, subtraction, division, modulus, etc. are all not implemented. The point of this package is not to veritably implement infinite precision numbers, but rather to show how S7 can be used in a package to make some basic data structures and work with some generics/functions. The package itself is very simple and has a relatively concise and simple implementation. Since this package's purpose is pedagogical, there isn't much point in implementing all the aforementioned features.
6060+Firstly, it is important to note that this is wholly a *toy* package. Whilst the package will build, and expose an API one can use to create `big_num` objects, I do not think one *should* use these as arbitrary precision numbers (look towards packages like [Rmpfr](https://cran.r-project.org/web/packages/Rmpfr/index.html).) This package's implementation is very rough and many properties one would expect from "numbers" are missing–negation, subtraction, division, modulus, etc. are all not implemented. The point of this package is not to veritably implement infinite precision numbers, but rather to show how S7 can be used in a package to make some basic data structures and work with some generics/functions. The package itself is very simple and has a relatively concise implementation. Since this package's purpose is pedagogical, there isn't much point in implementing the aforementioned features.
26612727-So why BigNum specifically? Well, mostly because it's easy to implement. The BigNum project is taken from my CSC 203 class, a course in OOP at Cal Poly. As such, I already had all the methods implemented and a clear idea of what I needed to do and how, with the main work being in porting logic to R as opposed to devising the methods and classes needed. This greatly simplified dev time since I had a reference implementation to use. **Importantly,** **this (along with my lack of experience) could lead to unidiomatic R/S7 code and design patterns.** **If you notice anything strange, please open an issue/PR!**
6262+I wrote the S7 implementation first, and have since expanded to a S3 and S4 implementation (and might add a rough R6 one too?). These three versions (S3, S4, S7) have rough feature parity, but part of this project is to highlight the benefits of S7 so there are things you can't do (or at least, can't do as easily) in the other OOP structures.
6363+6464+So why BigNum specifically? Well, mostly because it's easy to implement. The BigNum project is taken from my CSC 203 class, a OOP course at Cal Poly. I already had all the methods implemented (in Java) and a clear idea of what I needed to do and how, with the main work being in porting design to R as opposed to novel thought. This greatly simplified dev time since I had a reference implementation to use. **Importantly,** **this (along with my lack of experience) could lead to unidiomatic R/S7 code and design patterns.** **If you notice anything strange, please open an issue/PR!**
28652929-I haven't developed an R package before, and so that provided additional motivation for me to create this project. That also means that this package is certainly written sub-optimally. Additionally, my experience with S7 is extremely limited–I would be extremely grateful for any and all R sourcerers who can rain issues and pull requests down from the heavens, fixing all my mistakes :)
6666+I haven't developed an R package before, and so that provided additional motivation for me to create this project. That also means that this package is certainly written sub-optimally. Additionally, my experience with S7 is extremely limited–I would be extremely grateful for any and all R sourcerers who can rain issues and pull requests down from the heavens fixing all my mistakes :)
30673168## References
32693370Vaughan D, Hester J, Kalinowski T, Landau W, Lawrence M, Maechler M, Tierney L, Wickham H (2024). *S7: An Object Oriented System Meant to Become a Successor to S3 and S4*. R package version 0.2.0.9000, <https://github.com/RConsortium/S7>, <https://rconsortium.github.io/S7/>.
3434-3535-Navarro, Danielle. 2024. “Creating New Generative Art Tools in R with Grid, Ambient, and S7.” February 25, 2024. <https://blog.djnavarro.net/posts/2024-02-25_s7/>.
36713772Henry L, Wickham H (2024). *rlang: Functions for Base Types and Core R and 'Tidyverse' Features*. R package version 1.1.4, <https://CRAN.R-project.org/package=rlang>.
3873···44794580## TODOs:
46814747-- Finish readme
4848-4949- - add more citations
5050-5182- Write documentation
52835384 - Comment code
54855555- - Some basic comments for actual use of package
5656-5786- Write tests
58875959-- Write a vignette?
6060-6161-- Website?8888+- Write a vignette?
-18
man/big_num.Rd
···11-% Generated by roxygen2: do not edit by hand
22-% Please edit documentation in R/big_num.R
33-\name{big_num}
44-\alias{big_num}
55-\title{Infinite precision natural number using a singly linked list}
66-\usage{
77-big_num(num = "")
88-}
99-\arguments{
1010-\item{num}{A string representation of a num.}
1111-}
1212-\description{
1313-TODO: WRITE THIS
1414-1515-The \code{big_num} class is essentially a wrapper around \link{linked_list}
1616-with a custom print method as well as some defined operators such as
1717-\code{+}, \code{*}, and \code{^} with an integer.
1818-}