현대식 프로그래밍 언어에서 왜 타입이 변수 이름 뒤에 오는가? 변수 선언에서 변수 이름 뒤에

거의 모든 현대 프로그래밍 언어 (Go, Rust, Kotlin, Swift, Scala, Nim, Python last version)에서 유형이 항상 변수 선언에서 변수 이름 뒤에 오는 이유는 무엇입니까?

x: int = 42그렇지 int x = 42않습니까?
후자는 전자보다 더 읽기 쉽지 않습니까?
트렌드 일까, 아니면이 솔루션 뒤에 정말 의미있는 이유가 있습니까?



답변

언급 한 모든 언어는 형식 유추를 지원 합니다., 유형이 쉽게 결정되는 유형의 초기화 표현식을 제공 할 때 자체적으로 입력 할 수 있기 때문에 유형이 해당 언어로 선언의 선택적 부분입니다 .

표현식의 선택적 부분을 오른쪽으로 더 멀리 배치하면 구문 분석 모호성이 줄어들고 해당 부분을 사용하는 표현식과 사용하지 않는 표현식 사이의 일관성이 향상되기 때문에 중요합니다. var선택 사항에 도달하기 전에 키워드와 변수 이름이 모두 필수 인 것을 알면 선언을 구문 분석하는 것이 더 간단합니다 . 이론적으로, 컴퓨터가보다 쉽게 분석 할 수 있도록 그 모든 것들을 해야 너무 인간에 대한 전반적인 가독성을 향상,하지만 더 많은 논쟁의 여지가있다.

당신과 같은 C ++와 같은 “비 현대적인”언어가 모든 옵션 유형 수정, 고려할 때이 인수는 특히 강력한 얻는다 *포인터를 들어 &, 참조를 들어 const, volatile등등. 여러 선언에 쉼표를 넣으면 포인터를 int* a, b;만들지 않는 것과 같은 이상한 모호한 점이 생깁니다 b.

심지어 C ++는 지금의 형태로 선언 “오른쪽 유형”을 지원 auto x = int{ 4 };하고, 그것은 몇 가지 장점을 가지고있다 .


답변

거의 모든 현대 프로그래밍 언어 (Go, Rust, Kotlin, Swift, Scala, Nim, 심지어 Python 마지막 버전)에서 유형이 항상 변수 선언 이후에 오는 이유는 무엇입니까?

전제는 두 가지 측면에서 결함이 있습니다.

  • 식별자 앞에 유형이있는 새로운 프로그래밍 언어가 있습니다 . 예를 들어 C♯, D 또는 실론입니다.
  • 식별자 뒤에 유형이있는 것은 새로운 현상이 아니며, 적어도 Pascal (1968-1969 년에 발표 된 1970 년에 발표)로 돌아가지만 실제로는 수학 유형 이론에 사용되어 ~ 1902에서 시작합니다. ML (1973), CLU (1974), Hope (1970s), Modula-2 (1977–1985), Ada (1980), Miranda (1985), Caml (1985), Eiffel (1985), Oberon에서도 사용되었습니다. (1986), Modula-3 (1986-1988) 및 Haskell (1989).

Pascal, ML, CLU, Modula-2 및 Miranda는 모두 매우 영향력있는 언어 였으므로 이러한 유형의 선언이 인기를 유지 한 것은 놀라운 일이 아닙니다.

x: int = 42그렇지 int x = 42않습니까? 후자는 전자보다 더 읽기 쉽지 않습니까?

가독성은 친숙한 문제입니다. 개인적으로 중국인은 읽을 수 없지만 중국인은 읽을 수없는 것으로 보입니다. 학교에서 파스칼을 배우고, 에펠, F♯, 하스켈, 스칼라를 습격하고 TypeScript, Fortress, Go, Rust, Kotlin, Idris, Frege, Agda, ML, Ocaml 등을 살펴보면… .

그것은 단지 추세일까요, 아니면 그러한 해결책 뒤에 정말로 의미있는 이유가 있습니까?

그것이 추세라면, 그것은 꽤 영속적입니다. 제가 언급했듯이, 수학에서 백 년 전으로 거슬러 올라갑니다.

식별자 다음에 유형을 갖는 주요 이점 중 하나는 유추하려는 경우 유형을 쉽게 제외 할 수 있다는 것입니다. 선언이 다음과 같은 경우 :

val i: Int = 10

그런 다음 유형을 생략하고 다음과 같이 추론하는 것이 쉽지 않습니다.

val i = 10

반면에 타입이 식별자 앞에 오는 경우 :

Int i = 10

그런 다음 구문 분석기가 표현식을 선언과 구별하기가 어려워집니다.

i = 10

언어 디자이너가 일반적으로 생각하는 해결책은 유형 대신 작성해야하는 “유형을 작성하고 싶지 않습니다”키워드를 소개하는 것입니다.

var  i = 10; // C♯
auto i = 10; // C++

그러나 이것은 실제로 의미가 없습니다. 기본적으로 유형을 쓰지 않는다는 유형을 명시 적으로 작성해야합니다. 응? 그냥 빼는 것이 훨씬 쉽고 합리적이지만 문법이 훨씬 복잡해집니다.

