Existe uma teoria das hierarquias de exceção?

18

Eu estou familiarizado com uma dúzia de linguagens de programação que têm exceções de alguma forma, mas vim testemunhar duas tendências "patológicas".

  1. Não parece haver um padrão ou hierarquia comum de exceções. Todo idioma basicamente lança sua própria versão e, se as exceções o tornarem padrão, os tipos de exceções encontrados no padrão serão bastante arbitrários (principalmente aqueles implementados durante a criação de ferramentas de linguagem, como a leitura de código-fonte em ou uma exceção para chamar o depurador, ou aquela que acontece quando o arquivo não pode ser encontrado etc.)

  2. Exceções definidas pelo idioma raramente são reutilizadas pelos programas do usuário. Geralmente, haveria uma ou duas exceções populares ("não implementar", por exemplo). Embora na maioria das vezes os programadores criem suas próprias exceções. (Compare isso com, por exemplo, a criação de novos tipos numéricos ou novos tipos de coleção).

Isso parece uma omissão terrível para mim. Como é que ninguém sabe que tipos de erros serão necessários nos programas do usuário? Eu esperava que houvesse uma espécie de hierarquia legal, semelhante a tipos numéricos, coleções, sistema de objetos etc.

Pior ainda, Goolge e Wikipedia fornecem muito pouca ajuda sobre o assunto. Até agora, encontrei apenas um artigo sobre exceção funcional que abre em uma passagem:

Este artigo argumenta que a programação funcional preguiçosa não apenas torna desnecessário o mecanismo interno de tratamento de exceções, mas fornece uma ferramenta poderosa para desenvolver e transformar programas que usam exceções

(Uma teoria funcional das exceções, Mike Spivey, 1988)

Mas acho que as exceções são boas. Não quero transformar programas que usam exceções, pelo contrário, quero tornar o uso de exceções menos caótico.

A questão:

Existe uma teoria das exceções? Se sim, como é chamado? Quais são, se houver, a pedra angular que delineia a base dela?

wvxvw
fonte
As exceções são uma invenção bastante nova, talvez com menos de 20 anos, surgindo um pouco do "longjmp" de C. eles estão principalmente conectados ao OOP. parece que o uso ideal / teoria / melhores práticas ainda estão em evolução. java tem um dos modelos mais elaborados. existem muitos "antipadrões" relacionados a exceções, como você observa. parte disso está ligada à teoria da "computação tolerante a falhas", que também parece um pouco em sua infância em geral.
vzn
Você pode considerar as exceções como um subconjunto da teoria da continuação. Vejo en.wikipedia.org/wiki/Continuation
jmite 15/10/13
Exceções e continuações são muito diferentes. Exceções se ligam dinamicamente a seus manipuladores, enquanto continuações o fazem estaticamente. Em geral, continuações por si só não podem ser usadas para implementar exceções, pelo menos na presença de tipos, consulte, por exemplo, Exceções digitadas e continuações não podem se expressar macro .
Martin Berger
"Exceções definidas pelo idioma raramente são reutilizadas pelos programas do usuário." Isto é tão verdade! Definir exceções personalizadas é muito raramente necessário. Por exemplo, python e seu stdlib definem algo como 160 exceções. As chances de que a exceção em que você está pensando não foram definidas são muito pequenas. Algumas (a maioria?) Dessas exceções não são amplamente conhecidas. Por exemplo, LookupErrorseria perfeitamente adequado para todos os contêineres personalizados, mas muitas pessoas nem sabem que ele existe.
Bakuriu 15/10
1
@jmite Mais um encontro que tive com exceções antes deste tópico ser do livro de Benjamin C. Pierce, Tipos e Linguagens de Programação. Onde ele menciona erros no contexto de definição de um tipo de função. Ou seja, do ponto de vista dele, os erros são apenas mais um valor retornado pelas funções (e, juntamente com o outro argumento, eles formam um tipo inteiro, se me permitem dizer).
Wvxvw

Respostas:

8

