Skip to content
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

splice and !!! don't seem to have identical behaviours #1778

Closed
kieranjmartin opened this issue Feb 20, 2025 · 4 comments
Closed

splice and !!! don't seem to have identical behaviours #1778

kieranjmartin opened this issue Feb 20, 2025 · 4 comments

Comments

@kieranjmartin
Copy link

kieranjmartin commented Feb 20, 2025

My understanding from the documentation is that these should behave in the same way, but I have found at least one (slightly convoluted) example where this is not the case.

(this is in R 4.4.1 with rlang 1.1.4)


simpler_inside <- function(c,d){
  c+d
}

simpler <- function(...){
  ldots <- list(...)
  rlang::inject(
    simpler_inside(
      !!!ldots
    )
  )
}
simpler(3,4)

This works, but if you replace simpler with

simpler <- function(...){
  ldots <- list(...)
  rlang::inject(
    simpler_inside(
      rlang::splice(ldots)
    )
  )
}
simpler(3,4)

This now errors with Error in simpler_inside(rlang::splice(ldots)) : argument "d" is missing, with no default. Looking at the debug, it seems like in this example the "splice" call is passed as the first argument to simpler_fun and then unpacks, and ideally should unpack before that.

I appreciate this example is a little artificial (there's no reason for me to turn the dots into a list here); my actual example involves a function factory where I need to extract the dots to pass to a function.

Perhaps this is me not understanding the differences, but I had thought that splice and !!! should act in the same way here.

@lionel-
Copy link
Member

lionel- commented Feb 24, 2025

yep splice() is lazy and only interpreted by list2().

@lionel- lionel- closed this as completed Feb 24, 2025
@kieranjmartin
Copy link
Author

Apologies, is this documented anywhere? The only reference to splice explicitly seems to be here which just says "To avoid this in performance-critical code, use splice() instead of !!!:" which led me to think they were perhaps interchangeable.

@lionel-
Copy link
Member

lionel- commented Feb 25, 2025

I added some docs in ad84ce4

The docs are not great because this is an obscure (and forgotten) part of dynamic dots.

@kieranjmartin
Copy link
Author

Thanks, that looks good!

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

No branches or pull requests

2 participants