Add unary "+", "-" and "!" - #53
Conversation
|
@codex review (can I also do it ?) |
There was a problem hiding this comment.
Codex Review: Here are some suggestions.
About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you open a pull request for review, mark a draft as ready, or comment "@codex review". If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex fix this CI failure" or "@codex address that feedback".
| if (length(args) == 1L) { | ||
| x <- r2f(args[[1L]], scope, ...) | ||
| Fortran(glue("(+{x})"), x@value) |
There was a problem hiding this comment.
[P1] Avoid reusing operand Variable in unary handlers
The new unary +/-/! handlers return Fortran(..., x@value) which reuses the same Variable object as the operand. When that result is assigned to a different symbol (e.g. y <- -x) the assignment code renames x@value to y, so the original binding for x no longer has a declaration. Any later reference to x in the function will emit x in the generated Fortran but no corresponding Variable exists, producing undeclared variable errors at compile time. Please create a fresh Variable(x@value@mode, x@value@dims) for unary results instead of mutating the source. The same issue appears in the unary - and ! handlers below.
Useful? React with 👍 / 👎.
|
@codex please review again |
|
Codex Review: Didn't find any major issues. Nice work! About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you open a pull request for review, mark a draft as ready, or comment "@codex review". If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex fix this CI failure" or "@codex address that feedback". |
|
Hmm ... after trying to understand codex suggestion, I think I have come to the conclusion, that it is not necessary. Codex seem to think S7 works like R6 in this case. I think this part was confusing it in the assignment handler ["<-"] # immutable / copy-on-modify usage of Variable()
if (is.null(var <- get0(name, scope))) {
# this is a binding to a new symbol
var <- value@value
var@name <- name
scope[[name]] <- varEven though the comment state it is immutable /copy-on-modify. |
|
Looks great! Can you please add a NEWS entry? |
This reverts commit e5931a5.
|
Reverted last commit and added news entry. |
|
Thanks! Looking at the code again just now, I see that the Codex suggestion was right, just for the wrong stated reason! A |
|
We can revert back again. As I understand it, in the assignment handler around here: stopifnot(is.symbol(target))
name <- as.character(target)
value <- args[[2]]
value <- r2f(value, scope, ...)
# immutable / copy-on-modify usage of Variable()
if (is.null(var <- get0(name, scope))) {
# this is a binding to a new symbol
var <- value@value
var@name <- name
scope[[name]] <- var
} else {We take the symbol-name on the left side (y <- x) and then we replace the copied x-name with the target y. And this is what saves us. If we fixed it here, I think we also need to fixed in the other unary intrinsic section. e.g r2f_handlers[["abs"]] <- function(args, scope, ...) {
stopifnot(length(args) == 1L)
arg <- r2f(args[[1]], scope, ...)
Fortran(glue("abs({arg})"), arg@value)
}We are using the same pattern. |
|
Oh, good catch! That should definitely be updated in |
|
I have previously tried to create a bug related to this Perhaps we can merge this one and then I don't mind creating a new PR for more robust handling of this and other handlers. Here is what codex had to say: Unary handler Variable reuse causes compile-time errorSummary: Reusing the operand’s Reproduction
devtools::load_all(quiet = TRUE)
qfun <- quick(function(x){
declare(type(x = logical(NA)))
y <- !x
out <- ifelse(y, 1L, 0L)
out
}, name = "bug_unary_not_local_cast")
qfun(c(TRUE, FALSE, TRUE))
What was generated and why it’s wrong
Where the pattern appears
Root cause
Fix
Concrete changes
Optional helper
Evidence tests
Key code references
TL;DR
|
Fixes #52
Not-operator only works with logical variable. If you want, I guess it could be extended to integer and double where 0 and 0.0 is true and false otherwise.