Há um grande número de publicações sobre exceções, com algumas investigações teóricas. Aqui está uma lista não estruturada e longe de completa, com alguns exemplos. Desculpe, não tenho tempo no momento para uma resposta mais focada.

  • B. Randell, Estrutura do sistema para tolerância a falhas de software.
  • JB Goodenough. Tratamento de exceção: problemas e uma notação proposta.
  • JB Goodenough. Manipulação de exceção estruturada.
  • BG Ryder, ML Soffa, Influences on the Design of Exception Handling.
  • D. Teller, A. Spiwack, T. Varoquaux, Pegue-me se você puder: Em direção ao gerenciamento de erros de tipo seguro, hierárquico, leve, polimórfico e eficiente no OCaml.
  • X. Leroy, F. Pessaux, análise baseada em tipo de exceções não capturadas.
  • R. Miller, A. Tripathi, Problemas com o tratamento de exceções em sistemas orientados a objetos.
  • S. Drew, KJ Gough, J. Ledermann, Implementando o Zero-Overhead Exception Handling.
  • B. Stroustrup, Exceção de Segurança: Conceitos e Técnicas.
  • D. Malayeri, J. Aldrich, Especificações práticas de exceção.
  • H. Nakano, uma formalização construtiva do mecanismo de captura e arremesso.
  • A. Nanevski, um cálculo modal para tratamento de exceções.
  • P. de Groote, Um Cálculo Simples de Tratamento de Exceções.
  • H. Thielecke, Sobre exceções e continuações na presença de estado.
  • JG Riecke, H. Thielecke, exceções digitadas e continuações não podem se expressar macro.
  • M. van Dooren, E. Steegmans, Combinando a robustez de exceções verificadas com a flexibilidade de exceções não verificadas usando declarações de exceção ancoradas.
  • JA Vaughan, uma interpretação lógica de exceções no estilo Java.
  • S. Marlow, S. Peyton Jones, A. Moran, Exceções assíncronas em Haskell.
  • B. Jacobs, F. Piessens, Failboxes: Manuseio de exceções comprovadamente seguro.
Martin Berger
fonte
Uau, muito obrigado! Levarei alguns meses (se não mais) para voltar com a resposta positiva :) Agora estou dividido entre alguns livros sem saber por onde começar!
wvxvw
2
Muitos desses documentos são sobre a implementação ou modelagem de exceções em linguagens de programação, e não sobre como projetar hierarquias de exceção. Você poderia cortar a lista para os documentos relevantes?
Gilles 'SO- stop be evil'
@Gilles A pergunta original não era clara. Eu acho que o que conta como exceções apropriadas depende principalmente do aplicativo. O único problema teórico real com exceções é a troca entre (1) acoplamento de módulos não relacionados por meio de exceções (é por isso que nenhuma linguagem após Java possui especificações de exceção obrigatórias), (2) dando ao usuário de um módulo alguma indicação de quais tipos de erros esperar e (3) ajuda do compilador no tratamento de erros. Até onde eu vejo, ainda não foi encontrada uma solução realmente convincente para esse enigma.
22813 Martin Berger
6

Não sei se existe ou não uma teoria, mas pode haver uma ciência experimental pragmática emergente.

A melhor fonte em que consigo pensar é Bjarne Stroustrup, The Design and Evolution of C ++, Addison-Wesley, 1994 . Se bem me lembro (é um livro muito bom e as pessoas continuam me emprestando e não o devolvendo, então não tenho uma cópia no momento), há um capítulo sobre exceções. O comitê C ++ no Stroustrup exigiu muitas evidências empíricas de que um recurso proposto era necessário antes que eles desejassem adicioná-lo à definição de linguagem. A página da Wikipedia sobre exceções tem a seguinte citação desse livro:

Na reunião de Palo Alto [padronização do C ++] em novembro de 1991, ouvimos um resumo brilhante dos argumentos para a semântica de terminação, apoiados tanto pela experiência pessoal quanto pelos dados de Jim Mitchell (da Sun, anteriormente da Xerox PARC). Jim utilizou o tratamento de exceções em meia dúzia de idiomas durante um período de 20 anos e foi um dos primeiros defensores da semântica da retomada como um dos principais designers e implementadores do sistema Cedar / Mesa da Xerox. Sua mensagem foi de encerramento é preferível à retomada; isso não é uma questão de opinião, mas uma questão de anos de experiência. O reinício é sedutor, mas não é válido. Ele apoiou essa declaração com experiência em vários sistemas operacionais. O exemplo principal foi Cedar / Mesa: foi escrito por pessoas que gostaram e usaram a retomada, mas após dez anos de uso, restava apenas um uso de retomada no sistema de meio milhão de linhas - e isso era uma investigação de contexto. Como a retomada não era realmente necessária para uma consulta de contexto, eles a removeram e encontraram um aumento significativo da velocidade nessa parte do sistema. Em todos os casos em que a retomada havia sido usada, ela se tornou um problema ao longo dos dez anos e um design mais apropriado a substituiu. Basicamente, todo uso de retomada representou uma falha em manter níveis separados de abstração separados. Em todos os casos em que a retomada havia sido usada, ela se tornou um problema ao longo dos dez anos e um design mais apropriado a substituiu. Basicamente, todo uso de retomada representou uma falha em manter níveis separados de abstração separados. Em todos os casos em que a retomada havia sido usada, ela se tornou um problema ao longo dos dez anos e um design mais apropriado a substituiu. Basicamente, todo uso de retomada representou uma falha em manter níveis separados de abstração separados.

No C ++, a vitória real é o RAII , o que facilita muito o tratamento da desalocação de recursos durante erros. (Não elimina a necessidade de throwe try- catch, mas significa que você não precisa finally.)

