Coder Social home page Coder Social logo

strict's Introduction

strict

Travis-CI Build Status CRAN_Status_Badge Coverage Status

The goal of strict to make R behave a little more strictly, making base functions more likely to throw an error rather than returning potentially ambiguous results.

library(strict) forces you to confront potential problems now, instead of in the future. This has both pros and cons: often you can most easily fix a potential ambiguity when you're working on the code (rather than in six months time when you've forgotten how it works), but it also forces you to resolve ambiguities that might never occur with your code/data.

Installation

# install.packages("devtools")
devtools::install_github("hadley/strict")

Features

library(strict) affects code in the current script/session only (i.e. it doesn't affect code in others packages).

  • An alternative conflict resolution mechanism. Instead of warning about conflicts on package load and letting the last loaded package win, strict throws an error when you access ambiguous functions:

    library(strict)
    library(plyr)
    library(Hmisc)
    #> Loading required package: lattice
    #> Loading required package: survival
    #> Loading required package: Formula
    #> Loading required package: ggplot2
    
    is.discrete
    #> Error: [strict]
    #> Multiple definitions found for `is.discrete`.
    #> Please pick one:
    #>  * Hmisc::is.discrete
    #>  * plyr::is.discrete

    (Thanks to @krlmlr for this neat idea!)

  • Shims for functions with "risky" arguments, i.e. arguments that either rely on global options (like stringsAsFactors) or have computed defaults that 90% evaluate to one thing (like drop). strict forces you to supply values for these arguments.

    library(strict)
    mtcars[, 1]
    #> Error: [strict]
    #> Please explicitly specify `drop` when selecting a single column
    #> Please see ?strict_drop for more details
    
    data.frame(x = "a")
    #> Error: [strict]
    #> Please supply a value for `stringsAsFactors` argument.
    #> Please see ?strict_arg for more details
  • Automatically sets options to warn when partial matching occurs.

    library(strict)
    
    df <- data.frame(xyz = 1)
    df$x
    #> Warning in `$.data.frame`(df, x): Partial match of 'x' to 'xyz' in data
    #> frame
    #> [1] 1
  • T and F generate errors, forcing you to use TRUE and FALSE.

    library(strict)
    T
    #> Error: [strict]
    #> Please use TRUE, not T
  • sapply() throws an error suggesting that you use the type-safe vapply() instead. apply() throws an error if you use it with a data frame.

    library(strict)
    sapply(1:10, sum)
    #> Error: [strict]
    #> Please use `vapply()` instead of `sapply()`.
    #> Please see ?strict_sapply for more details
  • : will throw an error instead of creating a decreasing sequence that terminates in 0.

    library(strict)
    
    x <- numeric()
    1:length(x)
    #> Error: [strict]
    #> Tried to create descending sequence 1:0. Do you want to `seq_along()` instead?
    #> 
    #> Please see ?shim_colon for more details
  • diag() and sample() throw an error if given scalar x. This avoids an otherwise unpleasant surprise.

    library(strict)
    
    sample(5:3)
    #> [1] 5 4 3
    sample(5:4)
    #> [1] 5 4
    lax(sample(5:5))
    #> [1] 3 2 1 4 5
    
    sample(5:5)
    #> Error: [strict]
    #> `sample()` has surprising behaviour when `x` is a scalar.
    #> Use `sample.int()` instead.
    #> Please see ?strict_sample for more details

Once strict is loaded, you can continue to run code in a lax manner using lax().

strict's People

Contributors

espinielli avatar hadley avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

strict's Issues

Error when using dplyr if list is redefined in a package

What I am doing is not exactly good practice anyway but I don't really understand why I am getting an error from strict here.

I have a package that creates a structure named list as list = structure(NA, class = 'result') and exports it. I have isolated this and placed it in this package. What it does isn't really important but when this package is loaded, if I try to use dplyr, I get an error

devtools::install_github('oganm/unpack')
library(strict)
library(unpack)
dplyr::filter(data.frame(a = c(1,2,3)), a == 1)
Error in filter_impl(.data, quo) : Evaluation error: [strict]
Multiple definitions found for `list`.
Please pick one:
 * unpack::list
 * base::list
Call `rlang::last_error()` to see a backtrace.

The code above does not try to use list which made me wonder if it can be avoided and why is it happening in the first place.

Don't allow load function for rds file

Double clicking a .rds file will automatically open the file with a load function call, which throws a very terse error:

t <- load("/Users/petergensler/Downloads/homedata_lesson1_clean.rds")
Error in load("/Users/petergensler/Downloads/homedata_lesson1_clean.rds") : 
  bad restore file magic number (file may be corrupted) -- no data loaded
In addition: Warning message:
file ‘homedata_lesson1_clean.rds’ has magic number 'X'
  Use of save versions prior to 2 is deprecated 

Maybe forcing a user to explicitly use read_rds when reading in a .rds file is a good idea?

##works fine
t <- readr::read_rds("/Users/petergensler/Downloads/homedata_lesson1_clean.rds")  

Use of deprecated function `rlang::env_bind_fns()`

> library(strict)
Warning message:
`env_bind_fns()` is deprecated as of rlang 0.3.0.
Please use `env_bind_active()` instead.
This warning is displayed once per session. 
> library(sessioninfo)
> session_info()
─ Session info ───────────────────────────────────────────────────────────────
 setting  value                       
 version  R version 3.4.4 (2018-03-15)
 os       Ubuntu 18.04.3 LTS          
 system   x86_64, linux-gnu           
 ui       X11                         
 language en_CA:en                    
 collate  en_US.UTF-8                 
 ctype    en_US.UTF-8                 
 tz       America/Toronto             
 date     2019-09-24                  

─ Packages ───────────────────────────────────────────────────────────────────
 package     * version    date       lib source                        
 assertthat    0.2.1      2019-03-21 [1] CRAN (R 3.4.4)                
 cli           1.1.0      2019-03-19 [1] CRAN (R 3.4.4)                
 crayon        1.3.4      2017-09-16 [1] CRAN (R 3.4.4)                
 rlang         0.4.0      2019-06-25 [1] CRAN (R 3.4.4)                
 sessioninfo * 1.1.1      2018-11-05 [1] CRAN (R 3.4.4)                
 strict      * 0.0.0.9000 2019-04-01 [1] Github (hadley/strict@446573b)
 withr         2.1.2      2018-03-15 [1] CRAN (R 3.4.4)                

[1] /usr/local/lib/R/site-library
[2] /usr/lib/R/site-library
[3] /usr/lib/R/library

`strict_drop()` error message should also make sense for subsetting rows

Great idea and package! Small issue in shim-risky.R: Perhaps change error message to "when selecting a single column or row"? Or disable warning because default is already drop = FALSE for rows?

> library("strict")
> mtcars[1, ]
Error: [strict]
Please explicitly specify `drop` when selecting a single column
Please see ?strict_drop for more details

conflict with package loading

Looks like strict trips up loading packages that use conflicted functions in their load scripts

E.g.

# package that overloads %*% from base
devtools::install_github('goldingn/greta')
library(greta)  

library(strict)

# apparently uses %*% in some load/attachment method
library(SparseM)
Error: package or namespace load failed for ‘SparseM’:
 [strict]
Multiple definitions found for `%*%`.
Please pick one:
 * greta::%*%
 * base::%*%

I can't workout exactly where in loading SparseM this happens, SparseM doesn't appear to have a .onLoad or .onAttach function and I couldn't shed any light by using debugonce(loadNamespace).

I can of course get around this with:

lax(library(SparseM))

but I suspect your aim is automatically isolate package loading from strict

Make T and F throw errors

env_bind_fns(environment(),
  T = function() abort("Please use TRUE, not T"),
  F = function() abort("Please use FALSE, not F")
)

(but has to happen at attach time, not build time)

For objects that exported from other packages

Multiple definitions found for `unit`.
Please pick one:
 * grid::unit
 * ggplot2::unit

Here unit are exported from grid. Will ggplot2::unit be a little bit redundant in this case?

Ideas

Interface

  • Delete conflicts code in favour of conflicted package.

  • Make use explicit, e.g. strict::activate() because that gives the ability to use arguments.
    Most importantly would use an edition/version argument so that we could increase the scope of the shims (hence making more existing code errorful) over time.
    Maybe give names to bundles of behaviour?
    use::strict().

  • How should it work inside package?
    Maybe only applies at development time?

  • Maybe need to reconsider name to make it more clear that it's opinionated, and others might not agree.

  • Related work: <https://github.com/koalaman/shellcheck>{.uri}, Rubocop

  • javascript is lexically scoped --- local_strict().
    options and env vars affect all code not just yours, so need to be careful.
    i.e. can't locally scope them.

    • how does use::strict() work inside a package?

    • use::strict(c("file", "vectors")); use::strict(except = "file")

  • Discuss pros and cons of static (linting) vs dynamic (strict)

  • Fixes for (e.g. sample()) require that strict be active even in production.
    This implies that strict can't do anything too slow.
    Still get a lot of protection if you just use in dev; just not quite as much.

  • Would need to make sure that all of the functions have solid documentation explaining the reasoning.
    But would let us put all of these arguments/explanations in one place.

Type stability

  • strict_sapply() could provide a hint as to what the vapply() code should look like.

  • Could also shim out basic arithmetic etc to use vctrs coercion and recycling rules.
    Similarly for paste(), to give it standard recycling rules.

    dplyr::filter(df, x == c("a", "b"))
    #> Error: lengths not compatible
    df$x == c("a", "b")
    # would still work
    
    use::tidyverse_recycling_rules()
    c("1", "2") == 1:3
    
    paste(character(), 1)
    
  • Require all tidyverse functions to supply .ptype (I think that's already implemented through an option)

  • Require units argument to difftime()

Data analysis

  • Register rlang error and warning handlers so that you get more useful backtraces.

  • setwd() should error.

  • factor(), sort() locale issues?
    (But what can you actually do about them?)

  • Make attach() an error

  • Set options(lifecycle_verbosity = "warning")

  • suppressWarning() should error

  • Set more env vars

    _R_CHECK_LENGTH_1_CONDITION_=true
    _R_CHECK_LENGTH_1_LOGIC2_=true
    

    Maybe these should go in separate function/argument since they don't have lexical scope?

Package development

  • Some specific tidyverse mode for common shims that we use to prevent ourselves (or contributors) from using the wrong function

    • Optionally make file manipulation functions error in favour of fs.
      Since warnings instead of errors make it easier to make mistakes.

    • Optionally make readLines()/writeLines() error, in favour of using brio.
      Due to the handling of utf8 and line endings.

    • Enforce version argument of saveRDS()

  • Declare R version that you want to support (or read from DESCRIPTION?) and shim functions that backport-ish function that would error saying which version of R they were introduced in.
    Similarly for functions that only exist on one OS (e.g. shell()).

Stricter naming rules for named vectors

I'm not sure the best way to address this, but I would love to have a stricter way of assigning names to vectors whose components may have names. When you create a named vector with c(), the names of underlying arguments can modify the names of the output.

x = c(a = 1)
y = c(b = x[1]*2)
y
#> b.a 
#>   2
x = c(1)
z = c(b = x[1]*2)
z
#> b 
#> 2

One way to avoid this is to use y = c(b = unname(x[1]*2)), but this is clunky.

Don't allow insecure package installation?

Should strict be concerned with the security or release status of package installs?

If so, it might make sense to:

  • Allow devtools::install_github to install tagged releases only.
  • Install only signed releases from Github.
  • Require https connections for CRAN repos.

This functionality would probably depend on the notary package.
If this is outside your goals for strict, I understand!

Don't allow use of && and || on vectors

This one catches me out quite a lot as I've come from another language where && and || are almost exclusively used (since they just mean short-circuit and/or).

x <- c(1,2,3,4,5)
x > 1 && x < 4
#[1] FALSE
x <- c(1,2,3,4,5)
x >= 1 & x < 6
[1] TRUE TRUE TRUE TRUE TRUE

Thanks to @WerthPADOH, I realise now that && and || just check the first item in the same way that if(vector) does. Very dangerous and would be good for it to throw an error

Don't allow using attach() on a data frame

Quite a few people still learn to attach(df) for working with data. This is a dangerous approach, as you get confusion about where results of a transformation are stored:

attach(iris)
Sepal.Length <- round(Sepal.Length, 0)

Now Sepal.Length and iris$Sepal.Length are two different things.

Personally I would even throw an error from the moment attach() is used. See also the session Good Practice in ?attach.

Should there be a warning mode?

I think sometimes giving a warning instead of just fail have advantages. Like there are some code not in you control, error can prevent it to run but you cannot fix it.

Warning cannot force user to fix the problem, but it can still tell careful users about the problem. With warnings I can apply strict to all my code and have a peace of mind that many things will be checked, but if a lot of things will break immediately I'll hesitate to add it.

Type checking for base string functions

Base R's internal string functions (regex, strsplit, substr, paste, etc.) all coerce non-string types (particularly factors, but also numbers) to character vectors, e.g.

# Nice ordered factor
mon <- factor(month.name, month.name, ordered = TRUE)
mon
#>  [1] January   February  March     April     May       June      July     
#>  [8] August    September October   November  December 
#> 12 Levels: January < February < March < April < May < June < ... < December

# Implicitly coerces factor to character
substr(mon, 1, 3)
#>  [1] "Jan" "Feb" "Mar" "Apr" "May" "Jun" "Jul" "Aug" "Sep" "Oct" "Nov"
#> [12] "Dec"

# Operating on levels keeps types properly
levels(mon) <- substr(levels(mon), 1, 3)
mon
#>  [1] Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec
#> 12 Levels: Jan < Feb < Mar < Apr < May < Jun < Jul < Aug < Sep < ... < Dec

or more ridiculously

gsub(12L, 21, 1234L)
#> [1] "2134"

While the coercion is at least consistent and probably expected by anyone who has used R for a while, it would occasionally be convenient to have a stricter type-safety requirement whereby all coercion must be explicit (like strict does with apply on data.frames), making R

paste0('foo', 47L)
# Error: [strict] ...

paste0('foo', as.character(47L))
#> [1] "foo47"

more like Python:

print('foo' + 47)
# TypeError: must be str, not int

print('foo' + str(47))
#> foo47

Is there a better option than use fully qualified name in every case?

I tried strict with my Shiny app, the first error is this:

Multiple definitions found for `box`.
Please pick one:
 * shinydashboard::box
 * graphics::box

Obvious solution is to use the fully qualified name. However this can be a little cumbersome, another side effect is my Shiny UI code indented a lot, using long names may force me to add more line breaks to keep code within 80 columns.

In Python we can use import x as y. With R we can actually just use sbox <- shinydashboard::box and use sbox everywhere.

I'm wondering if this is a good solution.

Shim seq and :

To throw error unless explicitly requested descending numbers

Don't allow `1:length(vector)`

Strict produces an error when one uses something that results in 1:0. The goal here being to prevent cases where someone uses 1:length(x) which can produce 1:0 when x is empty.

It seems to me the strict package is intended to help catch errors before they actually occur. If that's the case then it should warn about any uses of code that looks like 1:length(x) regardless of if it produces 1:0 or 1:10.

Function from another package throws a warning

If I use the sobel function from the package multilevel:

library(multilevel)
library(strict)
data(bh1996)
sobel(pred=bh1996$HRS,med=bh1996$LEAD,out=bh1996$WBEING)

I get

Warning messages:
1: In summary(model1)$coef : partial match of 'coef' to 'coefficients'
2: In summary(model2)$coef : partial match of 'coef' to 'coefficients'
3: In summary(model3)$coef : partial match of 'coef' to 'coefficients'

Moreover, using lax around it doesn't make the warnings go away.

Force local environment for variables inside functions

Would be great to have an error when trying to access variables outside of the local scope from inside a function, unless explicitly specified. I personally think this is one of the most useful checks in Perl strict, and something that causes a lot of problems for especially beginner R coders.

Disallow indexing by factors

Since factors sometimes behave like character vectors and sometimes behave like integers, it is a bad idea to pass a factor into a square bracket index. For example

(x <- c(d = 1, c = 4, b = 9, a = 16))
##  d  c  b  a
##  1  4  9 16
(index <- factor(letters[1:4]))
## [1] a b c d
## Levels: a b c d
x[as.character(index)]
##  a  b  c  d
## 16  9  4  1
x[as.integer(index)]
##  d  c  b  a
##  1  4  9 16

Can you guess what x[index] returns?

If it took some thinking about, then I think you'll agree that factor indexing is problematic.

It would be useful if strict mode caused x[index] to throw an error.

BiocGenerics library throws error with strict

Hi,

I'm using strict and I'm seeing the following error on a function I am not calling in my script. Any ideas? I've tried using lax(BiocGenerics) but does not work and I'm not sure if it should.

To reproduce:

library(strict)
library(BiocGenerics)
library(readr)
read_tsv("example.tab")

gives:

terminate called after throwing an instance of 'Rcpp::eval_error'
  what():  Evaluation error: [strict]
Multiple definitions found for evalq.
Please pick one:
 * BiocGenerics::evalq
 * base::evalq.
Aborted (core dumped)
sessionInfo()
R version 3.4.1 (2017-06-30)
Platform: x86_64-redhat-linux-gnu (64-bit)
Running under: CentOS Linux 7 (Core)

Matrix products: default
BLAS/LAPACK: /usr/lib64/R/lib/libRblas.so

locale:
 [1] LC_CTYPE=en_US.UTF-8       LC_NUMERIC=C
 [3] LC_TIME=en_US.UTF-8        LC_COLLATE=en_US.UTF-8
 [5] LC_MONETARY=en_US.UTF-8    LC_MESSAGES=en_US.UTF-8
 [7] LC_PAPER=en_US.UTF-8       LC_NAME=C
 [9] LC_ADDRESS=C               LC_TELEPHONE=C
[11] LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base

other attached packages:
[1] strict_0.0.0.9000

loaded via a namespace (and not attached):
 [1] httr_1.3.1      compiler_3.4.1  R6_2.2.2        tools_3.4.1
 [5] withr_2.0.0     curl_2.8.1      memoise_1.1.0   git2r_0.19.0
 [9] digest_0.6.12   rlang_0.1.2     devtools_1.13.3

RStudio code does not work in strict mode

Is there a way to load strict automatically, but not immediately at startup?

library(strict) in .Rprofile (alone) causes a blank RStudio (v1.0.143) screen and:

ERROR r error 4 (R code execution error) [errormsg=Error : [strict]
Please use `vapply()` instead of `sapply()`.
Please see ?strict_sapply for more details
]; OCCURRED AT: rstudio::core::Error rstudio::r::exec::evaluateString(const std::string &, SEXP *, sexp::Protect *) /Users/rstudio/rstudio/src/cpp/r/RExec.cpp:302

Seen on macOS 10.12.5 with R 3.4.0. Apologies, if it's more of an RStudio issue!

Unload strict package without restarting session

In case anyone else has had need to unload the strict R package without restarting your session, you need to do the following:

if ("strict_conflicts" %in% search()) detach("strict_conflicts")
if ("strict_shims" %in% search()) detach("strict_shims")
if ("strict" %in% loadedNamespaces()) unloadNamespace("strict")

Unfortunately, detach("package:strict") doesn't work. There's a little more detail here.

Please let me know if I've missed anything.

Guidelines on performance issues

This is an extremely useful package, thanks for developing it!

I think the README would benefit from some insight on performance impact, particularly the use of lax(). I have not delved into the internals, but I presume you're adding some fairly deep hooks to core methods in order to keep an eye out for pitfalls. The : vector operations appear to be roughly 5 times slower with strict when using a variable as the right argument (1:x) and ~24x slower when a constant is used (1:4). lax operations wrapped around : seem to be over 40 times slower for a variable right argument, and 650x slower when a constant is used. In many cases this would be trivial, but in some cases it could have a major impact.

It would be helpful if you could share any insights on where major performance costs might lie, and how to minimize them. Sample benchmark code (for :):

## Make sure strict is not loaded initially
library("microbenchmark")
rndVect <- function() {
    for (i in 1:100) {
        z <- sample(1:4,1)
        x <- 1:z # Vector of 'random' length
    }
}
fixVect <- function() {
    for (i in 1:100) {
        x <- 1:4 # Vector of fixed length
    }
}
set.seed(1234)
## Times are in microseconds
microbenchmark(rndVect = rndVect(), fixVect = fixVect(),
               times = 1000, unit = 'us')
## Means on my system: rndVect = 590, fixVect = 38

####### Load strict #######
library("strict")
set.seed(1234)
microbenchmark(rndVect = rndVect(), fixVect = fixVect(),
               times = 1000, unit = 'us')
## Means on my system: rndVect = 2900, fixVect = 920

set.seed(1234)
microbenchmark(rndVect = lax(rndVect()), fixVect = lax(fixVect()),
               times = 100, unit = 'us')
## Means on my system: rndVect = 26000, fixVect = 25000

## R 3.3.1, x86_64-pc-linux-gnu

Thanks again!

Error if condition for control statements that have length != 1

R can change its behavior for code like...

a <- 1:2
if (a == 1) {
  print("ok")
}

to be an error instead of the typical the condition has length > 1 and only the first element will be used warning. It seems like it might be in keeping with package:strict to throw that error. However, it looks like this would require setting an environmental variable...

Sys.setenv(`_R_CHECK_LENGTH_1_CONDITION_`="true")
a <- 1:2
if (a == 1) {
  print("ok")
}

What do you think, is setting that env var in scope for package:strict?

strict is still running after Shiny app stopped

After error reported from strict, I terminated my Shiny app and start to fix the problems. Then I found there are still console output, and the source file cannot be saved, RStudio had problems connecting with the R session.

You can found below that there are some errors reported in console even I was just checking help documents.

> shiny::runApp('shiny/app')
Loading required package: shiny
Loading required package: pacman

Listening on http://127.0.0.1:6016
sh: -c: line 0: syntax error near unexpected token `)'
sh: -c: line 0: `(<p>No data are available for download.</p>) > /var/folders/f3/6cdx4zf94qz95r6d89s_4xcsrcsjqm/T//RtmpWustTW/file6f1f331b7684'
Error in fread(res$res_cont, sep = ",", nrows = 5) : 
  file not found: /var/folders/f3/6cdx4zf94qz95r6d89s_4xcsrcsjqm/T//RtmpWustTW/file6f1f331b7684
Warning: Error in : [strict]
Multiple definitions found for `%>%`.
Please pick one:
 * stringr::%>%
 * DT::%>%
Stack trace (innermost first):
    87: <Anonymous>
    86: stop
    85: abort
    84: strict_abort
    83: <Anonymous>
    82: exprFunc [/Users/xhdong/Projects/ctmm-Shiny/shiny/app/server.R#295]
    81: widgetFunc
    80: func
    79: origRenderFunc
    78: renderFunc
    77: origRenderFunc
    76: output$individuals
     1: shiny::runApp

> ?`%>%`
Error: [strict]
Multiple definitions found for `plot`.
Please pick one:
 * ctmm::plot
 * graphics::plot
> ?plot
Error: [strict]
Multiple definitions found for `plot`.
Please pick one:
 * ctmm::plot
 * graphics::plot
Error: [strict]
Multiple definitions found for `plot`.
Please pick one:
 * ctmm::plot
 * graphics::plot
Error: [strict]
Multiple definitions found for `plot`.
Please pick one:
 * ctmm::plot
 * graphics::plot
Error: [strict]
Multiple definitions found for `plot`.
Please pick one:
 * ctmm::plot
 * graphics::plot
Error: Unable to establish connection with R session
Error: Unable to establish connection with R session

Is it possible to use strict as some inspections?

If the strict checks can be run as inspections instead of fail on error, there will be these advantages:

  • Running inspections can gather all the errors in one run instead of one error at a time (assuming the original code can be executed normally), which provide a good overview and are more efficient. For example I have several cases needing fully qualified name, but I have to run the code again and again to find yet another case.
  • This give user the option to selectively fix some issues. I knew this could be different with the motivating philosophy, though sometimes there are some special cases that don't have a perfect solution yet, like the multiple source of %>%.
  • I would say all the conditions that strict check are not equal. Some definitely should be fixed, some are less serious. An inspection that report all the problems will allow user to apply some priority on them.

I understand to run these conditions check as inspections probably is not easy, and could need substantial changes from current code.

base::diag rejecting strict_diag

strict::strict_diag(matrix(1:9, nrow = 3))

returns

Error in base::diag(x = x, nrow = nrow, ncol = ncol) : 
  'nrow' or 'ncol' cannot be specified when 'x' is a matrix

Is that intended?

I'm using R 3.3.3, but cannot find anything in the changelog to explain the failure.

Can strict report the error source location in Shiny app?

When I used strict in my Shiny app, the error stack trace didn't tell me the location of the error source:

Listening on http://127.0.0.1:6633
Warning: Error in : [strict]
Multiple definitions found for `source`.
Please pick one:
 * XML::source
 * base::source
Stack trace (innermost first):
    44: <Anonymous>
    43: stop
    42: abort
    41: strict_abort
    40: <Anonymous>
     1: runApp
Error : [strict]
Multiple definitions found for `source`.
Please pick one:
 * XML::source
 * base::source
ERROR: [on_request_read] connection reset by peer

The error message provide enough information for me to locate the problem, but I'm wondering if the specific line can be reported like strict error in regular R code.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.