pkgsrc-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[pkgsrc/trunk]: pkgsrc/devel/R-rlang Update to 0.3.1

branches:  trunk
changeset: 318659:829baa23941a
user:      wen <>
date:      Sun Jan 27 14:59:18 2019 +0000

Update to 0.3.1

Upstream changes:
rlang 0.3.1

This patch release polishes the new backtrace feature introduced in rlang 0.3.0 and solves bugs for the upcoming release of purrr 0.3.0. It also features as_label() and as_name() which are meant to 
replace quo_name() in the future. Finally, a bunch of deparsing issues have been fixed.
Backtrace fixes

    New entrace() condition handler. Add this to your RProfile to enable rlang backtraces for all errors, including warnings promoted to errors:

    if (requireNamespace("rlang", quietly = TRUE)) {
      options(error = rlang::entrace)

    This handler also works as a calling handler:

      error = calling(entrace),

    However it?s often more practical to use with_abort() in that case:


    with_abort() gains a classes argument to promote any kind of condition to an rlang error.

    New last_trace() shortcut to print the backtrace stored in the last_error().

    Backtrace objects now print in full by default.

    Calls in backtraces are now numbered according to their position in the call tree. The numbering is non-contiguous for simplified backtraces because of omitted call frames.

    catch_cnd() gains a classes argument to specify which classes of condition to catch. It returns NULL if the expected condition could not be caught (#696).

as_label() and as_name()

The new as_label() and as_name() functions should be used instead of quo_name() to transform objects and quoted expressions to a string. We have noticed that tidy eval users often use quo_name() to 
extract names from quosured symbols. This is not a good use for that function because the way quo_name() creates a string is not a well defined operation.

For this reason, we are replacing quo_name() with two new functions that have more clearly defined purposes, and hopefully better names reflecting those purposes. Use as_label() to transform any 
object to a short human-readable description, and as_name() to extract names from (possibly quosured) symbols.

Create labels with as_label() to:

    Display an object in a concise way, for example to labellise axes in a graphical plot.

    Give default names to columns in a data frame. In this case, labelling is the first step before name repair.

We expect as_label() to gain additional parameters in the future, for example to control the maximum width of a label. The way an object is labelled is thus subject to change.

On the other hand, as_name() transforms symbols back to a string in a well defined manner. Unlike as_label(), as_name() guarantees the roundtrip symbol -> string -> symbol.

In general, if you don?t know for sure what kind of object you?re dealing with (a call, a symbol, an unquoted constant), use as_label() and make no assumption about the resulting string. If you know 
you have a symbol and need the name of the object it refers to, use as_name(). For instance, use as_label() with objects captured with enquo() and as_name() with symbols captured with ensym().

Note that quo_name() will only be soft-deprecated at the next major version of rlang (0.4.0). At this point, it will start issuing once-per-session warnings in scripts, but not in packages. It will 
then be deprecated in yet another major version, at which point it will issue once-per-session warnings in packages as well. You thus have plenty of time to change your code.
Minor fixes and features

    New is_interactive() function. It serves the same purpose as base::interactive() but also checks if knitr is in progress and provides an escape hatch. Use with_interactive() and 
scoped_interactive() to override the return value of is_interactive(). This is useful in unit tests or to manually turn on interactive features in RMarkdown outputs

    calling() now boxes its argument.

    New done() function to box a value. Done boxes are sentinels to indicate early termination of a loop or computation. For instance, it will be used in the purrr package to allow users to 
shortcircuit a reduction or accumulation.

    new_box() now accepts additional attributes passed to structure().

    as_string() now unwraps quosured symbols automatically.

    Note that quo_name() is not appropriate for transforming symbols to strings. quo_name() is suitable for creating default labels, not for deterministic conversions between symbol and string. 
Please use as_string() instead.

    Fixed a quotation bug with binary operators of zero or one argument such as `/`(1) (#652). They are now deparsed and printed properly as well.

    New call_ns() function to retrieve the namespace of a call. Returns NULL if the call is not namespaced.

    Top-level S3 objects are now deparsed properly.

    Empty { blocks are now deparsed on the same line.

    Fixed a deparsing issue with symbols containing non-ASCII characters (#691).

    expr_print() now handles [ and [[ operators correctly, and deparses non-syntactic symbols with backticks.

    call_modify() now respects ordering of unnamed inputs. Before this fix, it would move all unnamed inputs after named ones.

    as_closure() wrappers now call primitives with positional arguments to avoid edge case issues of argument matching.

    as_closure() wrappers now dispatch properly on methods defined in the global environment (tidyverse/purrr#459).

    as_closure() now supports both base-style (e1 and e2) and purrr-style (.x and .y) arguments with binary primitives.

    exec() takes .fn as first argument instead of f, for consistency with other rlang functions.

    Fixed infinite loop with quosures created inside a data mask.

    Base errors set as parent of rlang errors are now printed correctly.

rlang 0.3.0
Breaking changes

The rlang API is still maturing. In this section, you?ll find hard breaking changes. See the life cycle section below for an exhaustive list of API changes.

    quo_text() now deparses non-syntactic symbols with backticks:

    #> [1] "`foo+`"

    This caused a number of issues in reverse dependencies as quo_text() tends to be used for converting symbols to strings. quo_text() and quo_name() should not be used for this purpose because they 
are general purpose deparsers. These functions should generally only be used for printing outputs or creating default labels. If you need to convert symbols to strings, please use as_string() rather 
than quo_text().

    We have extended the documentation of ?quo_text and ?quo_name to make these points clearer.

    exprs() no longer flattens quosures. exprs(!!!quos(x, y)) is now equivalent to quos(x, y).

    The sentinel for removing arguments in call_modify() has been changed from NULL to zap(). This breaking change is motivated by the ambiguity of NULL with valid argument values.

    call_modify(call, arg = NULL)  # Add `arg = NULL` to the call
    call_modify(call, arg = zap()) # Remove the `arg` argument from the call

    The %@% operator now quotes its input and supports S4 objects. This makes it directly equivalent to @ except that it extracts attributes for non-S4 objects (#207).

    Taking the env_parent() of the empty environment is now an error.


The changes for this version are organised around three main themes: error reporting, tidy eval, and tidy dots.

    abort() now records backtraces automatically in the error object. Errors thrown with abort() invite users to call rlang::last_error() to see a backtrace and help identifying where and why the 
error occurred. The backtraces created by rlang (you can create one manually with trace_back()) are printed in a simplified form by default that removes implementation details from the backtrace. To 
see the full backtrace, call summary(rlang::last_error()).

    abort() also gains a parent argument. This is meant for situations where you?re calling a low level API (to download a file, parse a JSON file, etc) and would like to intercept errors with 
base::tryCatch() or rlang::with_handlers() and rethrow them with a high-level message. Call abort() with the intercepted error as the parent argument. When the user prints rlang::last_error(), the 
backtrace will be shown in two sections corresponding to the high-level and low-level contexts.

    In order to get segmented backtraces, the low-level error has to be thrown with abort(). When that?s not the case, you can call the low-level function within with_abort() to automatically promote 
all errors to rlang errors.

    The tidy eval changes are mostly for developers of data masking APIs. The main user-facing change is that .data[[ is now an unquote operator so that var in .data[[var]] is never masked by data 
frame columns and always picked from the environment. This makes the pronoun safe for programming in functions.

    The !!! operator now supports all classed objects like factors. It calls as.list() on S3 objects and as(x, "list") on S4 objects.

    dots_list() gains several arguments to control how dots are collected. You can control the selection of arguments with the same name with .homonyms (keep first, last, all, or abort). You can also 
elect to preserve empty arguments with .preserve_empty.

Conditions and errors

    New trace_back() captures a backtrace. Compared to the base R traceback, it contains additional structure about the relationship between frames. It comes with tools for automatically restricting 
to frames after a certain environment on the stack, and to simplify when printing. These backtraces are now recorded in errors thrown by abort() (see below).

    abort() gains a parent argument to specify a parent error. This is meant for situations where a low-level error is expected (e.g. download or parsing failed) and you?d like to throw an error with 
higher level information. Specifying the low-level error as parent makes it possible to partition the backtraces based on ancestry.

    Errors thrown with abort() now embed a backtrace in the condition object. It is no longer necessary to record a trace with a calling handler for such errors.

    with_abort() runs expressions in a context where all errors are promoted to rlang errors and gain a backtrace.

    Unhandled errors thrown by abort() are now automatically saved and can be retrieved with rlang::last_error(). The error prints with a simplified backtrace. Call summary(last_error()) to see the 
full backtrace.

    New experimental option rlang__backtrace_on_error to display backtraces alongside error messages. See ?rlang::abort for supported options.

    The new signal() function completes the abort(), warn() and inform() family. It creates and signals a bare condition.

    New interrupt() function to simulate an user interrupt from R code.

    cnd_signal() now dispatches messages, warnings, errors and interrupts to the relevant signalling functions (message(), warning(), stop() and the C function Rf_onintr()). This makes it a good 
choice to resignal a captured condition.

    New cnd_type() helper to determine the type of a condition ("condition", "message", "warning", "error" or "interrupt").

    abort(), warn() and inform() now accepts metadata with .... The data are stored in the condition and can be examined by user handlers.

    Consequently all arguments have been renamed and prefixed with a dot (to limit naming conflicts between arguments and metadata names).

    with_handlers() treats bare functions as exiting handlers (equivalent to handlers supplied to tryCatch()). It also supports the formula shortcut for lambda functions (as in purrr).

    with_handlers() now produces a cleaner stack trace.

Tidy dots

    The input types of !!! have been standardised. !!! is generally defined on vectors: it takes a vector (typically, a list) and unquotes each element as a separate argument. The standardisation 
makes !!! behave the same in functions taking dots with list2() and in quoting functions. !!! accepts these types:

        Lists, pairlists, and atomic vectors. If they have a class, they are converted with base::as.list() to allow S3 dispatch. Following this change, objects like factors can now be spliced 
without data loss.

        S4 objects. These are converted with as(obj, "list") before splicing.

        Quoted blocks of expressions, i.e. { } calls

    !!! disallows:
        Any other objects like functions or environments, but also language objects like formula, symbols, or quosures.

    Quoting functions used to automatically wrap language objects in lists to make them spliceable. This behaviour is now soft-deprecated and it is no longer valid to write !!!enquo(x). Please 
unquote scalar objects with !! instead.

    dots_list(), enexprs() and enquos() gain a .homonyms argument to control how to treat arguments with the same name. The default is to keep them. Set it to "first" or "last" to keep only the first 
or last occurrences. Set it to "error" to raise an informative error about the arguments with duplicated names.

    enexprs() and enquos() now support .ignore_empty = "all" with named arguments as well (#414).

    dots_list() gains a .preserve_empty argument. When TRUE, empty arguments are stored as missing arguments (see ?missing_arg).

    dots_list(), enexprs() and enquos() gain a .check_assign argument. When TRUE, a warning is issued when a <- call is detected in .... No warning is issued if the assignment is wrapped in brackets 
like { a <- 1 }. The warning lets users know about a possible typo in their code (assigning instead of matching a function parameter) and requires them to be explicit that they really want to assign 
to a variable by wrapping in parentheses.

    lapply(list(quote(foo)), list2) no longer evaluates foo (#580).

Tidy eval

    You can now unquote quosured symbols as LHS of :=. The symbol is automatically unwrapped from the quosure.

    Quosure methods have been defined for common operations like ==. These methods fail with an informative error message suggesting to unquote the quosure (#478, #tidyverse/dplyr#3476).

    as_data_pronoun() now accepts data masks. If the mask has multiple environments, all of these are looked up when subsetting the pronoun. Function objects stored in the mask are bypassed.

    It is now possible to unquote strings in function position. This is consistent with how the R parser coerces strings to symbols. These two expressions are now equivalent: expr("foo"()) and 

    Quosures converted to functions with as_function() now support nested quosures.

    expr_deparse() (used to print quosures at the console) now escapes special characters. For instance, newlines now print as "\n" (#484). This ensures that the roundtrip parse_expr(expr_deparse(x)) 
is not lossy.

    new_data_mask() now throws an error when bottom is not a child of top (#551).

    Formulas are now evaluated in the correct environment within eval_tidy(). This fixes issues in dplyr and other tidy-evaluation interfaces.

    New functions new_quosures() and as_quosures() to create or coerce to a list of quosures. This is a small S3 class that ensures two invariants on subsetting and concatenation: that each element 
is a quosure and that the list is always named even if only with a vector of empty strings.


    env() now treats a single unnamed argument as the parent of the new environment. Consequently, child_env() is now superfluous and is now in questioning life cycle.

    New current_env() and current_fn() functions to retrieve the current environment or the function being evaluated. They are equivalent to base::environment() and base::sys.function() called 
without argument.

    env_get() and env_get_list() gain a default argument to provide a default value for non-existing bindings.

    env_poke() now returns the old value invisibly rather than the input environment.

    The new function env_name() returns the name of an environment. It always adds the ?namespace:? prefix to namespace names. It returns ?global? instead of ?.GlobalEnv? or ?R_GlobalEnv?, ?empty? 
instead of ?R_EmptyEnv?. The companion env_label() is like env_name() but returns the memory address for anonymous environments.

    env_parents() now returns a named list. The names are taken with env_name().

    env_parents() and env_tail() now stop at the global environment by default. This can be changed with the last argument. The empty environment is always a stopping condition so you can take the 
parents or the tail of an environment on the search path without changing the default.

    New predicates env_binding_are_active() and env_binding_are_lazy() detect the kind of bindings in an environment.

    env_binding_lock() and env_binding_unlock() allows to lock and unlock multiple bindings. The predicate env_binding_are_locked() tests if bindings are locked.

    env_lock() and env_is_locked() lock an environment or test if an environment is locked.

    env_print() pretty-prints environments. It shows the contents (up to 20 elements) and the properties of the environment.

    is_scoped() has been soft-deprecated and renamed to is_attached(). It now supports environments in addition to search names.

    env_bind_lazy() and env_bind_active() now support quosures.

    env_bind_exprs() and env_bind_fns() are soft-deprecated and renamed to env_bind_lazy() and env_bind_active() for clarity and consistency.

    env_bind(), env_bind_exprs(), and env_bind_fns() now return the list of old binding values (or missing arguments when there is no old value). This makes it easy to restore the original 
environment state:

    old <- env_bind(env, foo = "foo", bar = "bar")
    env_bind(env, !!!old)

    env_bind() now supports binding missing arguments and removing bindings with zap sentinels. env_bind(env, foo = ) binds a missing argument and env_bind(env, foo = zap()) removes the foo binding.

    The inherit argument of env_get() and env_get_list() has changed position. It now comes after default.

    scoped_bindings() and with_bindings() can now be called without bindings.

    env_clone() now recreates active bindings correctly.

    env_get() now evaluates promises and active bindings since these are internal objects which should not be exposed at the R level (#554)

    env_print() calls get_env() on its argument, making it easier to see the environment of closures and quosures (#567).

    env_get() now supports retrieving missing arguments when inherit is FALSE.


    is_call() now accepts multiple namespaces. For instance is_call(x, "list", ns = c("", "base")) will match if x is list() or if it?s base::list():

    call_modify() has better support for ... and now treats it like a named argument. call_modify(call, ... = ) adds ... to the call and call_modify(call, ... = NULL) removes it.

    call_modify() now preserves empty arguments. It is no longer necessary to use missing_arg() to add a missing argument to a call. This is possible thanks to the new .preserve_empty option of 

    call_modify() now supports removing unexisting arguments (#393) and passing multiple arguments with the same name (#398). The new .homonyms argument controls how to treat these arguments.

    call_standardise() now handles primitive functions like ~ properly (#473).

    call_print_type() indicates how a call is deparsed and printed at the console by R: prefix, infix, and special form.

    The call_ functions such as call_modify() now correctly check that their input is the right type (#187).

Other improvements and fixes

    New function zap() returns a sentinel that instructs functions like env_bind() or call_modify() that objects are to be removed.

    New function rep_named() repeats value along a character vector of names.

    New function exec() is a simpler replacement to invoke() (#536). invoke() has been soft-deprecated.

    Lambda functions created from formulas with as_function() are now classed. Use is_lambda() to check a function was created with the formula shorthand.

    is_integerish() now supports large double values (#578).

    are_na() now requires atomic vectors (#558).

    The operator %@% has now a replacement version to update attributes of an object (#207).

    fn_body() always returns a { block, even if the function has a single expression. For instance fn_body(function(x) do()) returns quote({ do() }).

    is_string() now returns FALSE for NA_character_.

    The vector predicates have been rewritten in C for performance.

    The finite argument of is_integerish() is now NULL by default. Missing values are now considered as non-finite for consistency with base::is.finite().

    is_bare_integerish() and is_scalar_integerish() gain a finite argument for consistency with is_integerish().

    flatten_if() and squash_if() now handle primitive functions like base::is.list() as predicates.

    is_symbol() now accepts a character vector of names to mach the symbol against.

    parse_exprs() and parse_quos() now support character vectors. Note that the output may be longer than the input as each string may yield multiple expressions (such as "foo; bar").

    parse_quos() now adds the quosures class to its output.

Soft-deprecated functions and arguments

rlang 0.3.0 introduces a new warning mechanism for soft-deprecated functions and arguments. A warning is issued, but only under one of these circumstances:

    rlang has been attached with a library() call.
    The deprecated function has been called from the global environment.

In addition, deprecation warnings appear only once per session in order to not be disruptive.

Deprecation warnings shouldn?t make R CMD check fail for packages using testthat. However, expect_silent() can transform the warning to a hard failure.

    .data[[foo]] is now an unquote operator. This guarantees that foo is evaluated in the context rather than the data mask and makes it easier to treat .data[["bar"]] the same way as a symbol. For 
instance, this will help ensuring that group_by(df, .data[["name"]]) and group_by(df, name) produce the same column name.

    Automatic naming of expressions now uses a new deparser (still unexported) instead of quo_text(). Following this change, automatic naming is now compatible with all object types (via 
pillar::type_sum() if available), prevents multi-line names, and ensures name and .data[["name"]] are given the same default name.

    Supplying a name with !!! calls is soft-deprecated. This name is ignored because only the names of the spliced vector are applied.

    Quosure lists returned by quos() and enquos() now have ?list-of? behaviour: the types of new elements are checked when adding objects to the list. Consequently, assigning non-quosure objects to 
quosure lists is now soft-deprecated. Please coerce to a bare list with as.list() beforehand.

    as_quosure() now requires an explicit environment for symbols and calls. This should typically be the environment in which the expression was created.

    names() and length() methods for data pronouns are deprecated. It is no longer valid to write names(.data) or length(.data).

    Using as.character() on quosures is soft-deprecated (#523).


    Using get_env() without supplying an environment is now soft-deprecated. Please use current_env() to retrieve the current environment.

    The frame and stack API is soft-deprecated. Some of the functionality has been replaced by trace_back().

    The new_vector_along() family is soft-deprecated because these functions are longer to type than the equivalent rep_along() or rep_named() calls without added clarity.

    Passing environment wrappers like formulas or functions to env_ functions is now soft-deprecated. This internal genericity was causing confusion (see issue #427). You should now extract the 
environment separately before calling these functions.

    This change concerns env_depth(), env_poke_parent(), env_parent<-, env_tail(), set_env(), env_clone(), env_inherits(), env_bind(), scoped_bindings(), with_bindings(), env_poke(), env_has(), 
env_get(), env_names(), env_bind_exprs() and env_bind_fns().

    cnd_signal() now always installs a muffling restart for non-critical conditions. Consequently the .mufflable argument has been soft-deprecated and no longer has any effect.

Deprecated functions and arguments

Deprecated functions and arguments issue a warning inconditionally, but only once per session.

    Calling UQ() and UQS() with the rlang namespace qualifier is deprecated as of rlang 0.3.0. Just use the unqualified forms instead:

    # Bad
    rlang::expr(mean(rlang::UQ(var) * 100))

    # Ok
    rlang::expr(mean(UQ(var) * 100))

    # Good
    rlang::expr(mean(!!var * 100))

    Although soft-deprecated since rlang 0.2.0, UQ() and UQS() can still be used for now.

    The call argument of abort() and condition constructors is now deprecated in favour of storing full backtraces.

    The .standardise argument of call_modify() is deprecated. Please use call_standardise() beforehand.

    The sentinel argument of env_tail() has been deprecated and renamed to last.

Defunct functions and arguments

Defunct functions and arguments throw an error when used.

    as_dictionary() is now defunct.

    The experimental function rst_muffle() is now defunct. Please use cnd_muffle() instead. Unlike its predecessor, cnd_muffle() is not generic. It is marked as a calling handler and thus can be 
passed directly to with_handlers() to muffle specific conditions (such as specific subclasses of warnings).

    cnd_inform(), cnd_warn() and cnd_abort() are retired and defunct. The old cnd_message(), cnd_warning(), cnd_error() and new_cnd() constructors deprecated in rlang 0.2.0 are now defunct.

    Modifying a condition with cnd_signal() is defunct. In addition, creating a condition with cnd_signal() is soft-deprecated, please use the new function [signal()] instead.

    inplace() has been renamed to calling() to follow base R terminology more closely.

Functions and arguments in the questioning stage

We are no longer convinced these functions are the right approach but we do not have a precise alternative yet.

    The functions from the restart API are now in the questioning lifecycle stage. It is not clear yet whether we want to recommend restarts as a style of programming in R.

    prepend() and modify() are in the questioning stage, as well as as_logical(), as_character(), etc. We are still figuring out what vector tools belong in rlang.

    flatten(), squash() and their atomic variants are now in the questioning lifecycle stage. They have slightly different semantics than the flattening functions in purrr and we are currently 
rethinking our approach to flattening with the new typing facilities of the vctrs package.

rlang 0.2.2

This is a maintenance release that fixes several garbage collection protection issues.


 devel/R-rlang/Makefile |   4 ++--
 devel/R-rlang/distinfo |  10 +++++-----
 2 files changed, 7 insertions(+), 7 deletions(-)

diffs (33 lines):

diff -r e210c26f6a5f -r 829baa23941a devel/R-rlang/Makefile
--- a/devel/R-rlang/Makefile    Sun Jan 27 14:50:34 2019 +0000
+++ b/devel/R-rlang/Makefile    Sun Jan 27 14:59:18 2019 +0000
@@ -1,4 +1,4 @@
-# $NetBSD: Makefile,v 1.3 2018/07/28 14:40:43 brook Exp $
+# $NetBSD: Makefile,v 1.4 2019/01/27 14:59:18 wen Exp $
 CATEGORIES=    devel
@@ -8,7 +8,7 @@
 LICENSE=       gnu-gpl-v3
 R_PKGNAME=     rlang
-R_PKGVER=      0.2.1
+R_PKGVER=      0.3.1
diff -r e210c26f6a5f -r 829baa23941a devel/R-rlang/distinfo
--- a/devel/R-rlang/distinfo    Sun Jan 27 14:50:34 2019 +0000
+++ b/devel/R-rlang/distinfo    Sun Jan 27 14:59:18 2019 +0000
@@ -1,6 +1,6 @@
-$NetBSD: distinfo,v 1.2 2018/06/01 02:08:10 wen Exp $
+$NetBSD: distinfo,v 1.3 2019/01/27 14:59:18 wen Exp $
-SHA1 (R/rlang_0.2.1.tar.gz) = 9a34dce3f6c1643f69906087a3085353074025f4
-RMD160 (R/rlang_0.2.1.tar.gz) = d26b53fae0cf2d025b9dd95e0639309554928e87
-SHA512 (R/rlang_0.2.1.tar.gz) = ae03d86426d1ef8abfa7f74249036b8a81e1e28b09018f7b8a6b244418697e6723f2e2b3ca1abc3bbd9354c1de9aaa8cf0423291754901573fb73bd6f777b7d1
-Size (R/rlang_0.2.1.tar.gz) = 325006 bytes
+SHA1 (R/rlang_0.3.1.tar.gz) = fdc160a4c605ffa2168f22152fa0d11d025674f5
+RMD160 (R/rlang_0.3.1.tar.gz) = 3932b55c81a8f362b67f31923853f7bfa833ed86
+SHA512 (R/rlang_0.3.1.tar.gz) = 0ac7063bd8e52dafb54dee7828f8f9025b1eff4c5baee3b78c7abc9432ae12748e91dd2611d612e13697e5d5a9dae49d96897636bacf0156153487309db7d769
+Size (R/rlang_0.3.1.tar.gz) = 857682 bytes

Home | Main Index | Thread Index | Old Index