Acho que o que os convenceu de que precisavam de exceções são os contêineres genéricos: o gravador de contêineres não sabe nada sobre os tipos de erros que os objetos contidos podem precisar retornar (muito menos como lidar com eles), mas o código que inseriu esses objetos no diretório O container deve saber algo sobre o que é a interface desses objetos. Mas como não sabemos nada sobre que tipos de erros os objetos contidos podem gerar, não podemos padronizar os tipos de exceção. (Contrapositivamente: se pudéssemos padronizar os tipos de exceção, não precisaríamos de exceções.)

A outra coisa que as pessoas parecem ter aprendido ao longo dos anos é que é difícil colocar corretamente as especificações de exceção em um idioma. Veja, por exemplo, o seguinte: http://www.gotw.ca/publications/mill22.htm , ou isto: http://www.gotw.ca/gotw/082.htm . (E não é apenas C ++, os programadores Java também têm argumentos longos sobre suas experiências, com exceções verificadas versus não verificadas .)

Um pouco sobre a história das exceções. O artigo clássico é: John B. Goodenough: "Tratamento de exceções: questões e uma notação proposta", Commun. ACM 18 (12): 683-696, 1975. Mas exceções eram conhecidas antes disso. Mesa os possuía em 1974, e PL / I também os possuía. Ada tinha um mecanismo de exceção antes de 1980. Acredito que as exceções do C ++ foram mais influenciadas pela experiência com a linguagem de programação CLU de Barbara Liskov, de cerca de 1976. Barbara Liskov: "Uma história da CLU", em História das linguagens de programação --- II , Thomas J. Bergin, Jr. e Richard G. Gibson, Jr. (Eds.). 471-510, ACM, 1996 .

Lógica Errante
fonte
Isso é interessante e terei que pesquisar mais para responder melhor. Mas até o momento: eu sei que existe uma objeção muito forte ao uso de exceções em C ++ (talvez uma anedota, mas as convenções de codificação do Google são usadas para proibir o uso de exceções). As exceções verificadas em Java são certamente um experimento único e, portanto, interessante, mas o recurso ganhou tantos créditos ruins ao longo de sua história ... muitas pessoas simplesmente as repetem novamente em tempo de execução (embora isso possa estar relacionado apenas à sintaxe).
Wdxvw #
Estou mais familiarizado com a classificação de exceções do Common Lisp, onde eles tentaram (embora com pouco sucesso) dividi-las de acordo com o nível de ameaça que representam para programar. por exemplo, serious-conditionvs simple-condition. Agora também estou lendo JL Austing, onde ele classifica erros (não relacionados à programação) em grupos com base em como o sistema falhou ao executar a tarefa (por exemplo, peças impróprias usadas versus intenções não sinceras). O que não é imediatamente aplicável à programação, mas pode ocorrer após algum refinamento.
Wvxvw 15/10
@Wandering Logic Eu vomitei porque você explicou por que os excpetios de C ++ são sux e que a inclusão instruída de recursos pode destruir a linguagem.
Val
@wvxvw A very strong objectionexceção contra no C ++ vem de dois fatos: não há finallyconstrução e ninguém mais usa exceções. O primeiro problema também agrava o segundo. Ou seja, quando você não possui finally, não pode fechar o recurso quando a exceção ocorre. Como ninguém usa exceções, todas as funções / APIs as evitam, você deve investir muito na reconstrução de toda a infraestrutura C ++ tradicional, agrupando todas as funções com suas exceções para começar a obter benefícios delas em seu código. Mas a falta de finallytorna essa abordagem impossível também.
Val
@wvxvw: as convenções do Google proíbem a criação de exceções nos limites do módulo (.so). Isso ocorre porque as exceções no C ++ usam informações de tipo em tempo de execução (RTTI) e o Linux não fez um bom trabalho ao implementar a digitação em tempo de execução. No Linux, você só pode transmitir tipos de tempo de execução de maneira confiável entre os módulos se compilou os módulos com a mesma versão do mesmo compilador e vinculou-se à versão idêntica do libstdc ++. Realmente, essa é uma rejeição do C ++ em geral pela comunidade Linux, não uma rejeição de exceções especificamente.
Wandering Logic
3

Permitam-me apenas salientar que as exceções são um caso de efeito computacional . Outros efeitos computacionais são estado mutável, E / S, não determinismo, continuações e muitos outros. Portanto, sua pergunta pode ser feita de maneira mais geral: como formamos hierarquias de efeitos computacionais, como organizamos e por que temos os que temos, e não outros, etc.

Andrej Bauer
fonte
1
Eu acho que isso é completamente irrelevante. A questão não é modelar a noção de exceções, mas sim mapear para erros - acho que a maneira correta de descrevê-la da perspectiva do PLT seria uma teoria das hierarquias de exceção.
Gilles 'SO- stop be evil'
Hmm, você está certo. Corrigi a resposta para apontar isso, mas acho que não há necessidade de excluí-lo. O que você acha?
Andrej Bauer