동적 유형 언어와 정적 유형 언어


205

정적 유형 언어와 비교하여 동적 유형 언어의 장점과 한계는 무엇입니까?

또한보십시오 : 동적 언어의 사랑으로 무엇입니까 (훨씬 더 논쟁적인 스레드 ...)


10
이 질문은 너무 주관적입니다.
Jason Dagit

7
나는 그것을 주관적이지 않고 화염 미끼라고 부를 것입니다. 그러나 그것에 관한 객관적인 사실이 있습니다.
Vinko Vrsalovic

2
동의 함 : 너무 주관적입니다. 두 가지 접근 방식을 비교하고 대조하는 것은 흥미롭지 만 포럼 묵시록 직전에 위험에 빠집니다.
Daniel Spiewak

17
동적 언어는 데모 / 던지기 응용 프로그램의 신속한 개발에 유용합니다. 관심있는 오타를 만들면 웹 페이지가 계속로드되므로 여기 또는 여기에 몇 가지 데이터 요소가있을 수 있습니다. 컴파일러 오류없이 변수를 잘못 입력하는 기능이 "이점"으로 여겨지는 다른 상황은 상상할 수 없습니다.
Alex R

4
이러한 오류는 일반적으로 JavaScript를 끔찍하게 멈추게합니다. 적어도 그것은 또한 가치있는 오류를 던질 것입니다. 어떤 이유로 든 정적 타이핑 패러다임의 사람은 빈 try / catch 문으로 자바 스크립트 오류를 ​​묻고 싶습니다. 그것은 내 경험에있어 어떤 현상이었다. 그게 뭐야? 어쨌든 코드를 실행할 때 피드백을받지 못하는 것은 아닙니다.
Erik Reppen

답변:


139

인터프리터가 타입 및 타입 변환을 추론 할 수있는 능력으로 인해 개발 시간이 더 빨라지지만 컴파일 타임에이를 파악할 수있는 정적 타입 언어로는 얻을 수없는 런타임 실패를 유발할 수 있습니다. 그러나 요즘 (그리고 오랜 시간 이후) 커뮤니티에서 어느 것이 더 낫거나 (또는 ​​항상 그렇더라도) 어느 것이 더 좋을지 논의됩니다.

이 문제에 대한 좋은 견해는 가능한 경우 정적 입력, 필요할 때 동적 입력 : Erik Meijer와 Microsoft의 Peter Drayton의 프로그래밍 언어 간 냉전의 종말입니다 .

