Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

`catch` should be it's own macro #594

Closed
devinus opened this Issue · 7 comments

2 participants

@devinus

So that I can do an inline catch like in Erlang:

case catch foo() do
end

bar = catch bar()
@josevalim
Owner

I never understood the benefit of those over the usual try/catch approach. Can you provide an example?

In any case, if we decided to add this, it could be done as a catch! macro (catch on its own is taken).

@devinus

@josevalim Sure, an example from some Erlang code:

        Rpc = case catch zuul_salieri_json:to_term(Body) of
            {'EXIT', _} ->
                throw(parse_error);
            {incomplete, _} ->
                throw(parse_error);
            Term ->
                #rpc{
                    jsonrpc = ?get(jsonrpc, Term),
                    id = ?get(id, Term),
                    method = ?get(method, Term),
                    params = ?get(params, Term)
                }
        end,
@josevalim
Owner

Yeah, this example does not convince me though. :) It does not add much over try/catch (see below) and catch! has the downside of catching everything, so it is an idiom I would avoid.

try do
  :zuul_salieri_json.to_term(body)
catch
  { :incomplete, _ } ->
    throw(:parse_error)
  term ->
    RPC[
      jsonrpc: get(:jsonrpc, term),
      id: get(:id, term),
      method: get(:method, term),
      params: = get(:params, term)
    ]
  _, _ ->
    throw(:parse_error)
end

My general impression is that catch is a mechanism added in Erlang but it was super seeded by try/catch in later Erlang releases.

@devinus

@josevalim uhh the point is to catch everything! It's easier than:

bar = try do
  foo()
catch
  anything -> anything
end

# when you should be able to just do:
bar = catch! foo()

Also the first one doesn't even capture what was caught.

@josevalim
Owner

@devinus except that you never do as you did above, right? You always end up matching against the returned value to extract information, so you end up with case + catch which is similar to try. And yes, sometimes you may want to catch everything, but those cases are rather rare. For example, do you really care about catching exits in :zuul_salieri_json.to_term(body)? Is there a chance it could hide potential bugs?

@devinus

@josevalim In your example, the incomplete is not thrown, it is potentially returned by to_json. You cannot catch it. This example doesn't work. You'd need a case clause in the try block as well, making the code more complicated.

@josevalim
Owner

@devinus good point. this is actually another annoyance i have with catch!, because it mixes returned with thrown results. In any case, it is easy to restructure that example to either call a local function to handle the result or to handle it later in case. catch Expr muddies too many concerns in my opinion which makes it rarely worth to use. :S

@josevalim josevalim closed this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.