Skip to content
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

errors concept #284

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions concepts/errors/.meta/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"authors": ["colinleach"],
"contributors": [],
"blurb": "R has a rich but relatively unfamiliar condition handling system."
}
85 changes: 85 additions & 0 deletions concepts/errors/about.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
# About

As explored in the `nothingness` concept, R has various ways to represent data which is absent (`NULL`), unknown (`NA`) or mathematically invalid (`NaN`, `Inf`).
In general, it will try to use these to flag problems in-place, and continue without raising an exception.

## `stop()`

Some problems are too fundamental to let the program continue. In this case, use `stop(msg)` to immediately halt the program with an `Error` and print `msg`.

```R
> f <- function() {
+ stop("I have a problem")
+ }
> f()
Error in f() : I have a problem
```

## `stopifnot()`

Similar to an `assert` in other languages, this is a convenient wrapper for `stop()`.
The parameters are an arbitrary number of boolean conditions, and the program will only continue if they are all `TRUE`.

```R
> stopifnot(1 < 2) # continues OK
> stopifnot(1 < 2, 1 == 2)
Error: 1 == 2 is not TRUE
```

## `try()`

R has a sophisticated variety of ways to handle errors.
These are based on Common Lisp and differ significantly from many popular languages.

The simplest is to wrap potentially problematic code in `try()`

```R
g <- function(val) {
log10(val)
}

> g(3)
[1] 0.4771213

> g("3")
Error in log10(val) : non-numeric argument to mathematical function

# with try() and a default value
h <- function(val) {
result <- NA
try(result <- log10(val))
result
}

> h(3) # works as before
[1] 0.4771213

> h("3") # returns a default value plus the error message
Error in log10(val) : non-numeric argument to mathematical function
[1] NA
```

## `warning()` and `message()`

These are non-fatal conditions, to warn of a problem that the program could at least partly recover from, or inform the user of progress in a long-running program.

One difference between them is that warnings are cached and (by default) output when the function returned, but messages are output immediately.
There are many ways to change the default behavior, beyond our scope here.

```R
w <- function() {
warning("something strange happened")
-1
}

> w()
[1] -1
Warning message:
In w() : something strange happened

# if warnings are not wanted
> suppressWarnings(w())
[1] -1
```

The `suppressWarnings()` function can occasionally be useful within Exercism, to avoid confusing the test runner with unwanted output.
80 changes: 80 additions & 0 deletions concepts/errors/introduction.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
# Introduction

As explored in the `nothingness` concept, R has various ways to represent data which is absent (`NULL`), unknown (`NA`) or mathematically invalid (`NaN`, `Inf`).
In general, it will try to use these to flag problems in-place, and continue without raising an exception.

## `stop()`

Some problems are too fundamental to let the program continue. In this case, use `stop(msg)` to immediately halt the program with an `Error` and print `msg`.

```R
> f <- function() {
+ stop("I have a problem")
+ }
> f()
Error in f() : I have a problem
```

## `stopifnot()`

Similar to an `assert` in other languages, this is a convenient wrapper for `stop()`.
The parameters are an arbitrary number of boolean conditions, and the program will only continue if they are all `TRUE`.

```R
> stopifnot(1 < 2) # continues OK
> stopifnot(1 < 2, 1 == 2)
Error: 1 == 2 is not TRUE
```

## `try()`

R has a sophisticated variety of ways to handle errors.
The simplest is to wrap potentially problematic code in `try()`

```R
g <- function(val) {
log10(val)
}

> g(3)
[1] 0.4771213

> g("3")
Error in log10(val) : non-numeric argument to mathematical function

# with try() and a default value
h <- function(val) {
result <- NA
try(result <- log10(val))
result
}

> h(3) # works as before
[1] 0.4771213

> h("3") # returns a default value plus the error message
Error in log10(val) : non-numeric argument to mathematical function
[1] NA
```

## `warning()` and `message()`

These are non-fatal conditions, to warn of a problem that the program could at least partly recover from, or inform the user of progress in a long-running program.

```R
w <- function() {
warning("something strange happened")
-1
}

> w()
[1] -1
Warning message:
In w() : something strange happened

# if warnings are not wanted
> suppressWarnings(w())
[1] -1
```

The `suppressWarnings()` function can occasionally be useful within Exercism, to avoid confusing the test runner.
6 changes: 6 additions & 0 deletions concepts/errors/links.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[
{
"url": "https://adv-r.hadley.nz/conditions.html",
"description": "Conditions chapter in Advanced R, 2nd Ed"
}
]
5 changes: 5 additions & 0 deletions config.json
Original file line number Diff line number Diff line change
Expand Up @@ -586,6 +586,11 @@
"uuid": "2751b6f2-7d71-4397-b063-9bf927a57756",
"slug": "booleans",
"name": "Booleans"
},
{
"uuid": "f9bc1f9b-aa22-48c3-bc1d-ad2ea75a4d36",
"slug": "errors",
"name": "Errors"
}
],
"key_features": [
Expand Down