Usage of catch_backtrace - julia

Recently, I found that catch_backtrace only works when it is called immediately after catch. Is it the intended behaviour? Am I using the backtrace correctly?
try
div(1,0)
catch e
bt = catch_backtrace()
showerror(STDOUT, e, bt)
end
DivideError: integer division error
in div at ./int.jl:79
in include_string at loading.jl:266
in execute_request_0x535c5df2 at /usr/local/share/julia/site/v0.4/IJulia/src/execute_request.jl:177
in eventloop at /usr/local/share/julia/site/v0.4/IJulia/src/IJulia.jl:141
in anonymous at task.jl:447
try
div(1,0)
catch e
println(3)
bt = catch_backtrace()
showerror(STDOUT, e, bt)
end
3
DivideError: integer division error

This seems to be isolated to IJulia. I can't reproduce on the REPL, and I have used catch_backtrace() several times (after other calls) in scripts.

Related

How can I fix the error Stackoverflow in julia

I write some code below and it works correctly.
function value_counter(data, feature_name)
feature_col = unique(data, feature_name)
unique_val = unique!(unique(data, feature_name))
count_val = []
value_counts_dict = Dict()
for val in unique_val
counter = 0
for col_val in feature_col
if val == col_val
counter += 1
end
end
append!(count_val, counter)
value_counts_dict[val] = counter
end
return value_counts_dict
end
But when I run it over three times. It appears a bug 'Stackoverflow' and I think the error from the unique method. How can I free the stack after running the code?
Update: I try to redefine unique method. It is still errors but this time it's in 'in' method
ERROR: LoadError: StackOverflowError:
Stacktrace:
[1] in(x::SubString{String}, itr::Vector{Any})
# Base .\operators.jl:1283
[2] redefine_unique(data::Vector{Any})
# Main E:\Study\3_grade\Csttnt\Project03_decision_tree\Decision_Tree.jl:35
It's probably not the in method or unique method itself that's causing the stack overflow. Rather, you have some large, probably recursive, stack that just happens to hit the stack size limit when it gets to that downstream function. What you should look for in the stack is where the recursive part is. What functions are being called repeatedly? You may be missing a base case somewhere, or perhaps introduced unexpected recursion into an overwritten Base function, as Sundar mentioned.

How can I make a retry function tail recursive?

I have a discriminated union that is similar to the Result type used in Scott's Railway Oriented Programming. For simplicity's sake, it's slightly simplified here:
type ErrorMessage = ErrorMessage of string
type ValidationResult<'a> =
| Success of 'a
| Error of ErrorMessage
I have a corresponding module ValidationResult that contains functions that act on these ValidationResults, one of them is a recursive retryable function that allows the parameter, f: unit -> 'a, to be called again (such as reading from stdin) if the ValidationResult is Error:
module ValidationResult
let doubleMap success error = function
| Success x -> success x
| Error e -> error e
let rec retryable errorHandler f =
let result = f ()
let retry e =
errorHandler e
retryable errorHandler f
doubleMap id retry result
But it isn't tail recursive and I would like to convert it to be so. How can I do that?
The F# compiler compiles tail-recursive functions in two different ways.
If the function is simple (calls itself directly), then it is compiled into a loop
If the tail-recursion involves multiple different functions (or even function values), then the compiler uses the .tail IL instruction to do a tail-call. This is also a tail-call, but handled by the .NET runtime rather than eliminated by the F# compiler.
In your case, the retryable function is already tail-recursive, but it is the second kind. Daniel's answer makes it simple enough so that it becomes the first kind.
However, you can keep the function as you have it and it will be tail-recursive. The only thing to note is that the compiler does not generate the .tail instruction by default in Debug mode (as it messes up the call stack) and so you need to enable it explicitly (in project options, check "Generate tail calls").
Just removing the call to doubleMap should do it:
let rec retryable errorHandler f =
match f() with
| Success x -> x
| Error e ->
errorHandler e
retryable errorHandler f

Convert exception with bactrace to string in Julia

