헝가리어 표기법이 표현이 불충분 한 정적 입력을 가진 언어에 대한 해결 방법입니까? [닫은]


28

에릭 리퍼 (Eric Lippert)의 기사 에서 헝가리 표기법은 어떻게 되나요? 그는 헝가리 표기법 (좋은 종류)의 목적이

스토리지 표현 정보 외에 시맨틱 정보를 포괄하도록 "유형"개념을 확장한다.

간단한 예로는 X 좌표를 나타내는 "x"를 나타내는 변수와 "y"를 나타내는 Y 좌표를 나타내는 변수를 접두사로 쓸 수 있습니다. xFoo + yBar코드가 분명히 잘못 보입니다.

그러나 나는 Haskell의 타입 시스템에 대해서도 읽었으며, Haskell에서 실제 타입을 사용하여 동일한 의미를 달성 할 수있는 것 같습니다 (즉 "시맨틱 정보를 포함하도록 타입 개념을 확장"). 컴파일러가 확인할 을 . 따라서 위의 예 xFoo + yBar에서 Haskell 에서는 프로그램이 올바르게 호환되지 않는 유형으로 선언되어 있기 때문에 프로그램을 올바르게 설계하면 실제로 컴파일에 실패합니다. 즉, Haskell의 형식 시스템이 헝가리어 표기법과 동등한 컴파일 타임 검사를 효과적으로 지원하는 것처럼 보입니다.

헝가리 표기법은 타입 시스템이 의미 정보를 인코딩 할 수없는 프로그래밍 언어에 대한 반창고 일 뿐입니 까? 또는 헝가리 표기법은 Haskell과 같은 정적 유형 시스템이 제공 할 수있는 것 이상의 것을 제공합니까?

(물론, 저는 하스켈을 예로 사용하고 있습니다. 비슷한 표현형 (풍부한? 강력한) 유형 시스템을 가진 다른 언어가 있지만 확실하지는 않습니다.)


명확하게하기 위해, 난 하지 에 변수 이름을 주석에 대해 얘기 데이터 유형, 오히려에 대한 정보를 의미 프로그램의 맥락에서 변수. 예를 들어, 변수는 정수 또는 float 또는 double 또는 long 또는 기타가 될 수 있지만 변수의 의미 는 인치 단위로 측정 된 상대적인 x 좌표 라는 의미 일 수 있습니다. 이것은 헝가리 표기법 (및 Haskell 유형)을 통한 인코딩에 대해 말하는 일종의 정보입니다.


Pascal-Pascal에서 정의한 XCood 및 YCoord 유형을 추가하려고하면 컴파일러에 경고 IIRC
mcottle

1
blog.moertel.com/articles/2006/10/18/… 은 Haskell의 유형 시스템에서 "헝가리 앱"과 매우 유사한 작업을 수행하는 방법에 대한 기사입니다.
로건 카파도

1
F #에는이 스타일 기능도 있습니다.
Rangoric

정말 좋은 기사 링크 (moertel.com 링크)는 타입 시스템을 사용하여 문자열 보간 보안 취약점을 컴파일 타임 오류로 바꾸는 것을 정확하게 생각하고 있습니다. 링크 주셔서 감사합니다.
Ryan C. Thompson

나는 OO가 의미에 대한 헝가리어 표기법을 따라 잡았다 고 생각합니다. 오늘 아마도 Foo.Position.X + Bar.Position.Y라고 쓸 것입니다.
Pieter B

답변:


27

나는 "예"라고 말할 것입니다.

헝가리 표기법의 목적은 형식으로 인코딩 할 수없는 이름으로 정보를 인코딩하는 것입니다. 그러나 기본적으로 두 가지 경우가 있습니다.

  1. 그 정보는 중요합니다.
  2. 그 정보는 중요하지 않습니다.

사례 2부터 시작하겠습니다. 정보가 중요하지 않은 경우 헝가리 표기법은 단순히 불필요한 노이즈입니다.

더 흥미로운 경우는 1 번이지만 정보가 중요하면 확인해야합니다. 즉 이름이 아닌 유형의 일부 여야합니다 .