정적 타이핑을 옹호하는 사람들은 정적 타이핑의 장점에는 프로그래밍 실수의 조기 발견 (예 : 부울에 정수 추가 방지), 유형 시그니처 형식의 더 나은 문서화 (예 : 이름을 확인할 때 인수의 수와 유형 통합) 등이 있다고 주장합니다. 컴파일러 최적화 기회 (예 : 정확한 유형의 수신기가 정적으로 알려진 경우 직접 호출로 가상 호출 대체), 런타임 효율성 향상 (예 : 모든 값이 동적 유형을 전달할 필요는 없음) 및 더 나은 설계 시간 개발자 경험 (예 : 알고 있음) 수신기의 유형 인 경우 IDE는 모든 해당 멤버의 드롭 다운 메뉴를 표시 할 수 있습니다). 정적 타이핑 광신자들은 우리가“잘 타이핑 된 프로그램은 잘못 될 수 없다”고 믿도록 노력합니다. 확실히 인상적으로 들리지만 다소 공허한 진술이다. 정적 유형 검사는 프로그램의 런타임 동작을 컴파일 타임으로 추상화 한 것이므로 부분적으로 만 소리가 나고 불완전합니다. 즉, 형식 검사기가 추적하지 않는 속성으로 인해 프로그램이 여전히 잘못 될 수 있으며 잘못 할 수없는 동안 형식을 확인할 수없는 프로그램이 있습니다. 정적 타이핑을 부분적이고 완전하지 않게 만드는 충동은 유형 시스템이“팬텀 유형”[11] 및“거품 유형”[10]과 같은 개념에서 볼 수 있듯이 지나치게 복잡하고 이국적이게 만듭니다. 이것은 다리에 묶인 공과 체인으로 마라톤을 뛰는 것과 같으며 첫 번째 마일 이후 밖으로 나가더라도 거의 당신이 그것을 만들었다는 소리를 외치며 소리칩니다. 정적 유형 검사는 프로그램의 런타임 동작을 컴파일 타임으로 추상화 한 것이므로 부분적으로 만 소리가 나고 불완전합니다. 즉, 형식 검사기가 추적하지 않는 속성으로 인해 프로그램이 여전히 잘못 될 수 있으며 잘못 할 수없는 동안 형식을 확인할 수없는 프로그램이 있습니다. 정적 타이핑을 부분적이고 완전하지 않게 만드는 충동은 유형 시스템이“팬텀 유형”[11] 및“거품 유형”[10]과 같은 개념에서 볼 수 있듯이 지나치게 복잡하고 이국적이게 만듭니다. 이것은 다리에 묶인 공과 체인으로 마라톤을 뛰는 것과 같으며 첫 번째 마일 이후 밖으로 나가더라도 거의 당신이 그것을 만들었다는 소리를 외치며 소리칩니다. 정적 유형 검사는 프로그램의 런타임 동작을 컴파일 타임으로 추상화 한 것이므로 부분적으로 만 소리가 나고 불완전합니다. 즉, 형식 검사기가 추적하지 않는 속성으로 인해 프로그램이 여전히 잘못 될 수 있으며 잘못 할 수없는 동안 형식을 확인할 수없는 프로그램이 있습니다. 정적 타이핑을 부분적이고 완전하지 않게 만드는 충동은 유형 시스템이“팬텀 유형”[11] 및“거품 유형”[10]과 같은 개념에서 볼 수 있듯이 지나치게 복잡하고 이국적이게 만듭니다. 이것은 다리에 묶인 공과 체인으로 마라톤을 뛰는 것과 같으며 첫 번째 마일 이후 밖으로 나가더라도 거의 당신이 그것을 만들었다는 소리를 외치며 소리칩니다. 그러므로 그것은 단지 부분적으로 건전하고 불완전합니다. 즉, 형식 검사기가 추적하지 않는 속성으로 인해 프로그램이 여전히 잘못 될 수 있으며 잘못 할 수없는 동안 형식을 확인할 수없는 프로그램이 있습니다. 정적 타이핑을 부분적이고 완전하지 않게 만드는 충동은 유형 시스템이“팬텀 유형”[11] 및“거품 유형”[10]과 같은 개념에서 볼 수 있듯이 지나치게 복잡하고 이국적이게 만듭니다. 이것은 다리에 묶인 공과 체인으로 마라톤을 뛰는 것과 같으며 첫 번째 마일 이후 밖으로 나가더라도 거의 당신이 그것을 만들었다는 소리를 외치며 소리칩니다. 그러므로 그것은 단지 부분적으로 건전하고 불완전합니다. 즉, 형식 검사기가 추적하지 않는 속성으로 인해 프로그램이 여전히 잘못 될 수 있으며 잘못 할 수없는 동안 형식을 확인할 수없는 프로그램이 있습니다. 정적 타이핑을 부분적이고 완전하지 않게 만드는 충동은 유형 시스템이“팬텀 유형”[11] 및“거품 유형”[10]과 같은 개념에서 볼 수 있듯이 지나치게 복잡하고 이국적이게 만듭니다. 이것은 다리에 묶인 공과 체인으로 마라톤을 뛰는 것과 같으며 첫 번째 마일 이후 밖으로 나가더라도 거의 당신이 그것을 만들었다는 소리를 외치며 소리칩니다. 잘못 될 수는 없지만 형식 검사를 할 수없는 프로그램이 있습니다. 정적 타이핑을 부분적이고 완전하지 않게 만드는 충동은 유형 시스템이“팬텀 유형”[11] 및“거품 유형”[10]과 같은 개념에서 볼 수 있듯이 지나치게 복잡하고 이국적이게 만듭니다. 이것은 다리에 묶인 공과 체인으로 마라톤을 뛰는 것과 같으며 첫 번째 마일 이후 밖으로 나가더라도 거의 당신이 그것을 만들었다는 소리를 외치며 소리칩니다. 잘못 될 수는 없지만 형식 검사를 할 수없는 프로그램이 있습니다. 정적 타이핑을 부분적이고 완전하지 않게 만드는 충동은 유형 시스템이“팬텀 유형”[11] 및“거품 유형”[10]과 같은 개념에서 볼 수 있듯이 지나치게 복잡하고 이국적이게 만듭니다. 이것은 다리에 묶인 공과 체인으로 마라톤을 뛰는 것과 같으며 첫 번째 마일 이후 밖으로 나가더라도 거의 당신이 그것을 만들었다는 소리를 외치며 소리칩니다.

