Acredito que códigos infectados por exceções sejam ruins. Imagine o seguinte código inofensivo:
public static Foo newFoo(int bar) { switch (bar) { case 1: return new FooOne(); case 2: return new FooTwo(); default: throw new IllegalArgumentException("invalid bar code: " + bar); } }
Você utiliza ele no meio da sua regra de negócio, com a maior tranquilidade. O código compila e tudo:
public static List<BazFoo> getAllBazFoo() { List<BazFoo> result = new ArrayList<>(); List<Baz> allBaz = BazDAO.getAllBaz(); for (Baz baz : allBaz) { int id = baz.getId(); int bar = baz.getBar(); Foo foo = Foo.newFoo(bar); BazFoo e = new BazFoo(id, foo); result.add(e); } return result; }
O problema é que a chamada Foo.newFoo(bar) pode lançar um IllegalArgumentException e quando isto ocorrer você não terá pista nenhuma de qual Baz está com a informação inválida.
Para tratar isto e tornar a mensagem mais útil, temos que lembrar de adicionar um try/catch no código:
public static List<BazFoo> getAllBazFoo() { List<BazFoo> result = new ArrayList<>(); List<Baz> allBaz = BazDAO.getAllBaz(); for (Baz baz : allBaz) { int id = baz.getId(); int bar = baz.getBar(); Foo foo; try { foo = Foo.newFoo(bar); } catch (IllegalArgumentException e) { throw new IllegalArgumentException("invalid baz: " + id, e); } BazFoo e = new BazFoo(id, foo); result.add(e); } return result; }
Adicione várias camadas de abstração à sua aplicação e pronto: espagueti sabor excepcional. Ao adicionar exceção em algum ponto, você terá que revisar toda a pilha de abstrações que você tem e garantir que a exceção não faça mal a ninguém e que tenha uma mensagem útil para futuras manutenções.
Haskell resolve boa parte da necessidade de exceções com retornos que simbolizam falhas, e.g. Maybe e Either, e o uso de Monad elimina a necessidade de verificar os retornos a cada passo.
Porém, ainda existem exceções em Haskell, por quê? Não consigo entender o motivo para preferir exceções ao invés de retornos especiais. Em quais situações usar exceções é melhor? Mais me parecem um goto modernizado.