DolphinDB JIT doesn't support break and continue in while-loop and for-loop? - jit

Recently I found that DolphinDB has supported JIT from version 1.01. But I found that break and continue doesn't work in for-loop or while-loop. I tried something like this:
#jit
def foo() {
for(i in 1..10) {
break
}
}
foo()
#jit
def foo() {
i = 0
while(i < 100) {
continue
}
}
foo()
both of them doesn't work, and throw exceptions. Since break and continue are pretty common
in my previous scripts, it's very inconvenience if they are not supported. So my question is are there any problem with my code, or will them be supported in later releases?

Please checkout version 1.01.2. This version supported the use of break and continue in JIT

Related

Is there any real use of the forever keyword in Qt? [duplicate]

Why do some people use while(true){} blocks in their code? How does it work?
It's an infinite loop. At each iteration, the condition will be evaluated. Since the condition is true, which is always... true... the loop will run forever. Exiting the loop is done by checking something inside the loop, and then breaking if necessary.
By placing the break check inside the loop, instead of using it as the condition, this can make it more clear that you're expecting this to run until some event occurs.
A common scenario where this is used is in games; you want to keep processing the action and rendering frames until the game is quit.
It's just a loop that never ends on its own, known as an infinite-loop. (Often times, that's a bad thing.)
When it's empty, it serves to halt the program indefinitely*; otherwise there's typically some condition in the loop that, when true, breaks the loop:
while (true)
{
// ...
if (stopLoop)
break;
// ...
}
This is often cleaner than an auxiliary flag:
bool run = true;
while (run)
{
// ...
if (stopLoop)
{
run = false;
continue; // jump to top
}
// ...
}
Also note some will recommend for (;;) instead, for various reasons. (Namely, it might get rid of a warning akin to "conditional expression is always true".)
*In most languages.
Rather than stuff all possible conditions in the while statement,
// Always tests all conditions in loop header:
while( (condition1 && condition2) || condition3 || conditionN_etc ) {
// logic...
if (notable_condition)
continue; // skip remainder, go direct to evaluation portion of loop
// more logic
// maybe more notable conditions use keyword: continue
}
Some programmers might argue it's better to put the conditions throughough the logic, (i.e. not just inside the loop header) and to employ break statements to get out at appropriate places. This approach will usually negate the otherwise original conditions to determine when to leave the loop (i.e. instead of when to keep looping).
// Always tests all conditions in body of loop logic:
while(true) {
//logic...
if (!condition1 || !condition2)
break; // Break out for good.
// more logic...
if (!condition3)
break;
// even more logic ...
}
In real life it's often a more gray mixture, a combination of all these things, instead of a polarized decision to go one way or another.
Usage will depend on the complexity of the logic and the preferences of the programmer .. and maybe on the accepted answer of this thread :)
Also don't forget about do..while. The ultimate solution may use that version of the while construct to twist conditional logic to their liking.
do {
//logic with possible conditional tests and break or continue
} while (true); /* or many conditional tests */
In summary it's just nice to have options as a programmer. So don't forget to thank your compiler authors.
When Edsger W. Dijkstra was young, this was equivalent to:
Do loop initialization
label a:
Do some code
If (Loop is stoppable and End condition is met) goto label b
/* nowadays replaced by some kind of break() */
Do some more code, probably incrementing counters
go to label a
label b:
Be happy and continue
After Dijkstra decided to become Antigotoist, and convinced hordes of programmers to do so, a religious faith came upon earth and the truthiness of code was evident.
So the
Do loop initialization
While (true){
some code
If (Loop is stoppable and End condition is met) break();
Do some more code, probably incrementing counters
}
Be happy and continue
Replaced the abomination.
Not happy with that, fanatics went above and beyond. Once proved that recursion was better, clearer and more general that looping, and that variables are just a diabolic incarnation, Functional Programming, as a dream, came true:
Nest[f[.],x, forever[May God help you break]]
And so, loops recursion became really unstoppable, or at least undemonstratively stoppable.
while (the condition){do the function}
when the condition is true.. it will do the function.
so while(true)
the condition is always true
it will continue looping.
the coding will never proceed.
It's a loop that runs forever, unless there's a break statement somewhere inside the body.
The real point to have while (true) {..} is when semantics of exit conditions have no strong single preference, so its nice way to say to reader, that "well, there are actually break conditions A, B, C .., but calculations of conditions are too lengthy, so they were put into inner blocks independently in order of expected probability of appearance".
This code refers to that inside of it will run indefinitely.
i = 0
while(true)
{
i++;
}
echo i; //this code will never be reached
Unless inside of curly brackets is something like:
if (i > 100) {
break; //this will break the while loop
}
or this is another possibility how to stop while loop:
if (i > 100) {
return i;
}
It is useful to use during some testing. Or during casual coding. Or, like another answer is pointing out, in videogames.
But what I consider as bad practice is using it in production code.
For example, during debugging I want to know immediately what needs to be done in order to stop while. I don't want to search in the function for some hidden break or return.
Or the programmer can easily forget to add it there and data in a database can be affected before the code is stopped by other manners.
So ideal would be something like this:
i = 0
while(i < 100)
{
i++;
}
echo i; //this code will be reached in this scenario

wait for user input while debugging Rcpp [duplicate]

