예외 계층 구조 이론이 있습니까?


18

나는 어떤 방식 으로든 예외가있는 십여 개의 프로그래밍 언어에 익숙하지만, 두 가지 "병리학 적"경향을 목격하게되었습니다.

  1. 일반적인 패턴이나 예외 계층 구조는없는 것 같습니다. 모든 언어는 기본적으로 자체 버전을 롤링하고 예외가 표준으로 만들어지면 표준에서 찾은 예외 종류는 다소 임의적입니다 (대개 소스 코드를 읽는 것과 같은 언어 도구를 만드는 동안 구현 된 예외) 디버거를 호출하는 문자열 또는 예외 또는 파일을 찾을 수 없을 때 발생하는 예외)

  2. 언어로 정의 된 예외는 사용자 프로그램에서 거의 재사용하지 않습니다. 일반적으로 하나 또는 두 개의 일반적인 예외가 있습니다 (예 : "구현하지 않음"). 대부분의 경우 프로그래머는 자신의 예외를 만듭니다. (예를 들어, 새 숫자 유형 또는 새 콜렉션 유형 작성과 비교하십시오).

이것은 나에게 끔찍한 누락처럼 보입니다. 사용자 프로그램에 어떤 종류의 오류가 필요한지 어떻게 알 수 있습니까? 숫자 유형, 컬렉션, 객체 시스템 등과 비슷한 멋진 계층 구조가 있기를 바랐습니다.

게다가 Goolge와 Wikipedia는이 주제에 대해 거의 도움이되지 않습니다. 지금까지 나는 구절에서 열리는 기능적 예외에 대한 논문 만 찾았습니다.

이 백서는 게으른 기능적 프로그래밍이 내장 예외 처리 메커니즘을 불필요하게 만들뿐만 아니라 예외를 사용하는 프로그램을 개발하고 변형하기위한 강력한 도구를 제공한다고 주장합니다.

(예외의 기능 이론, Mike Spivey, 1988)

그러나 나는 예외가 좋다고 생각합니다. 예외를 사용하는 프로그램을 변환하고 싶지는 않지만 예외 사용을 덜 혼란스럽게 만들고 싶습니다.

질문:

예외 이론이 있습니까? 그렇다면 무엇이라고합니까? 모퉁잇돌의 기초가되는 초석은 무엇입니까?


예외는 C의 "longjmp"에서 다소 발생하여 20 세 미만의 다소 새로운 발명품입니다. 그들은 대부분 OOP에 연결되어 있습니다. 이상적인 사용법 / 이론 / 모범 사례가 여전히 진화하고있는 것 같습니다. java는보다 정교한 모델 중 하나를 가지고 있습니다. 참고로 예외와 관련된 많은 "반 패턴"이 있습니다. 이 중 일부는 "내결함성 컴퓨팅 (fault tolerant computing)"이론과 관련이 있으며, 이는 전반적으로 초기 단계에 다소있는 것으로 보입니다.
vzn

연속 이론의 일부를 예외로 간주 할 수 있습니다. 참조 en.wikipedia.org/wiki/Continuation
jmite

@jmite 예외와 연속은 매우 다릅니다. 예외는 처리기에 동적으로 바인딩되지만 연속은 정적으로 수행됩니다. 일반적으로, 적어도 유형이 존재하는 경우에는 자체적으로 연속을 사용하여 예외를 구현할 수 없습니다 (예 : 유형이 지정된 예외 및 연속이 서로 매크로 표현할 수없는 경우 참조) .
Martin Berger

"언어에 의해 정의 된 예외는 사용자 프로그램에 의해 거의 재사용되지 않습니다." 이건 정말 진실! 사용자 정의 예외를 정의하는 것은 거의 필요하지 않습니다. 예를 들어 python과 stdlib는 160 개의 예외를 정의합니다. 당신이 생각하는 예외가 정의되지 않았을 가능성은 매우 작습니다. 이러한 예외 중 일부 (대부분?)는 널리 알려져 있지 않습니다. 예를 들어 모든 사용자 정의 컨테이너에 LookupError완벽하게 적합 하지만 많은 사람들이 해당 컨테이너가 존재한다는 것을 알지 못합니다.
Bakuriu