그러면 Eric Lippert 견적으로 돌아갑니다.

스토리지 표현 정보 외에 시맨틱 정보를 포괄하도록 "유형"개념을 확장한다.

실제로, 그것은 "유형의 개념을 확장하는" 것이 아니라, 유형의 개념입니다! 유형 의 전체 목적 (디자인 도구로서)은 의미 정보를 인코딩하는 것입니다! 스토리지 표현은 일반적으로 유형 에 전혀 속하지 않는 구현 세부 사항입니다 . (특히 OO 언어 에서는 표현 독립성이 OO의 주요 전제 조건 중 하나이므로 유형에 속할 수 없습니다 .)


헝가리어 표기법이 AFAIK로 가장 많이 사용 된 C는 OO 언어가 아닙니다.
Péter Török

4
@ PéterTörök : OO는 언어의 특징이 아닌 디자인 패턴이지만, 현대 언어는 C가 아닌 쉬운 언어입니다.
Jan Hudec

3
@ PeterTörök : 나는 평범한 C로 객체 지향 코드를 많이 썼습니다. 내가 말하는 것을 알고 있습니다.
Jan Hudec

1
중요한 정보는 이름이 아닌 변수 유형에 포함되어야한다는 것이 사실 일 수도 있지만, 말해야 할 중요한 사항이 많지만 어떤 유형 시스템이 표현할 수없는가는 중요합니다. 예를 들어, 경우는 S1에 우주에서 유일하게 참조 어느 곳입니다 char[]누구의 홀더 원하는 언제 변경됩니다 수는 있지만, 외부 코드에 노출해서는 안하고 S2에 대한 참조입니다 char[]적 변경해야하는 아무도하지만, 이는 공유 할 수 있습니다 변경하지 않겠다고 약속 개체,해야 S1하고 S2"어떤 물건의"동일하게 의미 간주?
supercat

1
@supercat-고유 유형을 설명하고 있습니다.
Jack

9

유형의 전체 목적 (디자인 도구로서)은 의미 정보를 인코딩하는 것입니다!

나는이 답변을 좋아 하고이 답변을 추적하고 싶었습니다 ...

Haskell에 대해서는 아무것도 모르지만 xFoo + yBarC, C ++ 또는 Java와 같은 형식 안전 형식을 지원하는 모든 언어 의 예와 같은 것을 달성 할 수 있습니다 . C ++에서는 자체 유형의 객체 만 가져 오는 오버로드 된 '+'연산자로 XDir 및 YDir 클래스를 정의 할 수 있습니다. C 또는 Java에서는 '+'연산자 대신 add () 함수 / 방법을 사용하여 추가를 수행해야합니다.

나는 항상 의미론이 아닌 유형 정보에 헝가리어 표기법이 사용되는 것을 보았습니다 (시맨틱이 유형으로 표시되는 한 제외). "스마트 한"프로그래밍 편집기 이전에 변수의 형식을 기억하는 편리한 방법으로 편집기에서 사용자에게 형식을 표시합니다.


언어가 xFoo + yBar사용자 정의 유형 을 허용하기 위해 객체 지향적이거나 필요하지는 않으며 , 해당 예제가 작동하는 데 C ++의 OO 측면도 필요하지 않습니다.
Luc Danton

당신은 맞습니다 .OO가 아닙니다. 유형 안전입니다. 내 답변을 편집했습니다.
BHS

흠. xFoo + yBar거의 모든 언어로 컴파일 오류 (또는 적어도 런타임 오류)를 만들 수 있다는 것이 좋습니다 . 그러나 Java 또는 C ++에서 XDir 및 YDir 클래스를 사용하는 수학은 원시 숫자를 사용하는 수학보다 느릴까요? 내 이해는 Haskell에서 컴파일 타임에 유형을 확인한 다음 런타임에 유형을 확인하지 않는 원시 수학 일 뿐이므로 일반 숫자를 추가하는 것보다 느리지 않습니다.
Ryan C. Thompson

