From 722207e3302903ecc9f12ca1572a5ab2aa1efcf0 Mon Sep 17 00:00:00 2001 From: colinleach Date: Fri, 21 Jul 2023 15:16:11 -0700 Subject: [PATCH] errors concept --- concepts/errors/.meta/config.json | 5 ++ concepts/errors/about.md | 85 +++++++++++++++++++++++++++++++ concepts/errors/introduction.md | 80 +++++++++++++++++++++++++++++ concepts/errors/links.json | 6 +++ config.json | 5 ++ 5 files changed, 181 insertions(+) create mode 100644 concepts/errors/.meta/config.json create mode 100644 concepts/errors/about.md create mode 100644 concepts/errors/introduction.md create mode 100644 concepts/errors/links.json diff --git a/concepts/errors/.meta/config.json b/concepts/errors/.meta/config.json new file mode 100644 index 00000000..b0b3d766 --- /dev/null +++ b/concepts/errors/.meta/config.json @@ -0,0 +1,5 @@ +{ + "authors": ["colinleach"], + "contributors": [], + "blurb": "R has a rich but relatively unfamiliar condition handling system." +} \ No newline at end of file diff --git a/concepts/errors/about.md b/concepts/errors/about.md new file mode 100644 index 00000000..4e5bf7a4 --- /dev/null +++ b/concepts/errors/about.md @@ -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. diff --git a/concepts/errors/introduction.md b/concepts/errors/introduction.md new file mode 100644 index 00000000..458098ed --- /dev/null +++ b/concepts/errors/introduction.md @@ -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. diff --git a/concepts/errors/links.json b/concepts/errors/links.json new file mode 100644 index 00000000..4455eb89 --- /dev/null +++ b/concepts/errors/links.json @@ -0,0 +1,6 @@ +[ + { + "url": "https://adv-r.hadley.nz/conditions.html", + "description": "Conditions chapter in Advanced R, 2nd Ed" + } +] diff --git a/config.json b/config.json index b51aafcc..92c0e666 100644 --- a/config.json +++ b/config.json @@ -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": [