tidyverse / magrittr

Improve the readability of R code with the pipe

Home Page:https://magrittr.tidyverse.org

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

combination of fseqs

MyKo101 opened this issue · comments

I believe the ability to add fseq functions together as a chain would be useful to users of fseq functions and would probably increase their usage. For example, users could define the following:

f <- . %>% add(2) %>% divide_by(2)
g <- . %>% multiply_by(2)
h <- f + g

Which would output:

> h
Functional sequence with the following components:

 1. add(., 2)
 2. multiply_by(., 2)
 3. divide_by(., 2)

Use 'functions' to extract the individual functions. 

I had implemented a feature like this in my own package, mpipe, however the magrittr 2.0 update broke my version and I've not got round to updating it on GH. I would be interested to know if this feature would be appealing to be used directly in magrittr.

I had a look at the new fseq internals and believe that it could be as simple as the follow method:

`+.fseq` <- function(a,b){
  a_env <- environment(a)
  b_env <- environment(b)
  
  e <- new.env(parent = parent.env(a_env))
  e[["env"]] <- a_env
  e[["_function_list"]] <- c(
    a_env[["_function_list"]],
    b_env[["_function_list"]]
  )
  e[["exprs"]] <- as.pairlist(c(
    a_env[["exprs"]],
    b_env[["exprs"]]
  ))
  res <- function(value){
    freduce(value,`_function_list`)
  }
  environment(res) <- e
  class(res) <- c("fseq","function")
  res
}

However, I understand if this is out of scope for magrittr

I see that mpipe is still a github-only package. Just a heads up that it shouldn't be published on CRAN because it defines methods for:

  • generics which you don't own, e.g. +,
  • with classes that you don't own, e.g. fseq.

Method registration has global effects for the whole package ecosystem as soon as the package is loaded, even if it's only loaded because of indirect dependencies which the user (and other packages) have no idea about. This is why you shouldn't implement methods for others.

I think using purrr to combine fseqs is probably the way to go:

f <- . %>% add(2) %>% divide_by(2)
g <- . %>% multiply_by(2)
h <- purrr::compose(f, g)

h
#> <composed>
#> 1. Functional sequence with the following components:
#>
#>  1. multiply_by(., 2)
#>
#> Use 'functions' to extract the individual functions.
#>
#> 2. Functional sequence with the following components:
#>
#>  1. add(., 2)
#>  2. divide_by(., 2)
#>
#> Use 'functions' to extract the individual functions.

h(10)
#> [1] 11

f(g(10))
#> [1] 11

Just to close the loop here, I think mpipe is a cool idea, but not something we'd consider for inclusion in magrittr, because we're trying to keep it as small as possible as we plan to transition to the base R pipe over the next few years.