동적 유형 언어의 옹호자들은 정적 타이핑이 너무 엄격하고 동적 언어의 부드러움으로 인해 요구 사항이 변경되거나 알려지지 않은 프로토 타이핑 시스템에 이상적이거나 예측할 수없이 변경되는 다른 시스템 (데이터 및 응용 프로그램 통합)과 상호 작용하는 데 이상적이라고 주장합니다. 물론 동적 타입 언어는 메소드 인터 셉션, 동적 로딩, 모바일 코드, 런타임 리플렉션 등과 같은 진정한 동적 프로그램 동작을 처리하는 데 필수적입니다. 프로그래밍 언어는 동적으로 형식화 된 스크립팅 언어보다 코드 재사용이 적고, 더 장황하며, 안전하지 않으며, 표현력이 떨어집니다. 이 주장은 문자 그대로 동적으로 유형이 지정된 스크립팅 언어의 많은 지지자에 의해 해석됩니다. 우리는 이것이 오류라고 주장하며 선언적 프로그래밍의 본질이 과제를 제거한다고 주장하는 것과 같은 범주에 속합니다. 또는 John Hughes가 말했듯이 [8], 기능을 생략하여 언어를 더 강력하게 만드는 것은 논리적으로 불가능합니다. 모든 유형 검사를 런타임으로 지연시키는 것이 좋은 일이라는 사실을 변호하는 것은 개발 프로세스 초기에 오류를 최대한 빨리 잡아야한다는 사실과 함께 타조 전술을 재생하는 것입니다. 기능을 생략하여 언어를 더 강력하게 만드는 것은 논리적으로 불가능합니다. 모든 유형 검사를 런타임으로 지연시키는 것이 좋은 일이라는 사실을 변호하는 것은 개발 프로세스 초기에 오류를 최대한 빨리 잡아야한다는 사실과 함께 타조 전술을 재생하는 것입니다. 기능을 생략하여 언어를 더 강력하게 만드는 것은 논리적으로 불가능합니다. 모든 유형 검사를 런타임으로 지연시키는 것이 좋은 일이라는 사실을 변호하는 것은 개발 프로세스 초기에 오류를 최대한 빨리 잡아야한다는 사실과 함께 타조 전술을 재생하는 것입니다.


37
"메소드 차단, 동적 로딩, 모바일 코드, 런타임 리플렉션"은 모두 레코드를 위해 Java로 수행 할 수 있습니다.
Will Hartung

13
팬텀 유형은 "과도하게 복잡하지 않습니다".
Jon Harrop

12
Meijer 용지에 대한 링크는 2010 년 5 월 16 일부로 중단되었습니다.
jchadhowell


4
@VinkoVrsalovic 형식 유추와 다형성이있는 정적 언어는 빠른 프로토 타입 제작에 매우 좋습니다. 동적 언어와 정적 언어의 안전성과 동일한 편의성을 제공합니다.
Edgar Klerks

119

정적 유형 시스템은 특정 오류를 정적으로 제거하여 프로그램을 실행하지 않고 검사하고 특정 측면에서 건전성을 증명하려고합니다. 일부 유형 시스템은 다른 유형보다 더 많은 오류를 포착 할 수 있습니다. 예를 들어, C #은 올바르게 사용될 때 널 포인터 예외를 제거 할 수 있지만 Java에는 그러한 힘이 없습니다. Twelf는 타입 시스템을 가지고있어 실제로 증명이 종료되도록 하여 정지 문제를 "해결"합니다 .

그러나 완벽한 타입 시스템은 없습니다. 특정 클래스의 오류를 제거하려면 규칙을 위반하는 완벽하게 유효한 특정 프로그램을 거부해야합니다. 이것이 Twelf가 실제로 정지 문제를 해결하지 못하는 이유입니다. 홀수 방식으로 끝나는 완벽하게 유효한 많은 증명을 버림으로써 피할 수 있습니다. 마찬가지로 Java 유형 시스템은 PersistentVector이기종 배열을 사용하기 때문에 Clojure의 구현을 거부 합니다. 런타임에 작동하지만 유형 시스템이이를 확인할 수 없습니다.

이러한 이유로 대부분의 유형 시스템은 "탈출"을 제공하여 정적 검사기를 재정의하는 방법을 제공합니다. 대부분의 언어의 경우 C # 및 Haskell과 같은 일부 모드는 "안전하지 않은"것으로 표시된 전체 모드를 갖지만 캐스팅 형식을 취합니다.

주관적으로, 나는 정적 타이핑을 좋아합니다. (힌트 : 제대로 구현 되지 자바), 정적 타입 시스템은 생산 시스템을 충돌하기 전에 오류를 걸러에 큰 도움이 될 수 있습니다. 동적 유형 언어는 더 많은 단위 테스트를 요구하는 경향이 있으며, 이는 지루한 일입니다. 또한 정적으로 유형이 지정된 언어는 동적 유형 시스템에서 불가능하거나 안전하지 않은 특정 기능을 가질 수 있습니다 ( 암시 적 변환 은 마음에 spring니다). 그것은 요구 사항과 주관적인 맛의 문제입니다. 더 이상 Ruby에서 다음 Eclipse를 빌드하지 않고 Assembly에서 백업 스크립트를 작성하거나 Java를 사용하여 커널을 패치하려고 시도합니다.

