Skip to content

Refactor slide computation function generation and move to as_slide_computation #337

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 22 commits into from
Aug 11, 2023

Conversation

nmdefries
Copy link
Contributor

@nmdefries nmdefries commented Jun 27, 2023

Description

Move assert_sufficient_f_args calls to within as_slide_computation.

Move computation function creation into as_slide_computation. Includes:

  • epi_slide computation function creation for the function/formula case
  • epix_slide forwarding an unmodified function in the function/formula case, and
  • epi[x]_slide computation function creation in the quosure case

Changes involved adding quosure-handling block to as_slide_computation. Stop passing quo as an argument to the quosure-case functions. Make epi_slide quosure-case data masking procedure match that of epix_slide (for easier refactoring).

Changes

  • R/grouped_epi_archive.R
  • R/slide.R
  • R/utils.R
  • A couple test files to make sure that dots access via .data matches access via .x and without a pronoun.

Fixes

Closes #326

In `as_slide_computation`, call `eval_tidy` on the quosure `x` passed
directly to `as_slide_computation`, rather than generating an
`f_wrapper` computation function that takes the quosure as an argument.
The computation function is regenerated each time `slide` is called, with
a new quosure, so the computation function doesn't need to be flexible
enough to run with different `quo`s.

This change makes the function/formula and quosure forks more similar,
since `group_modify`, `slide_one_grp` in the `epi_slide` case, and
`comp_one_grp` in the `epix_slide` case no longer need a `quo` argument
in the quosure fork. To make the two forks fully identical, the quosure
fork was changed to pass an empty set of dots to the computation
functions.

The `as_slide_computation` call and `group_modify` call can now be
pulled out of the if/else block.
@nmdefries nmdefries changed the title Ndefries/func conversion expansion Refactor slide computation function generation and move to as_slide_computation Jun 28, 2023
@nmdefries nmdefries marked this pull request as ready for review June 29, 2023 14:39
@nmdefries nmdefries requested a review from dajmcdon as a code owner June 29, 2023 14:39
Base automatically changed from ndefries/drop-nargs-num-args-check to main July 27, 2023 18:01
@nmdefries nmdefries requested a review from brookslogan July 27, 2023 18:15
`... = missing_arg(); some_function(...)` will pass zero arguments to
`some_function`, so we don't need to accept `...` in converted quosures.
@brookslogan
Copy link
Contributor

I have a few minor edits queued up locally that I'll ask you to look over after I finish a couple tests.

Question: what do you think about making as_slide_computation(f, ...) return a definitely-3-arg function that bakes in the dots? So no special-casing tidyeval outside of as_slide_computation would be needed. This would perhaps hit performance a bit in the f-is-function + nonzero ... case (or some more new_function-derivation but I'm not sure that's great for user debugging).

@nmdefries
Copy link
Contributor Author

making as_slide_computation(f, ...) return a definitely-3-arg function that bakes in the dots

Could you be a little more specific on this? What does "baking in the dots" mean? Are you saying that as_slide_computation will return a function like f(.x, .group_key, .ref_time_value) and the ... passed to as_slide_computation(f, ...) will be interpreted as local vars within the returned function f?

@brookslogan
Copy link
Contributor

Could you be a little more specific on this? What does "baking in the dots" mean? Are you saying that as_slide_computation will return a function like f(.x, .group_key, .ref_time_value)

Yes.

and the ... passed to as_slide_computation(f, ...) will be interpreted as local vars within the returned function f?

Not sure what counts as "local vars". I was thinking one approach would be:

as_slide_computation = function(f, ...) {

[...]

if (rlang::dots_n(...) > 0L) {
  function(.x, .group_key, .ref_time_value) {
    f(.x, .group_key, .ref_time_value, ...)
  }
} else {
  # in case forwarding dots is expensive, we could special-case 0 dots to not incur the forwarding expense
  f
}

[...]

}

A couple warnings were leaking out of `test()` from test cases that produced a
warning + error but only used `expect_error()`.  Use `expect_warning` in
addition to test for specific expected warnings.
Copy link
Contributor

@brookslogan brookslogan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure what I meant by untested changes locally. I've pushed the tweaks I had. Please sanity-check them. I think the only lingering question is about whether to try to "bake in" the dots + de-duplicate the tidyeval stuff. Maybe I'll just mark this approved and that could be in another PR?

@nmdefries nmdefries merged commit 1eceeb6 into main Aug 11, 2023
@nmdefries nmdefries deleted the ndefries/func-conversion-expansion branch August 11, 2023 17:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Expand as_slide_computation to perform f function validation and convert tidy computations into functions
2 participants