대답 1:

Robert Harper는 동적 유형 언어는 단일 유형의 정적 유형 언어 일 뿐이라는 차이점이 있습니다. 그리고 그것은 실제로 그 차이가 무엇인지, 그러나 그 대답은 대부분의 사람들에게 거의 쓸모가 없습니다. 또한, 특정 언어를 사용하는 기능적 언어의 차이점을 구체적으로 요청하여이 질문을 특히 흥미롭게 만듭니다.

Amber Anand가 이미 다른 대답 (그리고 여기에 꽤 좋은 대답)에서했던 것처럼 컴파일러의 기술로 이것을 대답하는 대신, 내 대답은 언어학의 관점과의 차이점을 살펴볼 것입니다. 그리고 나서 이것이 하나를 선택하는 기능적 언어에 어떤 영향을 미치는지에 대한 실제적인 예로 결론을 내릴 것입니다.

—— — — — — — — — — — — — — — — — — — — — — — — — —

(유형 시스템에 대해 잘 알고 있다면 이것을 건너 뛸 수 있습니다)

언어와 문법에 대하여

프로그래밍 언어는 기호 (예 : 기호 "="또는 기호 "a")와 이러한 기호의 결합 방법을 정의하는 문법으로 구성됩니다. 이런 의미에서 프로그래밍 언어는 영어 (또는 다른 자연어)와 매우 유사합니다. 영어에는 기호 (문자, 숫자 및 문장 부호), 단어 (기호의 조합 임) 및 이들을 조합하여 문장을 만드는 방법이 있습니다.

또한 영어는 "동사"또는 "명사"와 같이 각 단어에 특정 범주를 지정하고 일부 문법에서는 이러한 범주를 매우 구체적인 방식으로 만 (Subject-Verb-Object와 같이) 결합 할 수 있다고 규정합니다. 그렇지 않으면 문장이 유효하지 않습니다.

예를 들어 Normative English에서는 다음과 같이 말할 수 있습니다.

"내 차가 빨리 달린다"

그러나 당신은 말할 수 없습니다 :

"자동차 빨리 내 실행"

이 문장은 모든 기호와 단어가 유효하지만 전달하는 정보가 동일하더라도 규범 영어에서는 유효하지 않습니다. Verb-Object-Subject 구조를 사용하는 언어에 대해 이야기하고 있다면, 이것은 다른 방법 일 것이고“내 차는 빨리 달린다”는 잘못된 것입니다.

이제 프로그래밍 언어는 문법을 통해 동일한 방식으로 작성된 프로그램을 제한합니다. 예를 들어, Elm에서는 다음 프로그램이 유효합니다.

x + 1에서 x = 1이라고하자

그러나 유효한 Elm 단어 인 단어 만 사용하더라도 다음 프로그램은 아닙니다.

let + 1에서 let = 1

이 제한은 일반적으로 "정적 입력"이라고하는 것이 아니지만 비슷합니다. 지금은 이것을 "문법 제한"이라고합니다.

따라서 문법은 기호를 정의하고 이러한 기호의 의미와 결합 방법을 알려주고 이러한 조합에 범주를 할당 한 다음 해당 범주에 따라 추가 조합을 제한합니다. 이 경우 특히 "let"= ""는 "let"이 "keyword"범주이고 "let"키워드 뒤에 와야하는 단어는 "identifier"범주 여야하므로 유효하지 않습니다.

자연어와 마찬가지로 각 프로그래밍 언어에는 문법에 대한 제한이 다릅니다. 이러한 다른 제한은 동일한 의미를 전달하는 다른 방법으로 이어집니다. 그 이상으로, 이러한 다른 제한은 다른 관용구를 야기합니다. 즉, 단어가 배열되는 순서는 한 언어에서 다른 언어로 변경 될뿐만 아니라 다른 개념이 나타나거나 이해되는 전체 방식입니다. 이는 툴링 외에도 정적 FPL과 동적 FPL의 차이점을 이해하는 데 중요합니다. 나중에 다시 방문하겠습니다.

문법 기반 제한이 너무 제한적입니다