1
@jmite Benjamin C. Pierce의 저서 Types and Programming Languages에서이 주제를 제외하고 한 가지 더 예외가 발생했습니다. 그는 함수 유형을 정의하는 맥락에서 오류를 언급합니다. 즉, 그의 관점에서 볼 때 오류는 함수에서 반환 된 또 다른 값입니다 (그리고 다른 인수와 함께 전체 유형을 형성하면 허용됩니다).
wvxvw 2013 년

답변:


8

몇 가지 이론적 조사와 함께 예외에 관한 많은 출판물이 있습니다. 다음은 몇 가지 예를 포함하는 구조화되지 않은 완전한 목록입니다. 죄송합니다. 현재 더 집중된 답변을 드릴 시간이 없습니다.

  • B. Randell, 소프트웨어 결함 허용 시스템 구조.
  • JB Goodenough. 예외 처리 : 문제 및 제안 된 표기법.
  • JB Goodenough. 구조적 예외 처리
  • BG Ryder, ML Soffa는 예외 처리 설계에 영향을 미칩니다.
  • D. Teller, A. Spiwack, T. Varoquaux, 가능한 경우 알려주세요 : OCaml의 유형 안전, 계층 적, 경량, 다형성 및 효율적인 오류 관리
  • X. Leroy, F. Pessaux, 포착되지 않은 예외에 대한 유형 기반 분석.
  • R. Miller, A. Tripathi, 객체 지향 시스템의 예외 처리 관련 문제
  • S. Drew, KJ Gough, J. Ledermann, 제로 오버 헤드 예외 처리 구현.
  • B. Stroustrup, 예외 안전 : 개념 및 기법.
  • D. Malayeri, J. Aldrich, 실제 예외 사양.
  • H. Nakano, 포획 및 던지기 메커니즘의 건설적인 형식화.
  • A. Nanevski, 예외 처리를위한 모달 미적분학.
  • P. de Groote, 예외 처리의 간단한 미적분학.
  • H. Thielecke, 국가 현존 예외 및 지속에 관한.
  • JG Riecke, H. Thielecke, 유형별 예외 및 연속은 서로 매크로 표현할 수 없습니다.
  • M. van Dooren, E. Steegmans, 확인 된 예외의 견고성과 고정 된 예외 선언을 사용하여 확인되지 않은 예외의 유연성을 결합한 것.
  • JA Vaughan, Java 스타일 예외에 대한 논리적 해석.
  • S. Marlow, S. Peyton Jones, A. Moran, Haskell의 비동기 예외.
  • B. Jacobs, F. Piessens, Failboxes : 안전한 예외 처리.

와, 고마워요! 긍정적 인 답변으로 돌아 오는 데 몇 달이 걸리지 않을 것입니다. :) 이제 어디에서 시작할지 모르는 몇 권의 책 사이가 찢어졌습니다!
wvxvw

2
이 백서 중 다수는 예외 계층을 디자인하는 방법이 아니라 프로그래밍 언어로 예외를 구현하거나 모델링하는 것에 관한 것입니다. 관련 논문으로 목록을 정리할 수 있습니까?
Gilles 'SO- 악마 그만해

@Gilles 원래 질문은 약간 불분명했습니다. 적절한 예외로 간주되는 것은 주로 응용 프로그램에 달려 있다고 생각합니다. 예외에 대한 유일한 실제 이론적 문제는 (1) 예외를 통해 관련되지 않은 모듈을 결합하는 것 (Java가 필수 예외 사양을 가진 언어가없는 이유), (2) 모듈 사용자에게 어떤 종류의 오류가 발생할지를 알려주는 것입니다. 및 (3) 컴파일러가 오류 처리에 도움을줍니다. 내가 알 수있는 한,이 수수께끼에 대한 확실한 설득력있는 해결책은 아직 발견되지 않았습니다.
Martin Berger

6

나는 이론이 있는지 없는지 모르겠지만, 실용적으로 실험적인 과학이 생길 수도있다.

내가 생각할 수있는 최고의 소스는 Bjarne Stroustrup, C ++의 디자인과 진화, Addison-Wesley, 1994 입니다. 내가 올바르게 기억한다면 (매우 훌륭한 책이고 사람들이 저에게서 계속 빌려 와서 돌려주지 않기 때문에 현재 사본이 없습니다) 예외에 관한 장이 있습니다. Stroustrup의 C ++위원회는 언어 정의에 기꺼이 추가하기 전에 제안 된 기능이 필요하다는 많은 경험적 증거가 필요했습니다. 예외에 대한 위키 백과 페이지는 책에서 다음 인용문이있다 :