오, " x 타이핑은 y 타이핑 보다 10 배 더 생산적 이다"고 말하는 사람들 은 단순히 연기를 날려 버립니다. 동적 타이핑은 많은 경우에 "느끼게"느껴질 수 있지만 실제로 멋진 응용 프로그램을 실행 하려고하면 실패 합니다 . 마찬가지로 정적 타이핑은 완벽한 안전망처럼 보일 수 있지만 Java에서보다 복잡한 일반 유형 정의 중 일부를 살펴보면 대부분의 개발자가 눈 먼 사람들을 겁나게합니다. 타입 시스템과 생산성에도 불구하고은 총알은 없습니다.

마지막 참고 사항 : 정적 입력과 동적 입력을 비교할 때 성능에 대해 걱정하지 마십시오. V8 및 TraceMonkey와 같은 최신 JIT는 정적 언어 성능에 매우 가깝습니다. 또한 Java가 실제로 본질적으로 동적 중간 언어로 컴파일된다는 사실은 대부분의 경우 동적 타이핑이 일부 사람들이 만드는 큰 성능 저하가 아니라는 힌트가되어야합니다.


5
성능 정보 일반적인 경우에는 그다지 큰 차이를 만들지 않지만 높은 장력 수학에서는 실제로 차이가 있습니다. 테스트는 ipy 대 C #의 경우 1000 사이클마다 다른 기능 호출을 입증했습니다. 전자가 방법이 존재하는지 확인해야하기 때문입니다.
Dykam

29
"C #은 적절하게 사용될 때 널 포인터 예외를 제거 할 수있는 반면 Java에는 그러한 힘이 없습니다." ? 예나 인용은 높이 평가 될 것이다.
Srinivas Reddy Thatiparthy

13
"자바에서 좀 더 복잡한 제네릭 형식 정의 중 일부는 대부분의 개발자에게
눈가림을 피하는

3
또한 Java가 실제로 본질적으로 동적 인 중간 언어로 컴파일된다는 사실은 대부분의 경우 동적 인 타이핑이 일부 사람들이 그것을 만드는 큰 성능 저하가 아니라는 힌트가되어야한다”고 말했다. - "성능이 우수한"언어의 예가 Java 인 경우 재고를 원할 수 있습니다.
Yakk-Adam Nevraumont

" 자바는 본질적으로 동적 인 중간체로 컴파일한다 "-요점을 놓쳤다. 정적 검사는 사전에 수행되었으므로 컴파일러 dadd는 피연산자가 doubles 인 것을 미리 알고 있기 때문에 컴파일러가 명령어를 선택할 때이를 처리하는 추가 런타임 검사가 필요하지 않습니다 .
Michael Beer

45

글쎄, 둘 다 매우, 매우 매우 오해와 완전히 다른 두 가지입니다. 상호 배타적이지 않습니다 .

정적 유형은 언어 문법의 제한 사항입니다. 정적으로 입력 된 언어는 문맥에 맞지 않다고 말할 수 있습니다. 간단한 진실은 모든 데이터를 단순히 비트 벡터로 취급하지 않는 문맥 자유 문법으로 언어를 산만하게 표현하는 것이 불편하다는 것입니다. 정적 유형 시스템은 언어 문법의 일부입니다. 문맥 자유 문법보다 문법을 제한하기 때문에 문법 검사는 실제로 소스를 두 번 통과합니다. 정적 유형은 유형 이론의 수학적 개념에 해당하며 수학의 유형 이론은 단순히 일부 표현의 적법성을 제한합니다. 마찬가지로, 3 + [4,7]수학에서는 말할 수 없습니다 . 이것은 유형 이론 때문입니다.

따라서 정적 유형은 이론적 관점에서 '오류를 방지'하는 방법이 아니며 문법의 한계입니다. 실제로 +, 3 및 간격에 일반적인 이론적 정의가있는 경우 유형 시스템 3 + [4,7]을 제거하면 꽤 잘 정의 된 결과가 설정됩니다. '런타임 타입 오류'는 이론적으로 존재하지 않으며, 타입 시스템의 실제적인 사용은 인간 이 이해하지 못하는 동작을 방지하는 것입니다. 작업은 여전히 ​​비트의 이동 및 조작입니다.

이것에 대한 캐치 유형 시스템은 이러한 작업이 발생할지 여부를 결정할 수 없다는 것입니다. 마찬가지로 '유형 오류'가있는 프로그램과 그렇지 않은 프로그램에서 가능한 모든 프로그램 세트를 정확하게 분할하십시오. 두 가지만 할 수 있습니다.

1 : 프로그램에서 유형 오류가 발생 함을
증명합니다 2 : 프로그램에서 유형 오류가 발생 하지 않을 것임을 증명합니다

