Decisão para exceções não verificadas no Scala

17

Como programador java, sempre critiquei Exceções não verificadas. Os programadores costumam usá-lo como um caminho para facilitar a codificação apenas para criar problemas posteriormente. Além disso, os programas (embora desarrumados), com exceções verificadas, são muito robustos em comparação com contrapartes não verificadas.

Surpreendentemente em Scala, não há nada chamado exceções verificadas. Todo o Java marcado e desmarcado está desmarcado no Scala.

Qual é a motivação por trás dessa decisão? Para mim, abre uma ampla gama de problemas ao usar qualquer código externo. E se por acaso a documentação for ruim, isso resultará em KILL.

Jatin
fonte
11
Como programador Java, sempre critiquei as exceções verificadas. Código desarrumado nunca é robusto.
Michael Borgwardt

Respostas:

28

As exceções verificadas são principalmente consideradas uma falha. Observe que nenhuma linguagem criada após o Java as adotou. Consulte http://www.artima.com/intv/handcuffs2.html , http://googletesting.blogspot.ru/2009/09/checked-exceptions-i-love-you-but-you.html , http: / /www.mindview.net/Etc/Discussions/CheckedExceptions etc.

Em particular, eles são incompatíveis (exceto revertendo para throws Exception).

Em Scala você tem uma opção melhor: usando tipos algébricos para valores de retorno, como Option[T], Either[Exception, T], seu próprio tipo quando você quer que o usuário casos específicos punho (por exemplo, em vez de

def foo: Int // throws FileNotFoundException, IllegalStateException

Você tem

sealed trait FooResult
case class Success(value: Int) extends FooResult
case class FileNotFound(file: File) extends FooResult
case object IllegalState extends FooResult

def foo: FooResult

agora é necessário que o consumidor lide com todos os resultados)

Para lidar com código externo que gera exceções, você tem scala.util.control.exceptionou scala.util.Try(começando com Scala 2.10).

Alexey Romanov
fonte
4
Nunca entendi a maioria das pessoas não lida com o argumento das exceções verificadas . A maioria das pessoas não são bons desenvolvedores. Garanto que a maioria dos desenvolvedores não lidará com o resultado do erro. Na verdade, try..catchparece muito mais legível do que if. Além do mais, também posso garantir que esses mesmos desenvolvedores não escrevam código que retorne resultado de erro - muito complicado no Scala - você nem pode retornar de uma função sempre que quiser (como em Pascal)
Pijusn
5
Acho que você comenta confuso e sem evidências, @Pius. No Scala, a escolha de Opção como o tipo de retorno provavelmente resultará na correspondência de padrões, e não nas instruções If . Retornando Nenhum ao invés de Alguns nesse estilo é trivial, não complexo. Desenvolvedores menos indiscutíveis podem não optar por escrever funções que retornam tipos algébricos, mas isso é uma coisa diferente. Finalmente, "você nem pode retornar de uma função sempre que quiser" - simplesmente falso.
itsbruce
7

As exceções verificadas em Java não são uma coisa tão ruim. É claro que os ADTs podem ser a melhor opção para o Scala, mas em Java, as exceções marcadas têm seu lugar e o argumento do código arrumado é apenas sem noção, não importa, quantos blogs o repetiram. Basicamente, diz que você deve ignorar com prazer condições severas e possivelmente reparáveis ​​que podem ocorrer em seu sistema, porque o sistema de tipo parafuso, um código bonito , torna seu sistema robusto automaticamente. Tal raciocínio também explica por que tantos programadores Java mover voluntariamente o seu código em XMLs (Spring, Maven, etc. eu perca a muito papel aqui embora).

O motivo da falta de exceções verificadas em Scala, fornecido por M. Odersky abaixo de http://www.scala-lang.org/old/node/8787.html, é surpreendentemente diferente e faz sentido.

O problema com exceções verificadas é melhor demonstrado pelo método map nas listas:

def map[B](f: A => B): List[B]

Como fazer anotações no mapa com @throws? Se o mapa não receber uma anotação @throws em si, presumivelmente você não poderá passar nenhuma função que possua @throws. Isso introduziria restrições e distinções complicadas para as maneiras pelas quais o mapa pode ser usado. As coisas seriam melhores se pudéssemos declarar de alguma maneira que o mapa lança todas as exceções que seu argumento de função lança. Existem alguns sistemas de efeito que podem expressar isso, mas até agora todas as notações que vi são muito pesadas.

Lukas Rytz está pesquisando sistemas de efeitos leves que podem ser usados ​​para expressar o tipo de mapa e outras funções comuns de maneira concisa e precisa. É pesquisa, por isso, atualmente, não está claro até que ponto teremos sucesso e quanto disso poderá ser colocado no Scala. Idealmente, poderemos adicioná-lo em algum momento como um sistema de tipos opcional. Mas é muito cedo para fazer previsões concretas.

Felicidades

Não tenho certeza, mas acho que as lambdas do Java 8 também estão restritas a exceções não verificadas.Os métodos na maioria das (todas?) Novas interfaces funcionais no JDK 8 ( java.util.function.*) também não declaram exceções não verificadas.

woky
fonte
2

Se você quer ganhar eficiência, precisa desistir .. precisão / controle <- Preciso de uma palavra melhor para isso.

Scala está localizado no topo, tanto quanto a abstração. Se um dos objetivos da Scala é livrar-se do código clichê irritante, um lugar óbvio para se olhar é o tratamento de exceções do Java. Se você deseja escrever um código rápido em java, continue lançando suas exceções verificadas até que elas sejam ativadas main()e efetivamente desmarcadas.

Não sei se estou entendendo exatamente o que você está perguntando, mas esse é o motivo mais óbvio na minha opinião.

Bem, eu olhei um pouco e alguém escreveu sobre a tragédia das exceções de cheques .

David Cowden
fonte