I have a function in Julia I want to call for a set of arguments. It might throw an exeption and i want to convert it to a string with bactrace and log it for further examination.
for i in 1:100
try
myfun(i)
catch ex
println(ex)
println(bactrace(ex)) # does not work
end
end
How can one do this in Julia?
I know it's a bit old question, but here's what I found:
Base.show_backtrace(io, bt)
shows just the backtrace, and
sprint(io->Base.show_backtrace(io, bt))
prints it into a string in case you want to log it.
Edit: error_show in the previous answer is showerror now; it seems
str = showerror(STDOUT, ex, catch_backtrace())
Source: https://groups.google.com/forum/#!topic/julia-users/S485_5jG2Nw
Update 2: In v0.5 you can just do stacktrace() and catch_stacktrace()
Although you'd have to loop through the array of stacktraces to print it AFAIK.
Source: https://docs.julialang.org/en/stable/manual/stacktraces/
A litle more searching in the code found that this kind of works. It uses a function not exported in the API so it might break in the future, but for now it prints me a stack trace.
try
function()
catch ex
Base.error_show(STDERR, ex, catch_backtrace())
end

Fortran procedure pointer points to a subroutine that does nothing

I have a code like this
:
procedure(),pointer :: p
if ()
p => job1
else
p => job2
endif
do i=1,a_big_number
call x(...)
call p(i,j,k)
enddo
The subroutine 'job1' does some work, but the subroutine 'job2' does nothing. In other words, under some circumstances, I need to finish 'x' and 'job1'. Under other circumstances, I only need to do 'x'. My question is how should I define job2. It seems simply using null() does not work. What I am doing right now is like:
subroutine job2(i,j,k)
integer,intent(in) :: i,j,k
end subroutine
However, this looks silly, and I got a lot compiling warning when I compiled the code because those arguments were not used. Is there a smarter way to do this?
You could nullify the procedure pointer in the case that there was nothing useful to do, and then test the association status prior to invoking the procedure through the pointer.
PROCEDURE(interface_that_matches_job1), POINTER :: p
IF (...) THEN
p => job1
ELSE
NULLIFY(p) ! Or p => NULL()
END IF
DO i = 1, a_big_number
CALL x(...)
IF (ASSOCIATED(p)) CALL p(i,j,k)
END DO
If your concern is really about the if statement in the loop, you could just put the if statement outside of the loop:
if (condition) then
do ii = 1, big_number
call x(...)
call p(i,j,k)
end do
else
do ii = 1, big_number
call x(...)
end do
end if
Then do some timings on this version and then on a version with the if inside the loop:
do ii = 1, big_number
call x(...)
if (condition) then
call p(i,j,k)
end if
end do
I'd rather guess that you won't see any significant difference between them, as the subroutine call in the loop may already giving you an overhead much larger as the one caused by the if statement.

Recursive objects in F#?

This snippet of F# code
let rec reformat = new EventHandler(fun _ _ ->
b.TextChanged.RemoveHandler reformat
b |> ScrollParser.rewrite_contents_of_rtb
b.TextChanged.AddHandler reformat
)
b.TextChanged.AddHandler reformat
results in the following warning:
traynote.fs(62,41): warning FS0040: This and other recursive references to the object(s) being defined will be checked for initialization-soundness at runtime through the use of a delayed reference. This is because you are defining one or more recursive objects, rather than recursive functions. This warning may be suppressed by using '#nowarn "40"' or '--nowarn:40'.
Is there a way in which the code can be rewritten to avoid this warning? Or is there no kosher way of having recursive objects in F#?
Your code is a perfectly fine way to construct a recursive object. The compiler emits a warning, because it cannot guarantee that the reference won't be accessed before it is initialized (which would cause a runtime error). However, if you know that EventHandler does not call the provided lambda function during the construction (it does not), then you can safely ignore the warning.
To give an example where the warning actually shows a problem, you can try the following code:
type Evil(f) =
let n = f()
member x.N = n + 1
let rec e = Evil(fun () ->
printfn "%d" (e:Evil).N; 1)
The Evil class takes a function in a constructor and calls it during the construction. As a result, the recursive reference in the lambda function tries to access e before it is set to a value (and you'll get a runtime error). However, especially when working with event handlers, this is not an issue (and you get the warnning when you're using recursive objects correctly).
If you want to get rid of the warning, you can rewrite the code using explicit ref values and using null, but then you'll be in the same danger of a runtime error, just without the warning and with uglier code:
let foo (evt:IEvent<_, _>) =
let eh = ref null
eh := new EventHandler(fun _ _ ->
evt.RemoveHandler(!eh) )
evt.AddHandler(!eh)

Resources