이것은 내가 모순되는 것처럼 보일 수 있습니다. 그러나 C 또는 Java 유형 검사기는 프로그램을 '완전한'것으로 거부하거나 2에서 성공할 수없는 경우 '유형 오류'라고 부르므로 발생하지 않을 것이라는 것을 증명할 수 없습니다. 그것은 그들이 일어나지 않을 것이라는 것을 의미하는 것이 아니며, 단지 그것을 증명할 수 없다는 것을 의미합니다. 형식 오류가없는 프로그램은 컴파일러에서 증명할 수 없기 때문에 거부되는 경우가 많습니다. 간단한 예는if(1) a = 3; else a = "string";반드시 true이므로, else-branch는 프로그램에서 절대 실행되지 않으며 타입 오류가 발생하지 않습니다. 그러나 이러한 경우를 일반적인 방식으로 증명할 수 없으므로 거부됩니다. 이것은 정적으로 유형이 지정된 많은 언어의 주요 약점입니다. 자신을 보호하기 위해 필요하지 않은 경우에도 보호해야합니다.

그러나 대중적인 생각과는 달리, 원칙 1에 따라 작동하는 정적으로 유형이 지정된 언어가 있습니다. 유형 오류를 유발할 수 있음을 증명할 수있는 모든 프로그램을 거부하고 할 수없는 모든 프로그램을 통과시킵니다. 따라서 유형 오류가있는 프로그램을 허용 할 수 있습니다 (예 : Typed Racket). 동적 유형과 정적 유형 사이의 하이브리드입니다. 그리고 일부는이 시스템에서 두 가지 장점을 모두 누릴 수 있다고 주장합니다.

정적 타이핑의 또 다른 장점은 컴파일 타임에 유형이 알려져 있으므로 컴파일러가이를 사용할 수 있다는 것입니다. 자바에서 우리가 할 경우 "string" + "string"3 + 3, 둘 다 +결국 텍스트 토큰이 완전히 다른 운영 및 자료를 나타내고, 컴파일러는 혼자 유형에서 선택할 수있는 알고있다.

이제 여기서는 매우 논란의 여지가 있지만 '동적 타이핑'이 존재하지 않습니다 .

논란의 여지가 있지만, 동적으로 유형이 지정된 언어는 이론적 관점에서 유형이 지정되지 않은 것이 사실 입니다. 그들은 단지 하나의 유형으로 정적으로 유형이 지정된 언어입니다. 간단히 말해서, 실제로 문맥 자유 문법으로 문법적으로 생성되는 언어입니다.

왜 유형이 없습니까? 모든 오퍼레이션마다 모든 오퍼레이션이 정의되고 허용되므로 '런타임 유형 오류'란 정확히 무엇입니까? 이론적으로 순수한 부작용 입니다. print("string")어떤 인쇄 작업 을 수행 하는 작업이 작업 인 length(3)경우 전자가 string표준 출력 에 쓰는 부작용 error: function 'length' expects array as argument.이 있습니다. 이론적으로 볼 때 동적으로 유형이 지정된 언어는 없습니다. 그들은 형식화되지 않았습니다

다이나믹 타입 언어의 명백한 장점은 표현력이라는 것입니다. 타입 시스템은 표현력의 한계 일뿐입니다. 그리고 일반적으로 타입 시스템을 가진 언어는 타입 시스템을 무시했을 때 허용되지 않는 모든 작업에 대해 정의 된 결과를 가지게되며 결과는 인간에게는 의미가 없습니다. 많은 언어들이 타입 시스템을 적용한 후 튜링 완성도를 잃습니다.

명백한 단점은 인간에게 무의미한 결과를 생성하는 작업이 발생할 수 있다는 사실입니다. 이를 막기 위해 동적으로 유형이 지정된 언어는 일반적으로 이러한 연산을 재정의하지 않고 무의미한 결과를 생성하지 않고 오류를 작성하여 프로그램을 중지시킬 수있는 부작용을 갖도록 재정의합니다. 이것은 전혀 '오류'가 아닙니다. 실제로 언어 사양은 일반적으로 이것을 암시합니다. 이것은 이론적 인 관점에서 문자열을 인쇄하는 것만 큼 언어의 동작입니다. 따라서 타입 시스템은 프로그래머가 코드 흐름에 대해 추론하여 이러한 일이 발생하지 않도록합니다. 또는 실제로, 이유는 그래서는 않습니다발생하는 것은 디버깅에있어서 어느 시점에서나 유용 할 수 있으며, 이는 '오류'가 아니라 언어의 잘 정의 된 속성임을 보여줍니다. 사실상, 대부분의 언어가 가지고있는 '동적 타이핑'의 단일 잔존물은 0으로 나누는 것을 막고 있습니다. 이것은 동적 타이핑의 유형이며, 유형이 없으며, 0보다 다른 유형은 다른 모든 숫자와 다른 유형입니다. 사람들이 '유형'이라고 부르는 것은 배열의 길이 또는 문자열의 첫 문자와 같은 데이텀의 또 다른 속성입니다. 그리고 동적으로 타이핑 된 많은 언어를 사용하여와 같은 것을 작성할 수 있습니다 "error: the first character of this string should be a 'z'".

