Java 또는 C #과 같은 언어 디자이너는 null 참조의 존재와 관련된 문제를 알고 있다고 확신합니다 ( null 참조가 실제로 나쁜 것입니까? 참조 ). 또한 옵션 유형을 구현하는 것은 null 참조보다 훨씬 복잡하지 않습니다.
그들은 왜 어쨌든 포함하기로 결정 했습니까? 나는 null 참조가 부족하면 언어 작성자와 사용자 모두가 더 나은 품질의 코드 (특히 더 나은 라이브러리 디자인)를 장려하거나 강요 할 것이라고 확신합니다.
그것은 단순히 보수주의 때문일까요? “다른 언어들도 그것을 가지고 있어야합니다.”
답변
면책 조항 : 나는 개인적으로 언어 디자이너를 모르기 때문에 내가 당신에게주는 대답은 투기 적입니다.
Tony Hoare 자신 으로부터 :
나는 그것을 10 억 달러의 실수라고 부릅니다. 그것은 1965 년에 null 참조의 발명이었다. 당시 나는 객체 지향 언어 (ALGOL W)로 참조 할 수있는 최초의 포괄적 인 타입 시스템을 설계하고 있었다. 필자의 목표는 컴파일러가 자동으로 검사를 수행하여 모든 참조 사용이 절대적으로 안전하도록하는 것이 었습니다. 그러나 구현하기가 쉽기 때문에 null 참조를 넣는 유혹에 저항 할 수 없었습니다. 이로 인해 수많은 오류, 취약성 및 시스템 충돌이 발생하여 지난 40 년간 수십억 달러의 고통과 피해를 초래했을 수 있습니다.
강조합니다.
당연히 그것은 그에게 나쁜 생각처럼 보이지 않았습니다. 그것은이 같은 이유로 일부 영속 된 가능성이 높습니다 – 그것은 퀵의 튜링 상을 수상한 발명가에 좋은 생각처럼 보였다 경우, 많은 사람들이 있다는 놀라운 일이 아니다 여전히 그것이 악 이유를 이해하지 않습니다. 또한 마케팅 및 학습 곡선의 이유로 새로운 언어가 이전 언어와 유사하기 때문에 부분적으로 가능합니다. 지목 사항:
“우리는 C ++ 프로그래머를 뒤 따랐다. 많은 사람들을 Lisp로 반쯤 끌었다.”
-Guy Steele, Java 사양의 공동 저자
(출처 : http://www.paulgraham.com/icad.html )
물론 C에는 null이 있으므로 C ++에는 null이 있으며 C의 역사적 영향에 관여 할 필요가 없습니다. C #은 Microsoft의 Java 구현 인 J ++로 대체되었으며 Windows 개발에서 선택한 언어로 C ++로 대체되었으므로 어느 쪽에서 나 얻을 수있었습니다.
편집 여기 Hoare가 고려할만한 또 다른 인용문이 있습니다.
전체적으로 프로그래밍 언어는 예전보다 훨씬 더 복잡합니다. 객체 지향, 상속 및 기타 기능은 일관성 있고 과학적으로 잘 기초 된 학문 또는 정확성 이론의 관점에서 실제로 생각되지 않습니다. . 내가 평생 과학자로 추구해 온 원래의 가정은 올바른 프로그래밍 언어 디자인 (사용자를 위해 함정을 설정하지 않는 프로그래밍 언어 디자인)에 수렴하는 수단으로 정확성 기준을 사용한다는 것입니다. 프로그램의 다른 구성 요소는 해당 사양의 다른 구성 요소와 명확하게 일치하므로 구성에 대해 추론 할 수 있습니다. […] 컴파일러를 포함한 도구는 올바른 프로그램을 작성한다는 의미에 대한 이론을 기반으로해야합니다.
-2002 년 7 월 17 일, 영국 캠브리지, 필립 L. 프란 아의 구술 역사 인터뷰; 미네소타 대학교 찰스 배비지 연구소. [ http://www.cbi.umn.edu/oh/display.phtml?id=343]
다시 한 번 강조한다. Sun / Oracle 및 Microsoft는 회사이며 모든 회사의 결론은 돈입니다. 그들로 인한 이익 null
이 단점보다 더 클 수도 있고, 또는 문제를 완전히 고려하기에는 마감 기한이 너무 짧을 수도 있습니다. 마감일로 인해 발생했을 수있는 다른 언어 실수의 예 :
Cloneable이 고장났다는 것은 부끄러운 일이지만 발생합니다. 원래 Java API는 마감 시한에 맞춰 매우 빠르게 마감되어 시장 마감 시간을 맞이했습니다. 원래 Java 팀은 놀라운 작업을 수행했지만 모든 API가 완벽하지는 않습니다. Cloneable은 약점이며 사람들은 그 한계를 알고 있어야한다고 생각합니다. 조쉬 블로흐
답변
Java 또는 C #과 같은 언어의 디자이너가 null 참조의 존재와 관련된 문제를 알고 있다고 확신합니다.
물론이야.
또한 옵션 유형을 구현하는 것은 null 참조보다 훨씬 복잡하지 않습니다.
나는달라고 간청한다! C # 2에서 Null을 허용하는 값 형식으로 들어가는 디자인 고려 사항은 복잡하고 논쟁의 여지가 많았습니다. 그들은 언어와 런타임의 디자인 팀을 수개월 간의 토론, 프로토 타입 구현 등으로 가져 갔으며 실제로 nullable boxing의 의미는 C # 2.0 배송에 매우 가깝게 변경되었으며 이는 매우 논쟁의 여지가 있습니다.
그들은 왜 어쨌든 포함하기로 결정 했습니까?
모든 디자인은 미묘하고 심하게 양립 할 수없는 많은 목표 중에서 선택하는 과정입니다. 고려할 몇 가지 요소에 대한 간단한 스케치 만 제공 할 수 있습니다.
-
언어 기능의 직교성은 일반적으로 좋은 것으로 간주됩니다. C #에는 nullable 값 형식, nullable 값 형식 및 nullable 참조 형식이 있습니다. 널 입력 불가능 참조 유형이 존재하지 않으므로 유형 시스템이 직교하지 않습니다.
-
기존 C, C ++ 및 Java 사용자에게 친숙 함이 중요합니다.
-
COM과의 쉬운 상호 운용성이 중요합니다.
-
다른 모든 .NET 언어와의 쉬운 상호 운용성이 중요합니다.
-
데이터베이스와의 쉬운 상호 운용성이 중요합니다.
-
의미론의 일관성이 중요합니다. 우리가 TheKingOfFrance를 null과 동일하게 언급한다면 그것은 항상 “지금은 프랑스의 왕이 없다”는 것을 의미합니까, 또는 “프랑스의 왕이 분명히 있습니다. 또는 “프랑스에서 왕이 있다는 개념은 무의미하므로 질문하지 않아도됩니다!” Null은 C #에서 이러한 모든 것을 의미 할 수 있으며 이러한 모든 개념이 유용합니다.
-
성능 비용이 중요합니다.
-
정적 분석에 적합한 것이 중요합니다.
-
형식 시스템의 일관성이 중요합니다. 우리는 할 수 항상 nullable이 아닌 참조가 없다는 것을 알고 결코 아래에 있는 유효하지 않은 것으로 관찰 상황? null이 아닌 참조 유형의 필드를 가진 객체의 생성자에서는 어떻습니까? 참조를 작성 해야하는 코드에서 예외가 발생 하여 객체가 완성되는 해당 객체의 마무리 장치 는 어떻습니까? 보증에 관한 거짓말 시스템은 위험합니다.
-
그리고 시맨틱의 일관성은 어떻습니까? Null 값은 사용될 때 전파되지만 Null 참조는 사용될 때 예외를 발생시킵니다. 일관성이 없습니다. 그 불일치가 어떤 이점으로 정당화 되었습니까?
-
다른 기능을 중단하지 않고 기능을 구현할 수 있습니까? 이 기능이 배제 할 수있는 다른 기능은 무엇입니까?
-
당신은 당신이 원하는 군대가 아닌, 당신이 가진 군대와 전쟁을합니다. C # 1.0에는 제네릭이 없으므로
Maybe<T>
대안으로 말하는 것은 시작이 아닌 완전한 방법입니다. 런타임 팀이 null 참조를 제거하기 위해 제네릭을 추가하는 동안 .NET이 2 년 동안 미끄러 졌어 야합니까? -
타입 시스템의 일관성은 어떻습니까?
Nullable<T>
모든 유형의 값에 대해 말할 수 있습니다. 아니, 그건 거짓말입니다. 말할 수 없습니다Nullable<Nullable<T>>
. 할 수 있을까요? 그렇다면 원하는 의미론은 무엇입니까? 이 기능에 대해서만 전체 유형 시스템에 특별한 경우를 두는 것이 가치가 있습니까?
등등. 이러한 결정은 복잡합니다.
답변
Null은 가치 부족을 나타내는 매우 유효한 목적을 제공합니다.
나는 내가 무질서한 학대와 모든 두통과 그들이 자유로이 사용될 때 발생할 수있는 고통에 대해 내가 아는 가장 성실한 사람이라고 말할 것입니다.
내 개인적인 입장은 사람들이 필요하고 적절하다고 정당화 할 수있을 때만 null을 사용할 수 있다는 것입니다.
널을 정당화하는 예제 :
사망 날짜는 일반적으로 널 입력 가능 필드입니다. 사망일에는 3 가지 가능한 상황이 있습니다. 사람이 사망하고 날짜를 알거나, 사람이 사망하고 날짜를 알 수 없거나, 사람이 죽지 않았으므로 사망 날짜가 존재하지 않습니다.
사망 날짜도 DateTime 필드이며 “알 수 없음”또는 “빈”값이 없습니다. 기본 날짜는 사용 된 언어에 따라 달라지는 새로운 날짜 시간을 만들 때 나타나는 기본 날짜를 갖지만 기술적으로 실제로 그 시간에 사람이 죽어“빈 값”으로 표시 될 가능성이 있습니다 기본 날짜를 사용하십시오.
데이터는 상황을 올바르게 나타내야합니다.
사망자가 사망 한 것으로 알려져 있습니다 (1984 년 3 월 9 일)
간단한 ‘1984 년 3 월 9 일’
사람이 사망 한 날짜를 알 수 없음
가장 좋은 것은 무엇입니까? Null , ‘0/0/0000’또는 ’01 / 01 / 1869 ‘(또는 기본값은 무엇입니까?)
사망하지 않은 사람 사망일은 해당되지 않습니다
가장 좋은 것은 무엇입니까? Null , ‘0/0/0000’또는 ’01 / 01 / 1869 ‘(또는 기본값은 무엇입니까?)
따라서 각각의 가치를 생각해 봅시다 …
- Null 은주의를 기울여야합니다. 예를 들어 null이 아닌지 확인하지 않고 실수로 조작하려고하면 예외가 발생하지만 실제 상황을 가장 잘 나타냅니다. 죽음의 날짜는 존재하지 않습니다 … 아무것도 아닙니다 … null입니다 …
- 0/0/0000 , 일부 언어에서는 가능하며 날짜가없는 적절한 표현 일 수도 있습니다. 불행히도 일부 언어 및 유효성 검사는이를 유효하지 않은 날짜 시간으로 거부하므로 많은 경우에 실패하지 않습니다.
- 1/1/1869 (또는 기본 날짜 시간 값이 무엇이든) 여기서 문제는 다루기가 까다로워집니다. 사망일이없는 모든 기록을 걸러 내려면 어떻게됩니까?를 제외하고는 가치 가치가없는 것으로 사용할 수 있습니까? 나는 그 날짜에 실제로 죽은 사람들을 쉽게 걸러내어 데이터 무결성 문제를 일으킬 수 있습니다.
사실은 때때로 당신입니다 마십시오 아무것도 표현하지 있는지 때때로 변수 유형가 잘 작동하지만, 종종 변수 유형 아무것도 표현하지 할 수 있어야합니다.
사과가 없으면 사과가 0 개인데 사과가 몇 개인 지 모른다면 어떻게해야합니까?
반드시 null은 남용되고 잠재적으로 위험하지만 때때로 필요합니다. 값을 제공 할 때까지 값이없고 무언가를 나타내야하기 때문에 많은 경우에 기본값입니다. (없는)
답변
나는 “다른 언어들도 그것을 가지고 있고, 우리도 그것을 가져야 만한다 …”그런 식으로 Joneses를 따라 잡는 것처럼 가지 않을 것이다. 새로운 언어의 주요 특징은 다른 언어로 된 기존 라이브러리와 상호 작용할 수 있다는 것입니다 (C 읽기). C에는 null 포인터가 있으므로 상호 운용성 계층에는 반드시 null 개념이 필요합니다 (또는 사용할 때 폭발하는 다른 “존재하지 않음”).
언어 디자이너가 옵션 유형 을 사용하도록 선택 하고 널 이 될 수있는 모든 곳 에서 널 경로를 처리하도록 할 수 있습니다. 그리고 그것은 거의 확실히 버그를 줄입니다.
그러나이 상호 운용성 계층에 옵션 유형을 사용하는 경우 (특히 도입시기 및 대상 대상으로 인해 Java 및 C #의 경우) 채택을 어지럽히 지 않으면 피해를 입었을 수 있습니다. 옵션 유형은 90 년대 중반에서 후반의 C ++ 프로그래머들로부터 지옥을 성가 시게하거나 또는 null을 만나면 상호 운용성 계층에서 예외가 발생하여 90 년대 중반에서 후반까지의 C ++ 프로그래머들로부터 지옥을 성가 시게합니다. ..
답변
우선, 우리는 무의 개념 이 필요 하다는 것에 모두 동의 할 수 있다고 생각 합니다. 정보 의 부재 를 대변해야하는 상황이 있습니다 .
null
참조 (및 포인터)를 허용 하는 것은이 개념의 한 가지 구현 일뿐이며 C, Java, Python, Ruby, PHP, JavaScript 등의 문제가 있음을 알고 있지만 가장 인기가 있습니다. 모두 비슷한 것을 사용합니다 null
.
왜 ? 글쎄, 대안은 무엇입니까?
Haskell과 같은 기능적 언어에서는 Option
또는 Maybe
유형이 있습니다. 그러나 그것들은 다음에 기반합니다 :
- 파라 메트릭 유형
- 대수 데이터 유형
이제 원래 C, Java, Python, Ruby 또는 PHP가 이러한 기능 중 하나를 지원 했습니까? 아니요. Java의 결함이있는 제네릭은 최근 에 언어 역사에있어 다른 사람들이 전혀 구현하지 않은 것 같습니다.
거기 있어요 null
파라 메트릭 대수 데이터 형식이 더 어렵습니다. 사람들은 가장 간단한 대안으로 갔다.
답변
Null / nil / none 자체는 악이 아닙니다.
Tony Hoare가 자신의 이름을 불렀던 유명한 연설 “Billion dollar Mistake”를 본다면 어떤 변수가 널 (null)을 보유 할 수있게하는 것이 큰 실수 인지에 대해 이야기합니다 . 옵션을 사용하는 대안 은 실제로 널 참조를 제거 하지 않습니다 . 대신 널을 보유 할 수있는 변수와 그렇지 않은 변수를 지정할 수 있습니다.
사실, 적절한 예외 처리를 구현하는 최신 언어를 사용하면 null 역 참조 오류는 다른 예외와 다르지 않습니다. 찾아서 수정합니다. null 참조에 대한 일부 대안 (예 : Null Object 패턴)은 오류를 숨기고 나중에 훨씬 나중에 자동으로 실패합니다. 제 생각에는 빨리 실패하는 것이 훨씬 좋습니다 .
그렇다면 왜 언어가 옵션을 구현하지 못하는가? 사실, C ++은 가장 널리 사용되는 언어로 할당 할 수없는 객체 변수를 정의 할 수 있습니다 NULL
. 토니 호 아어 (Tony Hoare)는 그의 연설에서 언급 된 “널 문제”에 대한 해결책이다. 다음으로 가장 많이 사용되는 유형 언어 인 Java가없는 이유는 무엇입니까? 왜 일반적으로 유형 시스템에 결함이 많은지 묻습니다 . 언어가 체계적으로이 실수를한다고 말할 수는 없다고 생각합니다. 어떤 사람들은 그렇지 않습니다.
답변
프로그래밍 언어는 일반적으로 기술적으로 정확하기보다는 실질적으로 유용하도록 설계 되었기 때문입니다. 사실 null
상태는 데이터가 잘못되었거나 누락되었거나 아직 결정되지 않은 상태로 인해 일반적으로 발생합니다. 기술적으로 우수한 솔루션은 단순히 널 (null) 상태를 허용하고 프로그래머가 실수를한다는 사실을 잊는 것보다 다루기 힘들다.
예를 들어 파일과 함께 작동하는 간단한 스크립트를 작성하려면 다음과 같이 의사 코드를 작성할 수 있습니다.
file = openfile("joebloggs.txt")
for line in file
{
print(line)
}
joebloggs.txt가 없으면 단순히 실패합니다. 문제는 아마도 괜찮은 간단한 스크립트와 더 복잡한 코드의 많은 상황에서 그것이 존재하고 실패가 발생하지 않아서 시간 낭비를 확인하도록 강요한다는 것입니다. 더 안전한 대안은 잠재적 인 실패 상태를 올바르게 처리하도록함으로써 안전을 달성하지만 종종 그렇게하고 싶지는 않습니다.