Skip to content

Commit aa23547

Browse files
author
maechler
committed
add %||% to base
git-svn-id: https://svn.r-project.org/R/trunk@85410 00db46b3-68df-0310-9c12-caf00c1e9a41
1 parent c6a34a8 commit aa23547

File tree

8 files changed

+37
-15
lines changed

8 files changed

+37
-15
lines changed

doc/NEWS.Rd

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,11 @@
197197

198198
\item New option \code{catch.script.errors} provides a documented way
199199
to catch errors and continue in non-interactive use.
200+
201+
\item \code{L \%||\% R} newly in base is an expressive idiom for the
202+
\code{if(!is.null(L)) L else R} or \code{if(is.null(L)) R else L}
203+
phrases.
204+
200205
}
201206
}
202207

src/library/base/R/utils.R

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# File src/library/base/R/utils.R
22
# Part of the R package, https://www.R-project.org
33
#
4-
# Copyright (C) 1995-2021 The R Core Team
4+
# Copyright (C) 1995-2023 The R Core Team
55
#
66
# This program is free software; you can redistribute it and/or modify
77
# it under the terms of the GNU General Public License as published by
@@ -16,6 +16,9 @@
1616
# A copy of the GNU General Public License is available at
1717
# https://www.R-project.org/Licenses/
1818

19+
## A pearl from Ruby -> ggplot2 et al.
20+
`%||%` <- function(x, y) if(is.null(x)) y else x
21+
1922
shQuote <- function(string, type = c("sh", "csh", "cmd", "cmd2"))
2023
{
2124
if(missing(type) && .Platform$OS.type == "windows") type <- "cmd"

src/library/base/man/Control.Rd

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
% File src/library/base/man/Control.Rd
22
% Part of the R package, https://www.R-project.org
3-
% Copyright 1995-2022 R Core Team
3+
% Copyright 1995-2023 R Core Team
44
% Distributed under GPL 2 or later
55

66
\name{Control}
7+
\title{Control Flow}
78
\alias{Control}
89
\alias{if}
910
\alias{else}
@@ -13,7 +14,7 @@
1314
\alias{repeat}
1415
\alias{break}
1516
\alias{next}
16-
\title{Control Flow}
17+
\alias{\%||\%}
1718
\description{
1819
These are the basic control-flow constructs of the \R language. They
1920
function in much the same way as control statements in any Algol-like
@@ -28,18 +29,20 @@ while(cond) expr
2829
repeat expr
2930
break
3031
next
32+
33+
x \%||\% y
3134
}
3235
\arguments{
3336
\item{cond}{A length-one logical vector that is not \code{NA}.
3437
Other types are coerced to logical if possible, ignoring any class.
35-
(Conditions of length greater than one are an error.)
38+
(Conditions of length greater than one are an error.)
3639
}
3740
\item{var}{A syntactical name for a variable.}
3841
\item{seq}{An expression evaluating to a vector (including a list and
3942
an \link{expression}) or to a \link{pairlist} or \code{NULL}. A
4043
factor value will be coerced to a character vector. This can be a
4144
long vector.}
42-
\item{expr, cons.expr, alt.expr}{
45+
\item{expr, cons.expr, alt.expr, x, y}{
4346
An \emph{expression} in a formal sense. This is either a
4447
simple expression or a so-called \emph{compound expression}, usually
4548
of the form \code{\{ expr1 ; expr2 \}}.
@@ -68,6 +71,12 @@ next
6871
but this will not affect the next iteration. When the loop terminates,
6972
\code{var} remains as a variable containing its latest value.
7073

74+
\code{x \%||\% y} is a simple 1-line function, an idiomatic way to call
75+
\preformatted{
76+
if (is.null(x)) y else x
77+
# or equivalently, of course,
78+
if(!is.null(x)) x else y }
79+
Inspired by Ruby, it was first proposed by Hadley Wickham.
7180
}
7281
\value{
7382
\code{if} returns the value of the expression evaluated, or
@@ -101,6 +110,13 @@ for(n in c(2,5,10,20,50)) {
101110
}
102111
f <- factor(sample(letters[1:5], 10, replace = TRUE))
103112
for(i in unique(f)) print(i)
113+
114+
res <- {}
115+
res \%||\% "alternative result"
116+
x <- head(x) \%||\% stop("parsed, but *not* evaluated..")
117+
118+
res <- if(sum(x) > 7.5) mean(x) # may be NULL
119+
res \%||\% "sum(x) <= 7.5"
104120
}
105121
\keyword{programming}
106122
\keyword{iteration}

src/library/base/man/Logic.Rd

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,9 @@ isFALSE(x)
124124

125125
\code{\link{Syntax}} for operator precedence.
126126

127+
\code{L \link{\%||\%} R } which takes \code{L} if it is not \code{NULL},
128+
and \code{R} otherwise.
129+
127130
\code{\link{bitwAnd}} for bitwise versions for integer vectors.
128131
}
129132
\examples{

src/library/base/man/NULL.Rd

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
% File src/library/base/man/NULL.Rd
22
% Part of the R package, https://www.R-project.org
3-
% Copyright 1995-2022 R Core Team
3+
% Copyright 1995-2023 R Core Team
44
% Distributed under GPL 2 or later
55

66
\name{NULL}
@@ -53,6 +53,9 @@ is.null(x)
5353
\code{is.null} returns \code{TRUE} if its argument's value
5454
is \code{NULL} and \code{FALSE} otherwise.
5555
}
56+
\seealso{
57+
\code{\link{\%||\%}}: \code{L \%||\% R} is equivalent to \code{ if(!is.null(L)) L else R }
58+
}
5659
\examples{
5760
is.null(list()) # FALSE (on purpose!)
5861
is.null(pairlist()) # TRUE

src/library/grDevices/R/device.R

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,6 @@ deviceIsInteractive <- local({
4949
})
5050

5151

52-
`%||%` <- function(L,R) if(is.null(L)) R else L
53-
5452
dev.list <- function()
5553
{
5654
n <- get0(".Devices") %||% list("null device")

src/library/stats/R/AIC.R

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,6 @@
1616
# A copy of the GNU General Public License is available at
1717
# https://www.R-project.org/Licenses/
1818

19-
## A pearl from ggplot2 et al. NB: often needs '(..)' around RHS : <lhs> %||% ( <rhs> )
20-
`%||%` <- function(L,R) if(is.null(L)) R else L
21-
2219

2320
#### Return the value of Akaike's Information Criterion
2421
### originally from package nlne.

src/library/utils/R/str.R

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# File src/library/utils/R/str.R
22
# Part of the R package, https://www.R-project.org
33
#
4-
# Copyright (C) 1995-2021 The R Core Team
4+
# Copyright (C) 1995-2023 The R Core Team
55
#
66
# This program is free software; you can redistribute it and/or modify
77
# it under the terms of the GNU General Public License as published by
@@ -16,9 +16,6 @@
1616
# A copy of the GNU General Public License is available at
1717
# https://www.R-project.org/Licenses/
1818

19-
## A pearl from ggplot2 et al. NB: often needs '(.)' : <lhs> %||% ( <rhs> )
20-
## *not exported* [should rather be in 'base' than exported here]
21-
`%||%` <- function(L,R) if(is.null(L)) R else L
2219

2320
####------ str : show STRucture of an R object
2421
str <- function(object, ...) UseMethod("str")

0 commit comments

Comments
 (0)