C ++에서는 형식 검사도 컴파일 타임에 수행되며 대부분의 경우 변환 및 최적화가 최적화됩니다. Java는 연산자 오버로드 등을 허용하지 않기 때문에 그렇게하지 않습니다. 따라서 XCoordinate예를 들어 일반 정수로 취급 할 수 없습니다 .
cHao

5

나는 "헝가리어 표기법"이라는 문구 가 원문 다른 것을 의미하게되었다는 것을 알고 있지만, 그 질문에 "아니오"라고 대답 할 것입니다. 의미 또는 계산 유형의 변수 이름 지정은 SML 또는 Haskell 스타일 입력과 같은 기능을 수행하지 않습니다. 반창고도 아닙니다. C를 예로 들어 gpszTitle 변수의 이름을 지정할 수 있지만 해당 변수에 전역 범위가 없을 수 있으며 null로 끝나는 문자열을 가리킬 수도 없습니다.

더 현대적인 헝가리어 표기법은 강력한 의미의 추론 시스템에서 더 큰 차이를 보인다고 생각합니다. "의미"정보 (예 : "g"(글로벌) 또는 "f"(플래그))와 계산 유형 ( "p"포인터, " i "정수 등) 변수 이름이 계산 유형과 모호한 유사성 (시간이 지남에 따라 변함) 만 있고"다음 일치 "를 사용할 수 없을 정도로 비슷해 보이는 부정한 혼란으로 끝납니다. 특정 함수에서 변수를 찾으십시오-모두 동일합니다.


4

헝가리 표기법은 유형이 전혀없는 언어 인 BCPL을 위해 발명되었습니다. 또는 오히려 정확히 하나의 데이터 유형 인 단어를 가졌습니다. 단어는 포인터이거나 사용 방법에 따라 문자 또는 부울 또는 일반 정수일 수 있습니다. 분명히 이것은 캐릭터를 역 참조하는 것과 같은 끔찍한 실수를하기가 매우 쉬워졌습니다. 따라서 헝가리어 표기법이 개발되어 프로그래머는 최소한 코드를 보면서 수동 유형 검사를 수행 할 수 있습니다.

BCPL의 자손 인 C는 정수, 포인터, 문자 등의 고유 한 유형을 갖습니다. 따라서 기본 헝가리어 표기법을 어느 정도 불필요하게 만들었습니다 (int 또는 포인터 인 경우 변수 이름으로 인코딩 할 필요가 없음). 그러나이 수준 이상의 의미는 여전히 유형으로 표현할 수 없습니다. 이로 인해 "시스템"과 "앱"헝가리어가 구분됩니다. 변수가 int임을 표현할 필요는 없지만 코드 문자를 사용하여 int가 x 또는 y 좌표인지 인덱스인지 나타낼 수 있습니다.

보다 현대적인 언어는 사용자 정의 유형의 정의를 허용합니다. 즉, 변수 이름이 아닌 유형으로 의미 제한을 인코딩 할 수 있습니다. 예를 들어 일반적인 OO 언어에는 좌표 쌍 및 영역에 대한 특정 유형이 있으므로 x 좌표를 y 좌표에 추가하지 마십시오.

예를 들어, Joels의 유명한 기사 헝가리어 찬양에서, 그는 HTML 주입을 막기 위해 안전 us하지 않은 문자열과 s안전한 (html로 인코딩 된) 문자열 의 접두사 예제를 사용합니다 . 개발자는 코드를주의 깊게 검사하고 변수 접두사가 일치하는지 확인하여 HTML 주입 실수를 방지 할 수 있습니다. 그의 예제는 VBScript에 있으며, 이제는 사용자 정의 클래스를 허용하지 않는 더 이상 사용되지 않는 언어입니다. 현대 언어에서 문제는 사용자 정의 유형으로 해결할 수 있으며 실제로 Asp.net이 HtmlString클래스에서 수행하는 작업입니다. 이런 식으로 컴파일러는 오류를 자동으로 찾아서 사람의 시선에 의존하는 것보다 훨씬 안전합니다. 따라서 사용자 정의 유형의 언어는이 경우 "Apps Hungarian"이 필요하지 않습니다.


