result

result package for R

https://github.com/soumyaray/result

Science Score: 13.0%

This score indicates how likely this project is to be science-related based on various indicators:

  • CITATION.cff file
  • codemeta.json file
    Found codemeta.json file
  • .zenodo.json file
  • DOI references
  • Academic publication links
  • Academic email domains
  • Institutional organization owner
  • JOSS paper metadata
  • Scientific vocabulary similarity
    Low similarity (12.4%) to scientific vocabulary
Last synced: 6 months ago · JSON representation

Repository

result package for R

Basic Info
  • Host: GitHub
  • Owner: soumyaray
  • License: other
  • Language: R
  • Default Branch: main
  • Size: 54.7 KB
Statistics
  • Stars: 5
  • Watchers: 2
  • Forks: 0
  • Open Issues: 2
  • Releases: 1
Created over 2 years ago · Last pushed over 2 years ago
Metadata Files
Readme Changelog License

README.Rmd

---
output: github_document
---



```{r, include = FALSE}
knitr::opts_chunk$set(
  collapse = TRUE,
  comment = "#>",
  fig.path = "man/figures/README-",
  out.width = "100%"
)
```

# result


[![R-CMD-check](https://github.com/soumyaray/result/actions/workflows/R-CMD-check.yaml/badge.svg)](https://github.com/soumyaray/result/actions/workflows/R-CMD-check.yaml)


The `result` type captures expressions and functions that might cause error or 
otherwise fail to produce a value. Using `result` can make code more readable
and less error-prone by abstracting away the need for nested `if` statements and
`tryCatch` blocks. At its most powerful, `result` can be used to build a
composable pipeline of functions that will either end with a `success` object, 
or stop gracefully with a `failure` object as soon as an error is detected.

## Example

### Safe functions

Make your own functions fault-tolerant by wrapping your results in `success` 
or `failure` for downstream users to safely use:

``` {r, eval = TRUE}
library(result)

# A function that might fail
risky_fn <- function(good = TRUE) {
  if (good) success(42)
  else failure("cannot find good answer")
}

# Downstream users are now encouraged to inspect the result for success
risky_result <- risky_fn(good = TRUE)
if (is_success(risky_result)) {
  print(paste0("The answer: ", value(risky_result)))
}

risky_result <- risky_fn(good = FALSE)
if (is_failure(risky_result)) {
  cat(paste0("Failed because ", value(risky_result)))
}
```


### Smart Results

If you are using others' functions, wrap their results safely for immediate
inspection, or wrap the whole function for safe use later:

``` {r, eval = TRUE}
# A third-party function that might crash with error
external_api <- function(good = TRUE) {
  if (good) 42
  else stop("Cannot connect to API")
}

# We can either safely inspect the results:
api_result <- as_result(external_api(good = TRUE))
is_success(api_result)
value(api_result)

# Or we can wrap the risky function for safe use later!
safely_call_api <- result(external_api)
safely_call_api(good = FALSE) |> is_failure()
```

### Pipelines

We can chain together functions to create a pipeline that will either complete
successfully or else stop gracefully at the first sign of failure.

Operations for our pipeline:
``` {r, eval = TRUE}
# Start by wrapping the first operation in a result to evaluate later
safely_call_api <- result(external_api)

# Other (risky) operations we want to safely use
add_some <- function(x, y) x + y
times_some <- function(x, y) x * y
times_too_much <- function(x, y) {
  z <- x * y
  if (z > 100) stop("Result has become too big") else z
}
```

A successful pipeline binding `result` operations together:

``` {r, eval = TRUE}
process <-
  safely_call_api(good = TRUE) |>
  then_try(times_some, 2) |>
  then_try(add_some, 10)

if (is_success(process)) {
  print(paste0("Processed: ", value(process)))
} else {
  cat(paste0("Could not process: ", value(process)))
}
```

A failing pipeline that should fail gracefully at the second step (`times_too_much`):

``` {r, eval = TRUE}
process <-
  safely_call_api(good = TRUE) |>
  then_try(times_too_much, 50) |>
  then_try(add_some, 10)

if (is_success(process)) {
  print(paste0("Processed: ", value(process)))
} else {
  cat(paste0("Could not process: ", value(process)))
}
```

## Installation

You can install the released version of result from CRAN:
``` r
install.packages("result")
```

You can install the development version of result from 
[GitHub](https://github.com/soumyaray/result) with:

``` r
# install.packages("devtools")
devtools::install_github("soumyaray/result")
```

## Why not Either or Maybe?

`Result` is a generalization of the **`Maybe`** type that is available to R devs from
the [`maybe`](https://github.com/armcn/maybe) package. Conversely, the `Maybe` type 
is a special case of the `Result` type where the error type is `Nothing`. `Maybe` 
shines in situations when an operation might return something or nothing.
But `Result` can convey more information than `Maybe` in error situations 
(e.g., a status code or message explaining the error). In this R implementation,
the `result()` and `as_result()` functions also capture errors automatically, 
sparing developers from having to wrap expressions in their own `tryCatch` blocks.

The `Result` type is a special case of the **`Either`** type. 
Whereas `Either` resolves to `Left` or `Right`, `Result` usually resolves to 
notions of "Ok' or "Error". Use of `Left` and `Right` can be confusing to 
newcomers to functional concepts, and do not express the relevance of outcomes. 
In this R implementation of `Result`, the `result()` and `as_result()` functions
resolve to `success` and `failure` respectively, which should be intuitive to 
many developers. Implementations of `Result` in other languages (such as Rust)
sometimes use `ok` and `error` (or `err`), but these can conflict with 
variable names and keywords in other languages.

Owner

  • Name: Soumya Ray
  • Login: soumyaray
  • Kind: user
  • Location: Hsinchu, Taiwan
  • Company: Institute of Service Science, National Tsing Hua University

Researcher, Teacher, Coder

GitHub Events

Total
  • Watch event: 1
Last Year
  • Watch event: 1

Packages

  • Total packages: 1
  • Total downloads:
    • cran 386 last-month
  • Total dependent packages: 0
  • Total dependent repositories: 0
  • Total versions: 1
  • Total maintainers: 1
cran.r-project.org: result

Result Type for Safely Handling Operations that can Succeed or Fail

  • Versions: 1
  • Dependent Packages: 0
  • Dependent Repositories: 0
  • Downloads: 386 Last month
Rankings
Dependent packages count: 28.7%
Dependent repos count: 36.8%
Average: 50.5%
Downloads: 86.0%
Maintainers (1)
Last synced: 7 months ago

Dependencies

DESCRIPTION cran
  • testthat >= 3.0.0 suggests