옵션 / 아마도 좋은 아이디어로 간주되고 확인 된 예외가 아닌 이유는 무엇입니까?


23

스칼라와 같은 일부 프로그래밍 언어에는 Option유형 개념 (이라고도 함 Maybe)이 있으며 값을 포함하거나 포함하지 않을 수 있습니다.

내가 읽은 것에서 그들은이 문제를 다루는 우수한 방법으로 널리 간주됩니다 null. 왜냐하면 프로그래머는 런타임 중에 단순히 폭발하지 않고 값이 없을 수있는 경우를 프로그래머가 명시 적으로 강요하기 때문입니다.

반면에 Java의 Checked Exceptions는 나쁜 생각으로 여겨지며 Java는이를 구현하는 유일한 널리 사용되는 언어 인 것 같습니다. 그러나 그 배후의 아이디어는 Option유형 과 다소 유사 하여 프로그래머가 예외가 발생할 수 있다는 사실을 명시 적으로 처리하도록합니다.

Option유형에없는 확인 된 예외에 몇 가지 추가 문제점 이 있습니까? 아니면이 아이디어가 생각과 비슷하지 않고 예외가 아닌 옵션을 명시 적으로 처리 해야하는 이유가 있습니까?


Either e a데이터 유형 도 참조하십시오 .

4
확인 된 예외 정보 : 진화하는 코드베이스와 누락되거나 오래된 문서가있는 다수의 오픈 소스 및 내부 Java 라이브러리 사용자로서 Java가 특정 예외를 명시 적으로 선언하지 않을 것이라고 생각했습니다. 예상치 못한 나쁜 장소에서 처리되지 않은 런타임 오류가 나타나는 악몽이 될 것입니다. 그리고 Java7은 결국 예외 처리를 거의 제정신으로 만들어 기존의 try-catch 혼란을 상당 부분 제거했습니다.
hyde

답변:


24

때문에 OptionS가 작성 가능합니다. 유용한 방법이 많이 있습니다 Option여전히 흐름에 대한 정밀한 제어를 허용하면서 간결한 코드를 작성할 수, : map, flatMap, toList, flatten등. 이것은 Option특정 종류의 모나드, 작곡 방법을 잘 아는 일부 객체 때문입니다. 이러한 메소드가없고 항상 on을 일치 Option시키거나 isDefined자주 호출 해야하는 경우에는 그다지 유용하지 않습니다.

대신, 확인 된 예외는 안전성을 추가하지만, 예외를 잡거나 스택을 버블 링하는 것 (유형 선언에 보일러 플레이트가 추가 된 것) 외에는 할 수있는 일이 많지 않습니다.


1
검사 예외가 ... 더 또는 덜 같은 방식의 차이를 구성 try {/* bunch of complex code involving calls to 50 different methods that may throw SomeCheckedException */} catch(SomeCheckedException e) {/* operation failed, do something */}하고 fromMaybe someDefaultValue (something >>= otherThing >>= ...50 other functions that may return Nothing...)정확히 무엇입니까? 전자가 당신에게 무엇이 잘못되었는지에 대한 자세한 정보를 제공한다는 사실 이외에.
user253751

14

관련되어 있지만 예외 및 가능성 개체는 동일한 유형의 문제를 처리하지 않습니다.

예외

예외적 인 상황 (일부 경우 오류가 발생 함)을 로컬에서 처리하지 않으면 예외가 발생합니다. 예를 들어 csv를 구문 분석하고 잘못된 형식의 행으로부터 자신을 보호하려고합니다. 무언가 잘못되었다는 것이 라인 반복에서 일부 함수 호출 일 수 있습니다. 가장 깊은 수준 (예 : 서식 문제에 대해 알게 됨)에서 예외를 발생 시키면 루프에서 예외를 포착하고 오류를 기록한 후 다음 줄로 진행할 수 있습니다. 나머지 코드에서는 아무것도 수정할 필요가 없습니다.

검사 된 예외는 모든 중간 함수가 throwable 유형을 선언해야하기 때문에 많은 고통을 가중시킵니다. 이 기능은 원래의 목적을 능가하므로 요즘 인기가 없습니다.

아마도 물건

"실패"를 로컬에서 처리 할 수있을 때 객체를 선택해야 할 수도 있습니다. 그런 의미에서, 그들은 리턴 API + 참조 API 또는 널 입력 가능 유형을 대체합니다.

