Na programação embutida, as exceções tradicionalmente não eram permitidas, porque a sobrecarga do desenrolar da pilha que você precisa fazer era considerada uma variação inaceitável ao tentar manter o desempenho em tempo real. Embora smartphones possam tecnicamente ser considerados plataformas em tempo real, eles são poderosos o suficiente agora, onde as antigas limitações dos sistemas embarcados não se aplicam mais. Eu apenas trago isso por uma questão de meticulosidade.
As exceções geralmente são suportadas em linguagens de programação funcionais, mas tão raramente usadas que podem não ser. Um motivo é a avaliação lenta, que é feita ocasionalmente, mesmo em idiomas que não são preguiçosos por padrão. Ter uma função que é executada com uma pilha diferente do local em que ela foi enfileirada para executar dificulta determinar onde colocar seu manipulador de exceções.
O outro motivo é que as funções de primeira classe permitem construções como opções e futuros que oferecem a você os benefícios sintáticos das exceções com mais flexibilidade. Em outras palavras, o restante da linguagem é expressivo o suficiente para que as exceções não lhe comprem nada.
Não estou familiarizado com o Swift, mas o pouco que li sobre seu tratamento de erros sugere que eles pretendiam que o tratamento de erros seguisse padrões mais funcionais. Eu vi exemplos de código com success
e failure
blocos que se parecem muito com futuros.
Veja um exemplo usando um Future
de este tutorial do Scala :
val f: Future[List[String]] = future {
session.getRecentPosts
}
f onFailure {
case t => println("An error has occured: " + t.getMessage)
}
f onSuccess {
case posts => for (post <- posts) println(post)
}
Você pode ver que tem aproximadamente a mesma estrutura do seu exemplo usando exceções. O bloco future
é como um try
. O bloco onFailure
é como um manipulador de exceções. No Scala, como nas linguagens mais funcionais, Future
é implementado completamente usando a própria linguagem. Não requer nenhuma sintaxe especial como as exceções. Isso significa que você pode definir suas próprias construções semelhantes. Talvez adicione um bloco timeout
, por exemplo, ou a funcionalidade de registro.
Além disso, você pode passar o futuro, devolvê-lo da função, armazená-lo em uma estrutura de dados ou qualquer outra coisa. É um valor de primeira classe. Você não está limitado como exceções que devem ser propagadas diretamente na pilha.
As opções resolvem o problema de tratamento de erros de uma maneira ligeiramente diferente, o que funciona melhor em alguns casos de uso. Você não está preso apenas com o método.
Esse é o tipo de coisa que você "ganha ao perder exceções".