[erlang-questions] dialyzer/typer and exceptions

Kostis Sagonas kostis@REDACTED
Sat Oct 2 10:36:29 CEST 2010


Daniel Goertzen wrote:
> While experimenting with dialyzer and typer, I discovered that "catch" acts
> as type inference barrier.

Not sure what you mean by "type inference barrier".

What the type inference algorithm does is to approximate the types 
(i.e., set of terms) for which a function will "succeed" (i.e., not 
raise an exception). What 'catch' does is it catches exceptions and thus 
allows functions to be used with more terms.

For example, while the function:

   foo(X) -> X + 42.

will return a value only for numbers and thus has type signature

   -spec foo(number()) -> number().

the function:

   bar() -> catch (X + 22).

will return some value for all terms, not only for numbers, so it has 
the type signature:

   -spec bar(any()) -> any().

>  As an example, gen_server:call/2 uses catch in
> its first line and the resulting inferred type signature is:
> 
> -spec call(_,_) -> any().
> 
> Is there a way to get dialyzer/typer to ignore catches and assume the
> non-exception case, or is that opening pandora's box?

The answer to your question is "of course there is such a way", but the 
question then is what exactly would this type inference be computing. 
The current one tries to model the operational semantics of Erlang, not 
those of some ideal(ized) language.

> Also, are there any other constructs that are known to confound
> dialyzer/typer?

I think confound is a very strong term here, but the answer is that 
catch is the only such construct.  What also destroys type information 
is catch-all clauses/cases.

Independently of type inference though catch is a terrible construct and 
should be avoided in modern Erlang; try-catch is a much better construct 
for various reasons and dialyzer handles this much better.

Kostis


More information about the erlang-questions mailing list