또 다른 것은 동적으로 유형이 지정된 언어는 런타임에 사용 가능한 유형이 있으며 일반적으로 유형을 확인하고 처리하고 결정할 수 있다는 것입니다. 물론 이론 상으로는 배열의 첫 번째 문자에 액세스하고 그것이 무엇인지 보는 것만 큼 다르지 않습니다. 실제로, 당신은 자신의 동적 C를 만들 수 있습니다. 긴 long int와 같은 하나의 유형 만 사용하고 첫 8 비트를 사용하여 '유형'을 저장하고 그에 따라 검사하고 부동 소수점 또는 정수 추가를 수행하는 함수를 작성하십시오. 한 유형의 정적 유형 언어 또는 동적 언어가 있습니다.

실제로,이 모든 것이 보여 주듯이, 정적 타입 언어는 일반적으로 상용 소프트웨어를 작성하는 맥락에서 사용되는 반면, 동적 타입 언어는 일부 문제를 해결하고 일부 작업을 자동화하는 맥락에서 사용되는 경향이 있습니다. 정적으로 유형이 지정된 언어로 코드를 작성하는 것은 시간이 오래 걸리고 번거로운 작업입니다. 알 수없는 작업을 수행 할 수는 없지만 입력 시스템은 사용자가 작성하지 않은 오류를 방지합니다. 많은 코더는 시스템에 있기 때문에이 작업을 수행한다는 사실조차 모르지만 정적 언어로 코딩 할 때 유형 시스템이 잘못 될 수없는 일을 할 수 없다는 사실을 종종 해결합니다. 잘못되지 않을 것임을 증명할 수 없습니다.

내가 언급했듯이, 일반적으로 '정적 유형'은 무고한 것으로 판명 될 때까지 유죄 인 경우 2를 의미합니다. 그러나 형식 이론에서 자신의 형식 시스템을 파생시키지 않는 일부 언어는 규칙 1 : 무고한 유죄가 입증 될 때까지는 이상적인 하이브리드 일 수 있습니다. 아마도 Typed Racket이 당신을위한 것일 것입니다.

또한 더 터무니없고 극단적 인 예를 들어, 현재 'types'가 실제로 배열의 첫 번째 문자 인 언어를 구현하고 있습니다.이 언어는 데이터, 'type', 'type'의 데이터 자체입니다. 유형과 기준, 유형 자체를 가진 유일한 기준. 유형은 정적으로 제한되거나 정적으로 제한되지 않지만 런타임 정보를 기반으로 새 유형이 생성 될 수 있습니다.


1
"유형 시스템을 적용한 후 많은 언어가 튜링 완성도를 잃습니다." 일반적인 프로그래밍 언어에는 적용되지 않습니까? 내가 읽은 것으로부터, 정규 언어는 완전하지 않습니다
Răzvan Flavius ​​Panda

1
@ RăzvanPanda : Lajla는 아마도 Typed lambda 미적분학 이나 그들이 정리 프로 버에서 사용하는 일부 프로그래밍 언어의 변형을 언급했을 것입니다 . 많은 사람들이 정지를 보장하고 따라서 튜링이 완료되지 않은 프로그램 만 표현할 수 있습니다. 이러한 유형 시스템을 기반으로하는 실용적인 기능적 프로그래밍 언어는 코어 미적분을 재귀 유형으로 확장하여이 한계를 극복합니다.
hugomg

1
"소리가 매우 논란의 여지가 있지만, 동적으로 유형이 지정된 언어는 이론적 인 관점에서 유형이 지정되지 않은 것이 사실입니다." -... 순간에, 당신이 무슨 말을하는지 전혀 모른다는 것을 알고 있습니다. 동적 타이핑은 유형이 식별자가 아닌 값에 속한다는 것을 의미합니다. 프로그램을 증명하기는 어렵지만 반드시 불가능하지는 않습니다. 인라이닝 및 파라 메트릭 다형성은 이미 링크 타임 최적화의 개발로 이어졌습니다. 최적의 동적 유형 언어를 컴파일하는 것과 동일한 유형의 문제를 해결합니다. 가능한 모든 입력 및 출력을 알고 있습니다.
DeftlyHacked

25

아마도 동적 타이핑의 가장 큰 "혜택"은 더 얕은 학습 곡선 일 것입니다. 학습해야 할 형식 시스템이없고 형식 제약 조건과 같은 모퉁이의 경우 사소한 구문이 없습니다. 이를 통해 훨씬 더 많은 사람들이 동적 타이핑에 액세스 할 수 있으며 정교한 정적 유형 시스템에 접근 할 수없는 많은 사람들이 실현 가능합니다. 결과적으로 교육의 맥락 (예 : MIT의 Scheme / Python)과 프로그래머가 아닌 사람을위한 도메인 별 언어 (예 : Mathematica ) 에서 동적 타이핑이 발생했습니다 . 또한 동적 언어는 경쟁이 거의 없거나 전혀없는 틈새 시장에도 영향을 미쳤습니다 (예 : Javascript).