사람들이 프로그램을 작성할 수있는 방법 (정적 타이핑의 전체 요점)을 제한 할 수 있기 때문에 왜 다른 것이 필요한가? 기술적으로 우리는 다른 것을 필요로하지 않을 것입니다. 3 년 전, 구문 제한이 정적 타이핑을 불필요하게 만드는 방법에 대해 (반 농담) 썼습니다. 언어 문법에 더 많은 제한을가할수록 필요한 추가 제한 (유형)이 가장 적습니다.

문법 기반 제한의 문제점은 너무 제한적이므로 문법이 더 제한적이면 언어의 표현력이 떨어 지므로 프로그램을 작성하는 데 많은 노력이 필요합니다. 예를 들어, 함수를 구문 구조로 만들면 사용중인 함수를 알기 위해 유형 시스템이 필요하지 않습니다. 함수를 잘못 사용하면 런타임 또는 유형 확인 오류 대신 구문 분석 오류가됩니다.

// Canelés는 내가 쓰고있는 언어로 구문 기능이 있습니다. // 다음과 같이 정의합니다. define greet (greeting) do return "hello, $ {greeting}"; end // 이것은 괜찮습니다 : // (동적 타이핑을 사용하더라도 정적 분석이 가능합니다) greet ( "world"); // ==> "hello, world"// 구문 분석 오류입니다. [ "world"]. map (greet);

위의 예에서 언어가 덜 제한적인 문법을 선택하는 이유를 알 수 있습니다. Canelés에는 구문 기능이 있습니다. 즉, 값이 아니며 문법적 구성 요소이며 매우 구체적인 방식으로 만 사용할 수 있습니다. 이 경우 이름으로 함수를 호출 할 수 있지만 해당 함수를 변수에 할당하거나 배열에 저장하거나 다른 함수에 인수로 전달할 수 없습니다.

그것은 대부분의 사람들에게 이상적이지 않으므로 문법 기반 제한을 사용하는 대신 추가 제한을 설정하려는 언어 (어떤 이유로 든)를 사용하는 유형 시스템을 사용하십시오. 즉, 정적으로 유형이 지정됩니다.

유형 시스템 및 언어

따라서 유형 시스템은 언어가 채택 할 수있는“추가 제한 시스템”과 거의 같습니다. 유형 체계는 문법 규칙이 아니더라도 프로그램의 구문 유효성에 제약을줍니다.

예를 들어 영어로는 다음과 같이 말할 수 있습니다.

"제 차가 빨리 걷습니다."

단어는 유효한 영어이며 영어 문법에 올바른 순서로 정렬됩니다. 그럼에도 불구하고,이 문장은 아마도 대부분의 사람들에게 의미가 없을 것입니다. 차는 결국“걷지”않습니다.

영어에 유형 시스템 (예 : 추가 제한 사항)을 추가하여이 문제를 해결할 수 있는데, 이는 "자동차 과목"이 "보행"할 수 없음을 나타냅니다.

“Car”가 주제라고 가정하고“Car”동사를“run”으로 가정하고“Run”형용사를“fast”로 가정;“내 차가 빨리 걷는다”

