# Computation termination

Hello,

Say I run `f(g(x))` where `f` has no method for a `Nothing` data type and where `g` is defined as:

``````function g(x)
if condition on x is true
return a computed valid type for f
end
end
``````

`f`, therefore, will throw a method error if the condition isn’t met; is there a way to terminate the computation of `g` before returning `nothing` to the caller? something like this

``````function g(x)
if condition on x is true
return a computed valid type for f
end
terminate() # without returning `nothing`
end
``````

It sounds like you are looking for `exit()`.

I tried it, but terminates Julia.

As far as I know there are only two possibilities for the behavior of function `g` (outside of pathological behavior like exiting Julia or making it hang):

1. Function `g` returns a value
2. Function `g` throws an exception

(Any other behavior doesn’t make sense: if you write `y = g(x)` and you “terminate `g` before returning”, what should be the value of `y`?)

Both options can be good choices… If “condition on `x` is false” happens when `g` is called with an invalid value, it makes sense to use an exception (although exceptions are more expensive in terms of performance so sometimes you want to avoid them):

``````function g(x)
if condition on x is true
return a computed valid type for f
end
end

function f(x)
try
y = g(x)
catch
# Do something in bad case
end
end
``````

Often it is better to let `g` return `Union{Nothing, Float64}` or similar:

``````function g(x)
if condition on x is true
return a computed valid type for f
end
end

function f(x)
y = g(x)
if isnothing(y)
...
else
...
end
end
``````
2 Likes

Why is it not possible to define a method for `f`?

``````f(x::Nothing) = nothing
``````
1 Like

Throwing an exception indeed does the job; problem is, it seems a hacky solution to me, because – in my case – it is not an exception as such: it prints and ugly `Error` message and its backtrace (though the backtrace can be supressed). I am looking for a “cleaner” solution without an error message, that can be misleading for users.

Because I’m lazy and want to avoid creating a bunch of methods that seem superfluous.

BTW, this is perhaps what I’ll end up doing – in spite of my laziness.

or at least, is there a way the edit the `Error` string in the `throw` function to something less aggressive? say `Info`

I don’t think so: an uncaught exception is an error. But you can catch the expression with a `try` block, and then you can print the message you want (or do nothing).

Could you give a full, concrete example of the behavior you want?

1 Like

`f(x::Nothing) = nothing` is not superfluous, if it is the difference between `f(g(x))` being correct code or not. If you do not want the write the definition because it can be abused, and instead treat it at the call site, for many different kinds of single-argument functions, then you can define something like:

``````allow_nothing(f) = (x -> isnothing(x) ? nothing : f(x))
``````

to use at the places you call the functions. Or you can create a macro alternative that defines a method for you with similar behavior (but without the overhead of a closure) and invoke the macro for all functions (but as this is already single-line, I believe it is basically the same amount of effort).

2 Likes

My case is quite involved, so I’ll formulate something simpler.

I can catch the expression and print something but it still returns `nothing`, which `f` receives and throws the method error.

I think that the solution is what you said @sijo: throw an exception. I found a way how to suppress the backtrace that produces a clean output; I only need to figure how to change/suppress the ugly red `Error` message tag. I looked into the `throw` code but it’s quite cryptic to me (I’m still sort of a julia neophyte) so I cannot replace that pesky error tag string. At least this solution does what I’m looking for; perhaps I should be content with that.

This elides the red `Error` word:

``````Base.showerror(io::IO, e::ResponseException, bt; backtrace=true) = print(io, "\b"^7 * e.msg)
``````

Does the job, but it’s horrid! The signature of a true noob.

I’d love to see a minimal working example of the thing you’re trying to achieve. It doesn’t have to be a real-life example, but some small working code that shows the behavior you want for functions `f` and `g`.

Here it goes:

``````struct MyException <: Exception
msg::AbstractString
end

function Base.showerror(io::IO, e::MyException, bt; backtrace=true)
print(io, "\b"^7)
print(io, e.msg)
end

f(x::Real) = x^2

function h(x)
if isa(x, Real)
x
else
e = MyException("This is not an error, I just want to terminate execution.")
throw(e)
end
end

``````

Now test.

1. Valid:
``````julia> f(h(1))
1
``````
1. Invalid:
``````julia> f(h("one"))
This is not an error, I just want to terminate execution.
``````

which is what I was looking for: terminate execution to avoid a `f`’s method error.

return `nothing` is THE way to terminate execution of a function early.

If you use `return nothing` for something else, make your own signeton type and return that thing.

1 Like

Indeed, but the whole point is to avoid defining an `f(x::Nothing)` method.

Am I correct in saying you want something like R’s `stop` function.
Which terminates execution and returns to the top-level prompt without showing an big scary error message and stacktrace?

We have definitely talked about that before.
At least once,

3 Likes

I don’t know… this actually seems like a good solution for what you’re trying to do. BUT I suspect you’re trying to do something that’s wrong: calling `h` with a bad `x` value is an error and it’s wrong to pretend otherwise. If a user calls `f1` that calls `f2` that calls `f3` that calls `f` and all they get is the message `Computation interrupted (this is not an error)`, they will have a hard time finding the root of the problem.

Or maybe this `x` is not really a bad value? It’s a valid value that means “interrupt all computations”? I don’t remember seeing a real-life case where this makes sense. It sounds more like a recipe for spaghetti code: you have an inner function call that short-circuits all the caller functions as part of normal program execution (not error)? It’s like a `goto` but even worse because it’s not explicit.

To stay sane and avoid spaghetti code, when you write `f(g(x))` you normally want `g` to do its own job without interferring with the callers, and `f` should decide itself if it wants to interrupt its own computation depending on the return value of `g` (and `f` can include a `try-catch` block if it knows that `g` can throw an exception that `f` can handle itself).

(Of course maybe your thing actually does make sense and then I’d be curious to understand it better…)