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

Investigate and remove Rf_findVarInFrame3 usage in environment #367

Closed
DavisVaughan opened this issue Aug 1, 2024 · 2 comments · Fixed by #386
Closed

Investigate and remove Rf_findVarInFrame3 usage in environment #367

DavisVaughan opened this issue Aug 1, 2024 · 2 comments · Fixed by #386

Comments

@DavisVaughan
Copy link
Member

operator SEXP() const { return safe[Rf_findVarInFrame3](parent_, name_, TRUE); };
operator sexp() const { return SEXP(); };
};
public:
environment(SEXP env) : env_(env) {}
environment(sexp env) : env_(env) {}
proxy operator[](const SEXP name) const { return {env_, name}; }
proxy operator[](const char* name) const { return operator[](safe[Rf_install](name)); }
proxy operator[](const std::string& name) const { return operator[](name.c_str()); }
bool exists(SEXP name) const {
SEXP res = safe[Rf_findVarInFrame3](env_, name, FALSE);
return res != R_UnboundValue;
}

@DavisVaughan
Copy link
Member Author

DavisVaughan commented Aug 3, 2024

Likely going to use R_existsVarInFrame() in exists() on R >=4.2.0


And then likely going to use the new R_getVarEx() on >=R-devel, although it has different semantics than Rf_findVarInFrame3(env, sym, TRUE) in edge cases, i.e.:

  • For R_MissingArg values in the env, R_getVarEx() errors
  • For promises in the env, R_getVarEx() will evaluate them before returning them

I don't think there is anything we can do about this unless we get an iterator API for environments that doesn't add special behavior like this

@DavisVaughan
Copy link
Member Author

DavisVaughan commented Aug 5, 2024

Lionel and I decided that for the proxy SEXP conversion method, we should use the new R_getVar() function (not the extended version), which would:

  • Error on R_MissingArg (definitely what R Core wants from us)
  • Error on unbound symbols in the env (you should check with exists() first, also good to not expose R_UnboundValue)
  • Evaluate promises (probably what the typical user wants)

https://github.com/wch/r-source/blob/0986e80068addc5c884d06580412ff2331436814/src/main/envir.c#L2305

And then for the fallback for older R versions we call Rf_findVarInFrame3() but then add 3 checks to reimplement the 3 bullets from above, so the behavior is consistent on all R versions.

After the enum / iterator API for environments is released, people will have more options if they want to manually implement more advanced behaviors than this "safe" way.

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 a pull request may close this issue.

1 participant