@Albert_Zevelev (Albert Zevelev) posted a new topic, subject "Try/Catch shortcut". It read:

   Clarification:  
    I'm looking for something similar to: `condition ? a : b`  
    Except, my condition is when `a` returns some type of error, then do `b` instead of `a`.
    [code] 
        AZ(x)= try; sqrt(x); catch e; return sqrt(complex(x)); end
        AZ(2), AZ(-2)
        
        #I want
        AZ(a,b)= try; a; catch e; return b; end
        AZ(sqrt(-2), sqrt(complex(-2)))
        
    [/code]

To which @systems (Ali) replied

    `x = try sqrt(-1); catch e; 0 ; end`
    
    x is now = 0

So @Albert_Zevelev (Albert Zevelev) replied

    I want a function `AZ(a,b)` which first does `a` and if there is an error doing `a`, then does `b`.

So @systems (Ali) replied

    [code]
        AZ( a, b) = try sqrt(a) catch; sqrt(b) end 
        AZ(-1,4)
        
    [/code]

Then @johnmyleswhite (John Myles White) said

    No such function can ever exist in general because functions evaluate all of their arguments, but you want control flow (like the ternary operator provides), so you need to write a macro. Maybe something like the following:
    [code] 
        macro trycatch(a, b)
            quote
                try
                    tmp = $(esc(a))
                    tmp
                catch
                    $(esc(b))
                end
            end
        end
        
        let x = 2
            @trycatch(sqrt(x), sqrt(complex(x)))
        end
        
        let x = -2
            @trycatch(sqrt(x), sqrt(complex(x)))
        end
        
    [/code]

Then @Albert_Zevelev (Albert Zevelev) said

    Thanks! Do you know where `a?b:c` is in the Julia source code?
    
    Currently I've been programming an mle solver where loglik returns `-Inf` for illegal parameters:
    [code] 
            ll(θ;dist=dist,data=data) = try
                -sum(logpdf.(dist{Float64}(θ...),data))
            catch e
                return Inf
            end
        
    [/code]
    
    I'd prefer an operator like `a?$`:  
    `ll(θ;dist=dist,data=data)= -sum(logpdf.(dist{Float64}(θ...),data)) @?$ Inf `

So @johnmyleswhite (John Myles White) replied

    What do you mean by that? That's part of Julia's syntax: it's in the parser and isn't a function whose definition you could read. You could write a macro to reuse that syntax for your own needs if you wanted to.

So @systems (Ali) replied

    Also this might be interesting
    [code] 
        tryesce(a, b) =
            for i in b 
                tmp = nothing 
                try
                    tmp = a(i)
                catch
                end
                tmp === nothing ? continue : return tmp  
            end
        
        tryesce(sqrt, [-1,-2,4])
        
    [/code]

@Albert_Zevelev (Albert Zevelev) replied

    To followup w/ the above example (which works great!):
    [code] 
        macro trycatch(a, b)
            quote
                try
                    tmp = $(esc(a))
                    tmp
                catch
                    $(esc(b))
                end
            end
        end
        #
        f1(x)=@trycatch(sqrt(x), sqrt(complex(x)))
        f1(2), f1(-2)
        
    [/code]
    
    is it possible to rewrite: `@trycatch(f(x), g(x))`  
    with my own `@$@` as follows: `f(x) @$@ g(x)`  
    I wasn't able to find this in the macro docs.

To which @simeonschaub (Simeon Schaub) replied

    No, there's no such thing as infix macros in Julia, unfortunately.

To which @Albert_Zevelev (Albert Zevelev) replied

    But then how do they allow: `cond ? a : b ` same as `ifelse(cond,a,b)`?

To which @simeonschaub (Simeon Schaub) replied

    They are not the same thing:
    [code] 
        julia> true ? println("foo") : println("bar")
        foo
        
        julia> ifelse(true, println("foo"), println("bar"))
        foo
        bar
        
    [/code]

After which, @simeonschaub (Simeon Schaub) added

    Also note that the ternary operator is a language feature, not a macro. Therefore, it also can't be redefined by the user.

To which @Albert_Zevelev (Albert Zevelev) replied

    So bottom line if I have some function:  
    `add(a,b)` I cannot rewrite it as `a @$@ b`

So @simeonschaub (Simeon Schaub) replied

    Functions are very different from macros. You can redefine infix operators, because they are just generic functions. Functions can't transform syntax though. For example, you can define the infix operator `$`:
    [code] 
        julia> a $ b = 10 * a + b
        $ (generic function with 1 method)
        
        julia> 1 $ 2
        12
        
    [/code]

To which @johnmyleswhite (John Myles White) replied

    I think you're getting fixated on macro being an infix operator, which isn't possible but shouldn't matter that much. You can easily do something like `@t a $ b`.


{'source': 'discourse', 'url': 'https://discourse.julialang.org/t/try-catch-shortcut/48271', 'title': 'Try/Catch shortcut', 'views': 412, 'has_accepted_answer': False, 'word_count': 562, 'like_count': 19, 'reply_count': 12, 'participant_count': 4, 'posts': 16, 'tags': 'error', 'author': '@Albert_Zevelev (Albert Zevelev)', 'participants': '@Albert_Zevelev (Albert Zevelev), @systems (Ali), @johnmyleswhite (John Myles White), @simeonschaub (Simeon Schaub)', 'image_url': [None], 'created_at': '2020-10-13T02:03:15.594Z', 'last_posted_at': '2020-10-13T17:00:31.179Z'}