Describe the bug
VSCode-R evaluates the delayed-assign object too early.
To Reproduce
delayedAssign("delayed_obj", {
stop("should not execute")
})
The code inside has been executed but it shouldn't as delayed_obj is not evaluated

The code inside is executed only when delayed_obj gets evaluated

Do you want to fix by self? (I hope your help!)
Yes
(If yes,) what kind of help do you want? (e.g. Which file should I fix, Survey (related documents)
I want to know where to get started...
(If related)setting.json
{
"remote.SSH.connectTimeout": 30,
"remote.SSH.maxReconnectionAttempts": 5,
"remote.SSH.remotePlatform": {
"10.4.119.58": "linux",
"10.4.120.45": "linux"
},
"r.sessionWatcher": true,
"r.rterm.windows": "D:\\app\\Python\\Python39\\Scripts\\radian.exe",
"r.rpath.windows": "D:\\app\\R-4.0.0\\bin\\R.exe",
"diffEditor.renderSideBySide": true,
"[r]": {
"editor.formatOnSave": false
},
"git.autofetchPeriod": 300,
"terminal.integrated.shell.windows": "C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe",
"window.zoomLevel": 0,
"r.lsp.diagnostics": false,
"git.confirmSync": false,
"r.alwaysUseActiveTerminal": true,
"r.bracketedPaste": true,
"diffEditor.ignoreTrimWhitespace": false,
"git.autofetch": true,
"editor.tabSize": 2,
"terminal.external.windowsExec": "C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe",
"typescript.suggest.paths": false
}
Expected behavior
Should not evaluate the delayed-assign object so early - we should only evaluate the object when we really need it
Screenshots
See the comment in Reproduce Step
Environment (please complete the following information):
Thanks for working on this issue!
I want to know where to get started...
I believe the code related to this issue is here. A quick fix to this issue should be to disable the session watcher functionality. A proper solution probably requires some modification of init.R.
In the package vscDebugger we had similar issues, maybe the code is also relevant here (e.g. here and here).
It is caused by https://github.com/ManuelHentschel/vscode-R/blob/6cec72bdd3101ee0b5cd329c605f400752e52b01/R/init.R#L84 where eapply(env, ...) forces the evaluation of all symbols in env.
local({
x <- 1
delayedAssign("x", stop("a"))
eapply(environment(), function(x) NULL)
})
To avoid forcing the evaluation of promises in the global environment, we might have to check each symbol if it is a promise, as done in vscDebugger.
However, it might require using the R C API to do that, or we need to rely on some package such as pryr.
Probably I can relatively easily package up the code that I contributed to vscDebugger and try to submit it to CRAN. A further (more involved) solution is to try to identify all common functionalities between vscDebugger and vscode-R and create a common package for them.
However, it might require using the R C API to do that, or we need to rely on some package such as pryr.
Yes, I agree that we may not be able know if the object is a promise or not, without using the R C API or another package like pryr, according to R-lang/Promise-objects:
Within the R language, promise objects are almost only seen implicitly: actual function arguments are of this type. There is also a delayedAssign function that will make a promise out of an expression. There is generally no way in R code to check whether an object is a promise or not, nor is there a way to use R code to determine the environment of a promise.
So is it ok for vscode-R to depend on the pryr package? If so, I'm happy to file a PR.
(the C code to check is simple but I don't want to introduce compiled code for vscode-R, as it may need to upgrade often and the DLL lock on Windows may cause trouble)
Thanks.
I'm hesitated to introduce an R package to work with session watcher like vscDebugger does with VSCode-R-Debugger because it makes vscode-R less work-out-of-the-box unless we also make the whole installation process fast and smooth.
@shrektan
If you look at the links that @ManuelHentschel provided in his answer you can see that we solved exactly the same problem in vscDebugger. vscDebugger imported pryr which was unsafe because pryr is not maintained any more. Check the second link for the C code and the first link for the R side.
In the package vscDebugger we had similar issues, maybe the code is also relevant here (e.g. here and here).
I'm hesitated to introduce an R package to work with session watcher like vscDebugger does with VSCode-R-Debugger because it makes vscode-R less work-out-of-the-box unless we also make the whole installation process fast and smooth.
Well, the relevant code already depends on jsonlite. So adding a further tiny package should not make the installation process much harder.
I think the easiest way is to use rlang::env_binding_are_lazy(.GlobalEnv).