2

예, 충분한 유형 시스템을 가진 많은 언어가 여전히 문제가 있습니다. 기존 유형을 기반으로하거나 유사한 새로운 유형의 표현 가능성입니다.

즉, 우리가 타입 시스템을 더 많이 사용할 수있는 많은 언어들에서 우리는 이름과 몇 가지 변환 함수 이외의 기존 타입과 기본적으로 동일한 새로운 타입을 만드는 오버 헤드가 너무 크기 때문에 그렇게하지 않습니다.

본질적으로 우리는 이러한 언어로 헝가리어 표기법을 완전히 없애기 위해 강력한 형식의 typedef가 필요합니다 (F # style UoM도 가능)


2

IDE에 변수의 유형이 무엇인지 알려주는 팝업 힌트가없는 시간이있었습니다. IDE가 편집중인 코드를 이해하지 못하는 경우가 있었으므로 사용법에서 선언으로 쉽게 이동할 수 없었습니다. 또한 코드베이스 전체를 수동으로 거치지 않고 변수 이름을 리팩터링 할 수 없었던 시간도있었습니다. 고객을 검색하면 CustomerName도 얻으므로 검색 및 바꾸기를 사용할 수 없습니다.

그 어두운 시절로 돌아가서 변수가 사용 된 위치의 유형을 아는 것이 도움이되었습니다. 제대로 유지 관리한다면 (리팩토링 도구가 부족하여 큰 경우) 헝가리어 표기법이이를 알려줍니다.

요즘 생산되는 끔찍한 이름의 비용은 너무 높지만 비교적 최근의 일입니다. 내가 설명한 IDE 개발 이전의 많은 코드가 여전히 존재합니다.


1
내가 실수하지 않으면, 이것은 OP가 요구하는 것과 다른 유형의 헝가리 표기법을 다루는 또 다른 대답입니다.
MatrixFrog

2
이 답변은 "Systems Hungarian"이라고하며, 접두어는 언어 수준 "type"을 나타냅니다. 질문은 "Apps Hungarian"에 대해 묻습니다. 여기서 "type"이라는 단어는 오해되지 않았으며 의미 적 유형을 의미 합니다. 시스템 헝가리어는 요즘 거의 보편적으로 비난을 받고있다. 그러나 Apps Hungarian은 좋은 일이 될 수 있습니다.
cHao

sCustomerName을 선택하지 않고 sCustomer를 검색 할 수있는 편집기 (vi 및 emacs는 2 가지 예)는 70 년대부터 존재했습니다.
Larry Coleman

@Larry, 어쩌면
mcottle

@cHAo, 아니요, 그렇지 않습니다. 제 요점은 사람들이 왜 추가 정보를 변수 이름에 넣는 이유를 설명하려고했습니다. 나는 헝가리어 표기법을 언급하지 않았다. "검색 및 바꾸기가 소스 코드에서 작동하지 않는 이유"섹션에서 제공 한 예는 "Systems Hungarian"처럼 보이지만 의도하지 않았습니다. 혼란을 피하기 위해 선행 "s"를 삭제했습니다.
mcottle

0

옳은!

헝가리어 표기법과 같은 완전히 형식화되지 않은 언어 이외에 헝가리어 표기법은 불필요하고 성가시다. 대부분의 IDE가 유형 안전성을 유형 유형으로 확인한다고 생각할 때도 마찬가지입니다.

여분의 "i" "d"와 "?" 접두사는 코드를 읽기 어렵게 만들고, "cow-orker"가 iaSumsItems의 유형을 Integer에서 Long으로 변경하지만 필드 이름을 리팩토링하지 않는 것처럼 오해의 소지가 있습니다.


9
귀하의 답변에 따르면 원래의 똑똑한 "앱"헝가리어와 "시스템"헝가리어라는 멍청한 놈 사이의 차이점을 이해하지 못하고 있습니다. 읽기 joelonsoftware.com/articles/Wrong.html
라이언 컬페퍼
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.