-
Notifications
You must be signed in to change notification settings - Fork 151
Update environment binding API with planned ctors and accessors #1871
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
Conversation
1cc1f28 to
9dcf9dc
Compare
DavisVaughan
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like a nice API to me!
| r_obj* value = r_env_find(env, sym); | ||
|
|
||
| if (value == r_syms.unbound) { | ||
| return R_ENV_BINDING_TYPE_unbound; | ||
| } | ||
|
|
||
| if (value == r_missing_arg) { | ||
| return R_ENV_BINDING_TYPE_missing; | ||
| } | ||
|
|
||
| if (r_typeof(value) == R_TYPE_promise) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wouldn't be against implementing these in terms of just pure R API, rather than r_env_find(). That way we could fully remove r_env_find() eventually without having to think about "old R" support
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hmm I might be misunderstanding but I'm not sure how that would work. I'm fine having the old R support in place, this code will likely be unchanged for years once the R API has stabilised.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
all i meant here was using Rf_findVarInFrame3() directly in place of r_env_find(), in case we wanted to remove r_env_find()
| r_env_unbind(env, sym); | ||
| R_MakeActiveBinding(sym, fn, env); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Interesting that R_MakeActiveBinding() fails on preexisting standard bindings
| r_abort("Not a forced binding."); | ||
| } | ||
|
|
||
| return PRVALUE(value); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I faintly remember us saying that you are supposed to just Rf_eval() a forced binding to get its value, which is why we didn't add R_ForcedBindingValue(). Maybe use that?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We have the promise already so doing a separate lookup might be surprising in other ways
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But PRVALUE() is non-API. So what's the correct API compliant way to get the value?
| KEEP(value); | ||
| Rf_defineVar(sym, value, env); | ||
| FREE(1); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From what I can tell, Rf_defineVar() will protect value if it needs to, so I think you can skip this
There was a problem hiding this 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 but rchk might take issue with that, I faintly remember having to do macros to get it to acknowledge the protection.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yep: 28ce7b0
src/rlang/env-binding.h
Outdated
| } | ||
|
|
||
| static inline | ||
| void r_env_poke(r_obj* env, r_obj* sym, r_obj* value) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For legacy reasons? Seems like we use it a lot
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I missed that, I have now renamed it to r_env_bind()
| r_env_binding_delayed_expr(from, sym), | ||
| r_env_binding_delayed_env(from, sym) | ||
| ); | ||
| break; | ||
|
|
||
| case R_ENV_BINDING_TYPE_forced: | ||
| r_env_bind_forced( | ||
| env, | ||
| sym, | ||
| r_env_binding_forced_expr(from, sym), | ||
| r_env_binding_forced_value(from, sym) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess this relies on the _expr, _env, and _value helpers never allocating, right? Because if r_env_binding_delayed_expr() and r_env_binding_delayed_env() allocate then we'd have a protection issue. But I guess we'd say that the promise is protecting them?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you're right, this relies on the assumption that the accessors do pure access and don't allocate. Otherwise rchk will flag us down.
DavisVaughan
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like a nice API to me!
So we can write algorithms that can be easily switched to the API discussed at https://bugs.r-project.org/show_bug.cgi?id=18928