(그리고 C의 함수 포인터 타입 에 대해서도 이야기하지 않겠 습니다.)

앞서 언급 한 여러 언어의 설계자들이이 주제에 무게를 두었습니다.

  • Go FAQ (참조 : Go ‘s Declaration Syntax ) :

    왜 선언이 거꾸로됩니까?

    C에 익숙하다면 그것들은 거꾸로되어 있습니다. C에서, 변수는 타입을 나타내는 표현식처럼 선언됩니다. 좋은 생각이지만, 타입과 표현식 문법은 잘 섞이지 않습니다. 결과는 혼란 스러울 수 있습니다. 함수 포인터를 고려하십시오. Go는 대부분 식과 형식 구문을 분리하며 사물을 단순화합니다 ( *포인터에 접두사 를 사용 하는 것은 예외입니다). C에서 선언

    int* a, b;
    

    a포인터로 선언 하지만 그렇지 않습니다 b. 이동 중

    var a, b *int
    

    둘 다 포인터로 선언합니다. 이것은 더 명확하고 규칙적입니다. 또한, :=짧은 고지서 전체 변수 선언과 같은 순서를 제시한다고 주장 :=때문에

    var a uint64 = 1
    

    같은 효과가 있습니다

    a := uint64(1)
    

    또한 표현 문법이 아닌 유형에 대해 고유 한 문법을 ​​사용하여 구문 분석을 단순화 할 수 있습니다. 같은 키워드 func와는 chan명확하게하기.

  • 코 틀린 FAQ :

    왜 타입 선언이 오른쪽에 있습니까?

    코드를 더 읽기 쉽게 만든다고 생각합니다. 게다가, 그것은 좋은 구문 기능을 가능하게합니다. 예를 들어, 타입 주석을 남기기 쉽습니다. 스칼라는 또한 이것이 문제가되지 않는다는 것을 잘 증명했다.

  • 스칼라 프로그래밍 :

    Java와의 주요 편차는 유형 주석의 구문과 관련이 있습니다. Java에서 ” variable: Type“대신 ” Type variable“입니다. 스칼라의 접미사 유형 구문은 Pascal, Modula-2 또는 Eiffel과 유사합니다. 이 편차의 주된 이유는 유형 유추와 관련이 있으며, 종종 변수의 유형 또는 메소드의 반환 유형을 생략 할 수 있습니다. ” variable: Type“구문을 사용하면 이 작업이 쉬워집니다. 콜론과 유형은 그대로 두십시오. 그러나 C 스타일 ” Type variable“구문에서는 단순히 유형을 생략 할 수 없습니다. 더 이상 정의를 시작하기위한 마커가 없습니다. 누락 된 유형 (일부 유형 유추를 수행하는 C♯ 3.0, var이 목적으로 사용)에 대한 자리 표시자가 되려면 대체 키워드가 필요합니다 . 이러한 대안 키워드는 스칼라의 접근 방식보다 임시적이고 덜 규칙적입니다.

참고 : Ceylon의 설계자들은 접두사 유형 구문을 사용하는 이유를 문서화했습니다 .

접미사 유형 주석 대신 접두사

왜 파스칼과 ML 대신 선언 이름 뒤에 주석을 달 때 C와 Java를 따라 유형 주석을 먼저 넣습니까?

우리는 이것을 생각하기 때문에 :

shared Float e = ....
shared Float log(Float b, Float x) { ... }

이것보다 훨씬 쉽게 읽을 수 있습니다.

shared value e: Float = ....
shared function log(b: Float, x: Float): Float { ... }

그리고 우리는 다른 사람이 어떻게 다르게 생각할 수 있는지 이해하지 못합니다!

개인적으로, 나는 그들의 “인수”가 다른 사람들보다 훨씬 더 설득력이 있다고 생각합니다.


답변

파스칼도 그렇게하고 새로운 언어는 아닙니다. 그것은 처음부터 고안된 학문 언어였습니다.

변수 이름으로 시작하는 것이 의미 적으로 더 명확하다고 말하고 싶습니다. 유형은 기술적 인 세부 사항입니다. 실제 모델과 같은 클래스를 읽고 싶다면 엔티티의 이름을 먼저 지정하고 기술적 구현을 ​​마지막에 배치하는 것이 좋습니다.

C #과 Java는 C에서 유래하므로 “선행 기술”을 존중해야하므로 숙련 된 프로그래머를 혼동하지 마십시오.


답변

x: int = 42그렇지 int x = 42않습니까? 후자는 전자보다 더 읽기 쉽지 않습니까?

이러한 간단한 예에서는 큰 차이가 없지만 조금 더 복잡하게 만들어 봅시다. int* a, b;

이것은 C에서 실제로 유효한 선언이지만 직관적으로 보이는 것처럼 행동하지 않습니다. 우리는 type의 두 변수를 선언하는 것처럼 int*보이지만 실제로는 one int*과 one을 선언 하고 int있습니다.

언어가 선언에서 변수 이름 뒤에 유형 넣으면 그 문제를 해결할 수 없습니다.