가장 간결한 동적 유형 언어 (예 : Perl, APL, J, K, Mathematica )는 도메인 에 따라 다르며 설계된 간극 에서 가장 간결한 범용 정적 유형 언어 (예 : OCaml ) 보다 훨씬 간결 할 수 있습니다. .

동적 타이핑의 주요 단점은 다음과 같습니다.

  • 런타임 유형 오류

  • 동일한 수준의 정확성을 달성하기가 매우 어려우거나 심지어 실질적으로 불가능할 수 있으며 훨씬 더 많은 테스트가 필요합니다.

  • 컴파일러 검증 문서가 없습니다.

  • 정교한 최적화에 의존하여 성능이 좋지 않은 경우 (일반적으로 런타임에 가끔 컴파일 시간에 스탈린 구성표 대신)와 예측할 수없는 성능이 발생합니다.

개인적으로 나는 역동적 인 언어로 자랐지 만 다른 가능한 옵션이 없다면 전문가로 40 '극으로 만지지 않았습니다.


2
나는 진입 장벽이 낮다고 말하지만 숙달은 학습 곡선에 지나지 않습니다.
Erik Reppen

학습 할 유형 시스템이 없기 때문에 학습 곡선이 줄어 듭니까?
Jon Harrop

여전히 타입 시스템이 있습니다. 부울과 문자열을 추가 할 때 어떤 일이 발생하는지에 대해 합리적인 추측을 할 수 있지만, 동적으로 유형이 지정된 언어로 유형이 어떻게 강요되는지에 대한 실제 세부 정보를 아는 데 도움이되는 경우가 많습니다. 그것은 많은 엄격한 사람들이 얻지 못하는 것입니다. 우리는 실제로이 것들을 배웁니다.
Erik Reppen

@ErikReppen : 우리는 "타입 시스템"의 다른 정의를 사용하고 있습니다. 정적 유형 시스템, 예를 들어 대수적 데이터 유형, 제네릭을 배울 필요가 없다고 언급했습니다. 당신이 말하는 "유형"은 단지 데이터입니다. 일부 함수는 런타임에 일부 데이터를 거부한다는 사실은 보편적입니다.
Jon Harrop

12

Artima의 타이핑 : Strong vs. Weak, Static vs. Dynamic 기사 :

강력한 타이핑은 일치하지 않는 유형 간의 혼합 작업을 방지합니다. 유형을 혼합하려면 명시 적 변환을 사용해야합니다

타이핑이 약하다는 것은 명시적인 변환없이 유형을 혼합 할 수 있음을 의미합니다

파스칼 코스 탄자의 논문에서 Dynamic vs. Static Typing-패턴 기반 분석 (PDF)에서 정적 타이핑은 동적 타이핑보다 오류가 발생하기 쉽다고 주장합니다. 정적으로 타이핑 된 일부 언어는 "올바른 일"을 수행하기 위해 동적 타이핑을 수동으로 에뮬레이션하도록합니다. Lambda the Ultimate 에서 논의되었습니다.


1
"정적 타이핑은 동적 타이핑보다 오류가 발생하기 쉽습니다"-예, 두 배 예! 나는 두 가지 유형의 언어 모두에서 많은 경험을 쌓았으며 모든 경우 동적 언어는 "그냥 작동합니다."정적에는 2 배의 디버깅 시간이 필요합니다 (C ++ 및 Delphi 참조). 이것은 종종 유형 문제, 특히 모듈과 함수가 미친 유형 사이에 데이터를 전달하기 때문에 발생합니다. 동적 언어로 인해 발생할 수있는 모든 종류의 이론적 버그가 있지만 실제로는 프로그래머가 역학 유형을 잘못 사용하지 않는 한 유형 강제로 인한 버그가 발생하는 경우는 매우 드 rare니다.
dallin

7
몇 년 전에 Costanza 논문 초안을 읽었습니다. 그가 "정적"이라고 쓴 모든 곳에서 그는 실제로 "자바"를 의미했습니다. 나는 그에게 그의 주장을 반증하는 OCaml과 같은 언어로 수십 가지 반례를했지만 어쨌든 그것을 출판했다. 그 논문의 모습으로, 그는 여전히 똑같은 넌센스를 출판하고 있습니다. 예를 들어,이 백서에서 그는 "C #은 일반적으로 잘못된 Java 사본입니다"라고 주장합니다. 그것은 과학적인 논문에서 자리가 없습니다 ...
Jon Harrop