This question already has an answer here:
Getting user input from R console: Rcpp and std::cin
(1 answer)
Closed 5 years ago.
When debugging Rcpp, I usually find myself having to use old-school Rprintf statements to watch variables and program flow (as per the comment from #RomainFrancois on this answer). However, for situations such as large loops, where too much rapid output from Rprintf can quickly disappear over the top of the console, I would like to be able to pause execution until I press a key.
If I try using a std::cin.get() call in the c++ script and running it from Rstudio, the console gets stuck with no obvious way to direct keystrokes to the c++ call that is awaiting them. NB this is an RSudio specific problem - it does not occur when running the same code from a terminal window, which works as expected.
A simple reproducible example:
library(Rcpp)
cppFunction('
void test() {
for (int i = 0; i < 100; i++) {
Rprintf(\"i = %i\\n\", i);
std::cin.get();
}
}
')
test()
How can I get this to work so I can step through Rcpp functions interactively to debug them?
OK, I figured out a workaround - which is to use an R function (readline) to read user input, rather than a c++ one. I'd still like to know if there is a way for RStudio to pass input to c++ functions.
cppFunction('
void test(){
Environment base = Environment("package:base");
Function readline = base["readline"];
for (int i = 0; i < 10; i++) {
Rprintf(\"i = %i\", i);
readline("");
}
}
')
test()

Frama-C: No splitting of if-statement

I have the following problem when analyzing if-conditions with my plugin. When I analyze code like
if ((a && b) || c)
Frama-C creates code like this:
if (a) {
if (b){
goto _LOR;
}
else{
goto _LAND;
}
}
else{
_LAND: ;
if (c) {
_LOR: //....
For my analysis, I want to get the control-flow without the conditions split up, so that one statement remains. I want this, because by splitting up the conditional, the reaching of _LOR is dependent on the or-part only.
Example: creating the CFG as in the viewcfg plugin of the developer guide leads to this:
a=(a+b)+c can be reached in the then and the else-path of if a, which I cancel out in my plugin in the block-statement (so that after a "simple" if, the statement is not dependent on the condition anymore).
Is there a possibility to block the splitting of the if, by a command-line argument or something like that?
An undocumented and unsupported solution exists. Before compiling Frama-C, in function initCIL of cil.ml, change
theMachine.useLogicalOperators <- false (* do not use lazy LAND and LOR *);
into
theMachine.useLogicalOperators <- true;
The normalization will use logical || and && operators instead of gotos.
Please note that this is unsupported for a good reason. The Frama-C plugins packaged with the kernel expect an AST in which those operators are not used, so they will probably crash or do something unsound on your program. Use at your own risk!

How to avoid nested function definitions and still use <<- operator

Suppose I have these two functions:
fInner<-function()
{
# Do some complicated stuff, and...
I<<-I+1
}
fOuter<-function()
{
I<-0
fInner()
print(I)
}
Calling fOuter() produces an error: Error in fInner() : object 'I' not found. I know, that one way of fixing it is to re-write the example into
fOuter<-function()
{
fInner<-function()
{
I<<-I+1
}
I<-0
fInner()
print(I)
}
But what if I don't want to nest the functions that way? In my case fInner is a very heavy and complicated function (which I might want to move into my library), and fOuter is really an ad-hoc created function that defines one iterator. I will have many fOuter-class functions in my code, so nesting them will require duplicating the fInner inside every single little one iterator definition.
I suspect the solution has something to do with environments, but I don't know how to do it. Can anyone help?
You need access to the environment associated with the fOuter function--where the call to fInner is. You can get this with parent.frame, and you can get and set variables with get and assign:
fInner<-function()
{
assign("I", get("I", envir=parent.frame()) + 1, envir=parent.frame())
}
fOuter<-function()
{
I<-0
fInner()
print(I)
}
See ?environment and ?parent.frame for more info.
But this is just to satisfy your curiosity! You seem to agree that this is not a good idea. Manipulating environments and names can quickly get complicated, and unless you're doing something truly complex, there's probably a better way.

R Script - How to Continue Code Execution on Error

I have written an R script which includes a loop that retrieves external (web) data. The format of the data are most of the time the same, however sometimes the format changes in an unpredictable way and my loop is crashing (stops running).
Is there a way to continue code execution regardless the error? I am looking for something similar to "On error Resume Next" from VBA.
Thank you in advance.
Use try or tryCatch.
for(i in something)
{
res <- try(expression_to_get_data)
if(inherits(res, "try-error"))
{
#error handling code, maybe just skip this iteration using
next
}
#rest of iteration for case of no error
}
The modern way to do this uses purrr::possibly.
First, write a function that gets your data, get_data().
Then modify the function to return a default value in the case of an error.
get_data2 <- possibly(get_data, otherwise = NA)
Now call the modified function in the loop.
for(i in something) {
res <- get_data2(i)
}
You can use try:
# a has not been defined
for(i in 1:3)
{
if(i==2) try(print(a),silent=TRUE)
else print(i)
}
How about these solutions on this related question :
Is there a way to `source()` and continue after an error?
Either parse(file = "script.R") followed by a loop'd try(eval()) on each expression in the result.
Or the evaluate package.
If all you need to do is a small piece of clean up, then on.exit() may be the simplest option. It will execute the expression "when the current function exits (either naturally or as the result of an error)" (documentation here).
For example, the following will delete my_large_dataframe regardless of whether output_to_save gets created.
on.exit(rm("my_large_dataframe"))
my_large_dataframe = function_that_does_not_error()
output_to_save = function_that_does_error(my_large_dataframe)

Resources