자동차는“달릴”수 있기 때문에 이것은 이제 유효하지 않은 문장입니다. “* @ &) * (! @ & #) *”를 쓰는 것과 같습니다.

이는 동적 언어 (문법 제약 조건 만)와 정적 언어 (문법 + 추가 논리 제약 조건, 일반적으로 언어 사용자가 정의)의 주요 차이점입니다. 동적 (또는 유형이 지정되지 않은) 언어를 사용하면 아무 의미가없는 문장이라도 쓸 수 있습니다. 정적 (또는 타이핑 된) 언어는 이해하기 쉬운 문장을 쓰지 못하게합니다.

—— — — — — — — — — — — — — — — — — — — — — — — — —

유형은 프로그래밍 언어에 어떤 영향을 줍니까?

앞에서 언급했듯이 언어에 제한이 있으면 사람들이 해당 언어로 특정 개념을 표현하는 방식과 이들이 만들 관용구에 영향을 미칩니다. 따라서이 결정은 개념에 대한 추론 방법과 이러한 개념을 표현하는 방법에 직접적인 영향을줍니다.

이는 동적 타이핑을 사용하는 기능 언어 (Racket 또는 Clojure 등)와 정적 타이핑을 사용하는 기능 언어 (Haskell 또는 OCaml 등)의 주요 차이점은 사람들이 이러한 개념을 표현하는 방식입니다.

예를 들어, 목록에서 항목을 찾으려면 Clojure와 같은 동적 언어로 수행하는 방법입니다.

(defn find [predicate list] (if-let [item (first list)] (if (predicate item) item (find predicate (rest list)))))

그리고 이것이 하스켈과 같은 정적 언어로 수행하는 방법입니다.

데이터 아마도 a = 아무것도 | 그냥 찾기 :: (a-> Bool)-> [a]-> 어쩌면 찾기 p [] = 아무것도 찾을 수 없음 p (x : xs) = if (px) 다음 x는 find p xs

여기서 코드의 양은 거의 동일하지만 접근 방식은 매우 다릅니다. Clojure의 "찾기"는 "없는"모든 것에 대해 특별한 "nil"값을 사용합니다. "(first [])"는 nil을 반환하고, "(first" ")"는 nil을 반환합니다. (if-let) nil이 아닌 경우 바인딩하고, 그렇지 않으면 nil을 반환합니다. Nil은 Clojure의 모든 곳에 있으며 사람들은이 관용구를 활용하여 코드를 작성합니다.

그러나 Haskell에는 "nil"이 없습니다. 또는 오히려 Haskell에서는“nil”과 같은 값을 가질 수 없으므로 Clojure 사람들이 그렇게 많이 사용하는 관용구는 Haskell과 유사하지 않습니다. 유형 시스템에서는 반환 값에 대해 정확히 하나의 유형을 선택해야합니다. 즉, "find"는 일관된 유형의 값을 반환해야합니다. 유형을 한정하거나 둘 이상의 값을 리턴 할 수있는 상황을 처리하려면 어쩌면과 같이 많은 특정 유형을 작성해야합니다.

물론 반환 유형은 이러한 차이점 중 하나 일뿐입니다. 컬렉션 유형과 같은 것은 정적 언어와 동적 언어 사이에서 다르게 사용됩니다. 정적 언어는 통합 유형이나 하위 유형을 사용하지 않는 한 동종 컬렉션 구조 만 가질 수 있지만 동적 언어는 하나의 컬렉션에 모든 종류의 값을 넣을 수 있습니다. 이기종 콜렉션은 실제로 일반적으로 표준입니다.

정적 언어가 사람들이 동적 언어로 원하지만 관용적 인 구현 방법이없는 관용구를 제공하는 경우도 있습니다. Haskell의 리턴 유형 다형성은 모나드 시퀀싱에 사용됩니다 (표기법). 이러한 모든 관용구를 한 언어와 다른 언어로 이식 할 수는 있지만 구문이 너무 많거나 줄 바꿈 / 언 랩핑으로 인해 너무 많은 오버 헤드가 있기 때문에 실제로는 실용적이지 않은 것으로 끝납니다.

(따라서 리플렉션 기반 메타 프로그래밍과 같은 동적 언어의 고급 사용은 정적 언어에서는 불가능합니다. 또는 이러한 관용구를 퍼베이시브하게 만드는 방식으로는 불가능합니다).

이러한 관용구의 차이는 물론 정적 및 동적 기능 언어로 제한되지 않습니다. 다른 유형 시스템의 다른 제한은 다른 관용구로 이어집니다. 사람들이 Haskell에서 레코드를 사용하는 방식은 사람들이 Elm에서 레코드를 사용하는 방식과 다릅니다. Elm의 형식 시스템은 행 다형성을 지원하므로 Elm의 레코드는 Haskell (정적으로 형식화 됨)에서 사용되는 방식보다 JavaScript (동적 형식화 됨)와 같은 언어에서 사용되는 방식에 훨씬 가깝습니다.

나는 다른 Quora 답변에서 일반적으로 기능 언어의 차이점에 대해 썼습니다 : Quildreen Motta의 답변 Haskell, Clojure, Scala, Erland 및 F #과 같은 주요 현대 기능 언어는 어떻게 다른가요?

그리고 툴링이 있습니다

물론 타입 시스템은 프로그램에 큰 영향을 주지만 툴링에도 영향을 미칩니다. 최소한 툴링은 사람들이 프로그래밍 문제에 접근하는 방식과 깊이 통합되어 있지만 어떤 사람들은 그렇게 생각하지 않을 수도 있습니다. 타입 시스템이 툴링과 워크 플로우에 영향을 미치는 주요 방법을 요약하려고합니다 :

  • 타입 시스템은 사람들에게 디자인 제약을 쉽게 적용 할 수있는 방법을 제공하기 때문에 Type Driven Development라는 전체 디자인 방법론이 있습니다. 물론 T (ype) DD는 동적 언어와 정적 언어 모두에서 작동하지만 동적 언어는 정적으로 분석하기가 어렵 기 때문에 도움이되는 툴이 필요하지 않습니다. 정적 언어의 컴파일러는 프로그램을 빠르게 요약 할 수 있습니다. 변경 후 유효하거나 유효하지 않으며 유효하지 않은 경우에는 무엇이 잘못 되었습니까? 타입 추론과 소프트 타이핑과 같은 것은 동적 언어의 경우에 근사 할 수 있지만 정적 언어보다 덜 효과적 일뿐만 아니라 유형 오류가보고되는 방식에 유사하거나 더 나쁜 문제가 있습니다. 모든 제한 사항이 사전에 적용됩니다. 이것은 실험에 흥미 롭습니다. Haskell (및 다른 정적 언어)은 Holes로이를 근사 할 수 있지만 동일하지 않습니다. 정적 언어를 사용하면 IDE의 지능형 자동 완성과 같은 툴링을 쉽게 개발할 수 있습니다. 동적 언어는 형식 유추 및 실시간 실행 (예 : Pharo)으로이를 근사 할 수 있지만 유추 된 형식은 모호한 경향이 있습니다. 동적 언어는 이해하기 쉬운 오류 메시지를 갖는 경향이 있으며 프로그램이 실행될 때 발생하기 때문에 가능합니다. 오류가 발생하는 이유를 이해하기 위해 디버거를 사용합니다. 정적 언어에 대한 이것에 대한 연구는 충분하지 않지만 정적 유형 오류에 대한 Seidel 등의 동적 증인은 유망 해 보였다. 이것이 Purr가 다이나믹 타입 시스템에서 구문 제한을 사용하는 주된 이유이며, 주로 프로그래밍 교육을위한 기능적 언어입니다.

—— — — — — — — — — — — — — — — — — — — — — — — — —

참조

  1. 동적 언어는 Robert Harper의 정적 언어입니다 .Sam Tobin-HochstadtTypes Might Not Matter!에 의해 유형이 지정되고 유형이 지정되지 않은 "단일 형식의"언어로 Quildreen MottaQuildreen Motta의 답변 동적 유형 프로그래밍 언어에 대한 매력은 무엇입니까? 동적 유형 언어의 Eric NormandMonads, Tony Garnock-Jones 기능성 진주에 의한 Punning (또는 Null 포인터는 그렇게 나쁘지 않은 것으로 간주 함) : 묵시적 구성 또는 유형 클래스는 Oleg Kiselyov 및 Chung-chieh ShanQuildreen Motta의 유형 값을 반영합니다. 답변 Haskell, Clojure, Scala, Erland 및 F #과 같은 현대의 주요 기능 언어는 어떻게 다릅니 까? Tobias Lindahl의 성공 입력, Robert Cartwright의 Konstantinos SagonasSoft 입력 및 Mike에 의한 실제 유형 추론 FaganSkalpel : Eric L. Seidel, Ranjit Jhala 및 W의 정적 유형 오류 (또는 일반적으로 잘못된 유형의 프로그램이 잘못됨)에 대한 GHCDynamic 목격자의 SML 유형 구멍에 대한 유형 오류 슬라이서 estley WeimerTypes Gary BernhadtType Systems, Luca Cardelli의 프로그래밍 언어를 아는 사람