@dallin 내 경험은 완전히 반대입니다 .C, C ++, Java, Python, Perl 등에서 많은 프로그램을 작성 해야하는 경우 강제로 설정하지 않으면 동적 유형 언어로 작은 조정 프로그램보다 큰 것을 시작하지 않습니다. 파이썬에서는 WSGI 프로젝트에 대해 생각할 때 여전히 떨립니다. 오버 리터 해야하는 콜백은 객체 참조로 전달되었으며 코드는 때때로 객체가 아니라 일부 원소 유형이라는 것이 밝혀져 충돌했을 때 정상적으로 작동하는 것처럼 보입니다. 전달되고 있습니다. 이와 같은 버그가있는 물건을 쉽게 만들 수있는 언어는 매우 위험합니다.
Michael Beer

@MichaelBeer 또한 C / C ++와 같이 직접 메모리를 관리 할 수있는 언어는 위험하다고 말할 수 있습니다! 나는 몇 시간 동안 메모리 오류로 확실히 씨름했습니다. 거대한 Java 프로젝트도 소풍이 아닙니다. 모든 언어에서 언어의 위험과 모범 사례를 이해해야합니다. 내가 해본 적이있는 최악의 프로젝트는 구조가 거의없는 팀 PHP 프로젝트 였지만 좋은 프레임 워크와 좋은 프로그래밍 방식을 사용했을 때 꿈이었던 동적 언어로 프로젝트를 진행했습니다.
dallin

@dallin 동의합니다. 모든 언어에는 함정이 있습니다. 그러나 내가 언급 한 결함은 동적으로 유형이 지정된 언어에 내재되어 있으며 메모리를 직접 조작 할 수있는 가능성은 정적으로 유형이 지정된 언어의 고유 속성이 아닙니다. mem을 직접 조작 할 수있는 동적 유형 언어를 상상할 수 있습니다. 나는 C ++이 단순한 파괴 자라는 데 동의한다. 언어를 발명 한 사람은이 행성의 한 사람 만이 언어의 모든 부분을 알 수 없다고 믿는다. 그러나 이것은 C ++이 정적으로 타이핑되는 것이 아니라 30 년 이후 성장해온 몬스터에 대한 비난은 아닙니다.
Michael Beer

3

상황에 따라 다릅니다. 동적 유형 시스템 및 강력한 유형 시스템에 적합한 많은 이점이 있습니다. 동적 유형 언어의 흐름이 더 빠르다는 의견입니다. 동적 언어는 클래스 속성과 컴파일러에서 코드에서 무슨 일이 일어나고 있는지 생각하는 데 제약이 없습니다. 약간의 자유가 있습니다. 또한 동적 언어는 일반적으로 표현력이 뛰어나고 코드가 적어 좋습니다. 그럼에도 불구하고 오류가 발생하기 쉽고 의심 할 여지가 있으며 단위 테스트 범위에 더 의존합니다. 동적 언어로 프로토 타입을 제작하는 것은 쉽지만 유지 보수는 악몽이 될 수 있습니다.

정적 유형 시스템에 비해 주요 이점은 IDE 지원 및 정적 코드 분석기입니다. 코드가 변경 될 때마다 코드에 대한 자신감이 높아집니다. 유지 관리는 이러한 도구를 사용하여 케이크의 평화입니다.


0

정적 언어와 동적 언어에 대해서는 여러 가지가 있습니다. 저에게 가장 큰 차이점은 동적 언어에서 변수에는 고정 유형이 없다는 것입니다. 대신, 유형은 값에 연결됩니다. 이 때문에 실행되는 정확한 코드는 런타임까지 결정되지 않습니다.

초기 또는 순진한 구현에서 이것은 큰 성능 저하이지만 최신 JIT는 정적 컴파일러 최적화를 통해 얻을 수있는 최상의 성능에 가깝습니다. (일부 프린지의 경우 그보다 낫습니다).


0

모든 작업에 적합한 도구입니다. 시간의 100 %도 나아지지 않습니다. 두 시스템 모두 사람에 의해 만들어졌으며 결함이 있습니다. 미안하지만, 우리는 빨고 완벽한 것을 만듭니다.

동적 타이핑이 방해가 되었기 때문에 동적 타이핑을 좋아하지만 런타임 오류로 인해 계획하지 않은 오류가 발생할 수 있습니다. 정적 타이핑은 위에서 언급 한 오류를 해결할 수 있지만 초보자 (유형 언어) 프로그래머는 상수 문자와 문자열 사이를 캐스팅하려고 미치게 만듭니다.


-3

정적 입력 : Java 및 Scala와 같은 언어는 정적 유형입니다.

변수는 코드에서 사용되기 전에 정의되고 초기화되어야합니다.

예를 들어. int x; x = 10;

System.out.println (x);

동적 입력 : Perl은 동적 유형 언어입니다.

변수를 코드에서 사용하기 전에 초기화 할 필요가 없습니다.

y = 10; 코드의 후반부에서이 변수를 사용하십시오.


5
이것은 타입 시스템과 관련이 없습니다.
Thiago Negri
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.