Maybe 객체의 장점은 무언가 잘못되었음을 명시 적으로 선언한다는 것입니다. haskell에서 아마도 객체가 아닌 값을 가져야합니다. 그렇지 않으면 프로그램이 컴파일되지 않습니다.

nullable 형식의 문제는 절대적으로 안전하기 위해 항상 null을 확인해야한다는 것입니다. "무언가 잘못되었을 수 있습니다"상태가 기본 상태입니다.

리턴 코드 + ref api에 의한 패스의 문제점은 대부분의 사람들이 읽을 수 없다는 것입니다.


1
의견을 보내 주셔서 감사합니다. csv 예제가 의미가 없다고 생각하는 이유는 무엇입니까? OP는 실제로 상용구 방지 기술을 요구하지 않으며 적용 펑터 및 모나드와 같은 어휘 가이 질문에 너무 기술적 일 수 있다고 생각합니다.
Simon Bergot

1
Java (확인 된 예외가있는 다른 언어는 확실하지 않음)를 사용하면 IDE가 던지기를 추가하고 제거하고 javadoc 주석 상용구 부분을 업데이트한다는 점을 지적하고 싶습니다. 따라서 적어도 그 부분은 귀찮고 고통스럽지 않습니다. API 디자인을 할 때 그것이 고통이든, 이익이든, 또는 그 사이에 있든간에 그것은 또 다른 문제입니다.
hyde

5
@hyde : IDE가 무의미한 상용구 생성을 자동화 할 수 있다고해서 무의미한 상용구가 고통이 아님을 의미하지는 않습니다.
Michael Shaw

2
@hyde : 그러나 고통은 제거되지 않습니다. 무의미한 상용구가 여전히 존재하므로 아무런 이유없이 코드가 복잡해집니다. 상용구에 대한 이유가 있다면 무엇입니까?
Michael Shaw

2
@MichaelShaw 예외가 의미가 없으면 예외를 제거하십시오. 상황을 무시하거나 오류 값을 대신 반환하십시오. 버그이거나 복구 할 수없는 상황 인 경우 검사되지 않은 예외를 사용하십시오. 남아있는 것은 예를 들어 무의미한 상용구가 아닌 매개 변수 유형만큼 중요합니다. 기존 lib에서 API가 잘못된 경우 다른 lib를 사용하거나 잘못된 API로 고통받는 래퍼 메소드 / 클래스를 고려하십시오.
hyde

1

Maybe실제로 값이 필요할 때까지 오류 처리를 지연시킬 수 있기 때문에 (몇 가지 메소드 호출이 필요할 수 있음)

확인 된 예외 는 호출 위치에서 처리 해야 합니다.

예외의 유일한 단점은 실패한 이유에 대해 더 많은 정보를 전달할 수 있다는 것입니다 ( MaybeError오류가 발생했을 때 누군가가 던질 수있는 필드로 개발하지 않는 한 )


2
그러나 내 메소드 가이 예외를 throw한다고 선언하여 확인 된 예외 처리를 연기 할 수 있습니다.
미친 과학자

1
@MadScientist는 콜 스택 만 올라가는 반면 어쩌면 모든 방향으로 갈 수 있습니다
ratchet freak

5
Maybe유형을 처리 오류와 혼동해서는 안된다고 생각합니다 . 예외는 오류를보고하는 데 사용되고 옵션 유형은 부분 함수의 결과를 나타내는 데 사용됩니다. 부분 함수 반환 Nothing은 오류가 아닙니다.
Giorgio

@MadScientist : 메소드 호출이 "잘못된 값"표시를 리턴하면 즉시 명령문을 실행할 수 있습니다. 반대로, 메소드가 즉시 포착되지 않는 예외를 발생 시키면 호출 다음의 명령문은 건너 뜁니다. 확인 된 예외를 호출 스택에 퍼 뜨리게하는 것은 일반적으로 악한 일이며, 호출자가 호출 한 메소드에 의해 예상되는 의미가 있는지 여부를 호출자가 알 수있는 방법이 없기 때문에 일반적으로 악의적입니다 (그리고이를 처리하는 '가장 쉬운'방법은 아니어야 함). 호출 된 메소드가 거품을 일으키는 예기치 않은 조건을 나타내는 지 여부.
supercat
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.