1991 년 11 월 Palo Alto [C ++ 표준화] 회의에서, 우리는 개인 경험과 Jim Mitchell (Sun, 이전에는 Xerox PARC)의 데이터로 뒷받침 된 종료 의미론에 대한 훌륭한 요약을 들었습니다. Jim은 20 년 동안 24 개 언어로 예외 처리를 사용했으며 Xerox의 Cedar / Mesa 시스템의 주요 설계자 및 구현 자 중 하나로서 재개 의미론의 초기 제안자였습니다. 그의 메시지는 재개보다 우선하는 것이 낫다. 이것은 의견의 문제가 아니라 수년간의 경험의 문제입니다. 재개는 유혹적이지만 유효하지 않습니다. 그는 여러 운영 체제의 경험을 바탕으로이 진술을 뒷받침했습니다. 주요 예는 시더 / 메사 (Cedar / Mesa)였습니다. 50 만 라인 시스템에는 재개 사용이 한 번만 있었으며 이는 상황에 대한 문의였습니다. 이러한 상황 문의에는 재개가 실제로 필요하지 않았기 때문에이를 제거하고 시스템의 해당 부분에서 상당한 속도 증가를 발견했습니다. 재개가 사용 된 모든 경우에 10 년에 걸쳐 문제가되었고보다 적절한 디자인으로 대체되었습니다. 기본적으로, 재개를 사용할 때마다 별도의 추상화 수준을 분리하지 않은 것으로 나타났습니다. 재개가 사용 된 모든 경우에 10 년에 걸쳐 문제가되었고보다 적절한 디자인으로 대체되었습니다. 기본적으로, 재개를 사용할 때마다 별도의 추상화 수준을 분리하지 않은 것으로 나타났습니다. 재개가 사용 된 모든 경우에 10 년에 걸쳐 문제가되었고보다 적절한 디자인으로 대체되었습니다. 기본적으로, 재개를 사용할 때마다 별도의 추상화 수준을 분리하지 않은 것으로 나타났습니다.

C ++에서 진정한 승리는 RAII 이므로 오류가 발생했을 때 리소스 할당 해제를 훨씬 쉽게 처리 할 수 ​​있습니다. ( throwtry- 의 필요성을 catch없애지 않지만 필요하지 않음을 의미합니다 finally.)

예외가 필요하다고 확신 한 것은 일반 컨테이너라고 생각합니다. 컨테이너 작성자는 포함 된 객체가 반환해야 할 오류 유형 (아마도 처리 방법이 훨씬 적음)에 대해 아무것도 알지 못하지만 해당 객체를 컨테이너는 해당 객체의 인터페이스가 무엇인지 알아야합니다. 그러나 포함 된 객체에서 어떤 종류의 오류가 발생할 수 있는지 알지 못하므로 예외 유형을 표준화 할 수 없습니다. (반대로 : 예외 유형을 표준화 할 수 있다면 예외는 필요하지 않습니다.)

사람들이 수년에 걸쳐 배운 것으로 보이는 또 다른 것은 예외 사양이 언어에 올바르게 적용되기 어렵다는 것입니다. 예를 들어 http://www.gotw.ca/publications/mill22.htm 또는 http://www.gotw.ca/gotw/082.htm을 참조하십시오 . (그리고 그것은 C ++뿐만 아니라 Java 프로그래머도 확인 된 예외와 확인되지 않은 예외 에 대한 경험 에 대한 긴 논쟁을 가지고 있습니다 .)

예외의 역사에 대해 조금. John B. Goodenough : "예외 처리 : 문제 및 제안 된 표기법" Commun. ACM 18 (12) : 683-696, 1975. 그러나 그 전에는 예외가 알려져 있었다. Mesa는 1974 년경에 그것들을 가졌으며 PL / I도 그랬을 것입니다. Ada는 1980 년 이전에 예외 메커니즘을 가지고있었습니다. 저는 C ++의 예외가 1976 년경 Barbara Liskov의 CLU 프로그래밍 언어에 대한 경험에 가장 큰 영향을 받았다고 생각합니다. Barbara Liskov : 프로그래밍 언어의 역사 에서 "CLU의 역사" --- II , Thomas J. Bergin, Jr. 및 Richard G. Gibson, Jr. (Eds.). 471-510, ACM, 1996 쪽 .


