lara
lara

Reputation: 874

How do I skip to a certain part of my code if I encounter an error in Julia

I have a 'wrapper function' that takes inputs and just runs a lot of functions in turn and spits out a result at the end. A simple example

function wrapper(a,b)
    c = first_function(a,b)
    d = second_function(c)
    if typeof(d) == Int64
        e = third_function(d)
        f = fourth_function(e)    
        g = fifth_function(f)
        try 
            h = sixth_function(g)
        catch
            i = "this has failed"
        end
        i = seventh_function(h)
    else i = "this has failed"
    end

    return i
end

There are about 5 different places throughout the list of functions that I want to set up 'if - else' statements or 'try - catch' statements. The 'else' part and the 'catch' part are always evaluating the same things. In this example you can see what I mean by seeing that both the else and the catch statements execute i = "this has failed".

Is there a way that I can just define i = "this has failed" at the bottom of the function's code and just tell julia to skip to this line for the 'else' or 'catch' parts ? For example I'd like my above to be something like:

function wrapper(a,b)
    c = first_function(a,b)
    d = second_function(c)
    if typeof(d) == Int64
        e = third_function(d)
        f = fourth_function(e)    
        g = fifth_function(f)
        try 
            h = sixth_function(g)
        catch
            <skip to line 10>
        end
        i = seventh_function(h)
    else <skip to line 10>
    end

    <line 10> i = "this has failed"
    return i
end

Upvotes: 1

Views: 558

Answers (4)

David P. Sanders
David P. Sanders

Reputation: 5325

Also note that you almost never want to test the type of a variable in Julia - you should handle that by multiple dispatch instead.

Upvotes: 2

Tasos Papastylianou
Tasos Papastylianou

Reputation: 22225

You got some great literal answers answering your literal question, but the real question is why do you need to do it like this in the first place? It sounds like a really bad design decision. Essentially you're reinventing the wheel, badly! You're trying to implement a "subroutine" approach as opposed to a "functional" approach; subroutines have all but disappeared decades ago, for good reason. The fact that your question essentially boils down to "GOTO for Julia" should be a really big red flag.

Why not just define another function that handles your "fail code" and just call it? You can even define the fail function inside your wrapper function; nested functions are perfectly acceptable in julia. e.g.

julia> function outer()
         function inner()
           print("Hello from inner\n");
         end
         print("Hello from outer\n");
         inner();
       end
outer (generic function with 1 method)

julia> outer()
Hello from outer
Hello from inner

So in your case you could simply define a nested handle_failure() function inside your wrapper function and call it whenever you feel like it and that's all there is to it.


PS: Preempting the typical "there are some legit uses for GOTO in modern code" comment: yes; this isn't one of them.

Upvotes: 2

Chris Rackauckas
Chris Rackauckas

Reputation: 19132

You can use the @def macro from this SO post. For example:

@def i_fail_code begin
  i = "this has failed"
end

and then you'd do:

function wrapper(a,b)
    c = first_function(a,b)
    d = second_function(c)
    if typeof(d) == Int64
        e = third_function(d)
        f = fourth_function(e)    
        g = fifth_function(f)
        try 
            h = sixth_function(g)
        catch
            @i_fail_code
        end
        i = seventh_function(h)
    else @i_fail_code
    end
    return i
end

This macro is pretty cool because even though it's essentially just copy/pasting what's in its definition it will even get the line numbers for errors correct (i.e. it will send you to the correct line in the @def definition).

Upvotes: 3

aviks
aviks

Reputation: 2097

Julia has built in goto support via macros, which may be the simplest option. So something like:

function wrapper(a,b)
    c = first_function(a,b)
    d = second_function(c)
    if typeof(d) == Int64
        e = third_function(d)
        f = fourth_function(e)    
        g = fifth_function(f)
        try 
            h = sixth_function(g)
        catch
            @goto fail
        end
        i = seventh_function(h)
    else 
        @goto fail
    end
    return i
    @label fail 
    i = "this has failed"
    return i
end

Upvotes: 2

Related Questions