이것은 흥미롭고 더 나은 답변을 위해 더 많은 연구를해야 할 것입니다. 그러나 지금까지 : C ++에서 예외를 사용하는 것에 대한 반대 의견이 있음을 알고 있습니다 (아마도 일화하지만 예외 사용을 금지하는 데 사용되는 iirc Google 코딩 규칙). 자바 검사 예외는 확실히 독특하고 흥미로운 실험이지만, 그 기능은 역사를 통해 많은 악의를 얻었습니다 ... 대부분의 사람들은 런타임에 다시 던져 버립니다 (구문과 관련이있을 수는 있지만).
wvxvw

Common Lisp 예외의 분류에 대해 더 잘 알고 있습니다. 예외는 거의 성공하지는 못했지만 프로그램에 대한 위협 수준에 따라 예외를 나눕니다. 예를 들어, serious-conditionsimple-condition. 나는 또한 JL Austing를 읽고 있는데, 그는 시스템이 작업을 수행하지 못한 방법 (예 : 부적절한 부품 대 부정한 의도)을 기반으로 오류 (프로그래밍과 관련이 없음)를 그룹으로 분류합니다. 프로그래밍에 즉시 적용 할 수는 없지만 약간 수정 한 것일 수 있습니다.
wvxvw

@Wandering Logic C ++ excpetios가 sux 인 이유를 설명하고 교육 된 기능을 포함하면 언어가 손상 될 수 있다고 설명했기 때문에 나는 찬성했습니다.
Val

@wvxvw very strong objectionC ++의 예외에 대한 반대는 두 가지 사실에서 나옵니다. finally구문 이없고 아무도 예외를 사용하지 않습니다. 첫 번째 문제는 두 번째 문제를 악화시킵니다. 즉,이없는 finally경우 예외가 발생하면 리소스를 닫을 수 없습니다. 아무도 예외를 사용하지 않기 때문에 모든 함수 / API는 예외를 피하므로 모든 함수를 예외로 감싸는 전통적인 C ++ 인프라 전체를 재 구축하여 코드에서 이점을 얻으려면 많은 투자를해야합니다. 그러나이 부족 finally은이 접근법도 불가능하게 만듭니다.
Val

@wvxvw : Google의 규칙에 따라 모듈 (.so) 경계에서 예외가 발생하지 않습니다. C ++의 예외는 RTTI (Run-time Type Information)를 사용하기 때문에 Linux는 런타임 타이핑 구현을 제대로 수행하지 못하기 때문입니다. Linux에서는 동일한 버전의 동일한 컴파일러로 모듈을 컴파일하고 동일한 버전의 libstdc ++에 대해 링크 한 경우 모듈간에 런타임 유형 만 안정적으로 전달할 수 있습니다. 실제로 이것은 Linux 커뮤니티에서 일반적으로 C ++를 거부하는 것이지 예외를 거부하는 것은 아닙니다.
방황 논리

3

예외는 계산 효과 의 경우라는 점을 지적하겠습니다 . 다른 계산 효과는 변경 가능한 상태, I / O, 비결 정성, 연속성 및 기타 여러 가지입니다. 따라서 귀하의 질문에 더 일반적으로 질문 할 수 있습니다. 어떻게 계산 효과의 계층 구조를 구성하고, 어떻게 구성하며, 왜 우리는 다른 것들이 아닌 우리가 가진 것입니까?


1
나는 이것이 완전히 관련이 없다고 생각합니다. 문제는 예외 개념을 모델링하는 것이 아니라 오류에 매핑하는 것에 관한 것입니다. PLT 관점에서이를 설명하는 올바른 방법은 예외 계층 이론이라고 생각합니다.
Gilles 'SO- 악마 그만해

흠, 맞아. 나는 이것을 지적하기 위해 대답을 수정했지만 그것을 삭제할 필요는 없다고 생각합니다. 어떻게 생각해?
Andrej Bauer
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.