ハンガリーの表記法は、表現が不十分な静的型付けの言語の回避策ですか?[閉まっている]


28

Eric Lippertの記事「What's Up With Hungarian Notation?」、彼はハンガリー記法(良い種類)の目的は

ストレージ表現情報に加えてセマンティック情報を含むように「タイプ」の概念を拡張します。

簡単な例は、X座標を表す変数の前に「x」を、Y座標を表す変数の前に「y」を付けることです。これらの変数は整数か浮動小数点かどうかに関係なく、xFoo + yBar、コードは明らかに間違っています。

しかし、私はHaskellの型システムについても読んでおり、Haskellでは、コンパイラがチェックする実際の型を使用して同じことを達成できるようです(つまり、「型の概念を拡張して意味情報を含む」)。したがって、上記の例ではxFoo + yBar、プログラムを正しく設計すると、Haskellで互換性のない型として宣言されるため、実際にコンパイルに失敗します。つまり、Haskellの型システムは、ハンガリー語表記と同等のコンパイル時チェックを効果的にサポートしているようです。

それでは、ハンガリー記法は、型システムが意味情報をエンコードできないプログラミング言語の単なるバンドエイドなのでしょうか?または、ハンガリー記法は、Haskellのような静的型システムが提供できる以上のものを提供しますか?

(もちろん、私はHaskellを例として使用しています。他の言語も同様に表現力豊かな(リッチ?ストロング?)型システムを備えていると確信していますが、私はまったく遭遇していません。


明確にするために、私はしていないと、変数名に注釈を付けるの話データタイプではなく、に関する情報を意味プログラムのコンテキスト内の変数の。たとえば、変数は整数、浮動小数点、倍精度、長整数などの場合がありますが、変数の意味は、インチ単位で測定される相対x座標であることです。これは、ハンガリー記法(およびHaskell型)を介したエンコードについて話している種類の情報です。


Pascal-Pascalで定義したXCoodおよびYCoord型を追加しようとすると、コンパイラー警告IIRC
mcottle

1
blog.moertel.com/articles/2006/10/18/…は、Haskellの型システムで「ハンガリーのアプリ」に非常によく似た何かをすることに関する記事です。
ローガンカパルド

1
F#にもこのスタイル機能があります。
ランゴリック

これは、私が考えていた種類を正確に示す、本当に素晴らしい記事リンク(moertel.comのもの)です。型システムを使用して、文字列補間のセキュリティ脆弱性などをコンパイル時エラーに変換します。リンクをありがとう。
ライアンC.トンプソン

今日はおそらくFoo.Position.X + Bar.Position.Yと書くだろうから、OOはセマンティクスのハンガリー記法に追いついたと思う。
ピーターB

回答:


27

私は「はい」と言います。

あなたが言うように、ハンガリー記法の目的は、タイプでエンコードできない情報を名前でエンコードすることです。ただし、基本的に2つのケースがあります。

  1. その情報は重要です。
  2. その情報は重要ではありません。

最初にケース2から始めましょう。その情報が重要でない場合、ハンガリー語表記は単に不要なノイズです。

より興味深いケースは番号1ですが、情報が重要な場合はチェックする必要があります。つまり、nameではなくtypeの一部である必要があります。

Eric Lippertの引用に戻ります。

ストレージ表現情報に加えてセマンティック情報を含むように「タイプ」の概念を拡張します。

実際、それは「型の概念を拡張する」のではなく、それ型の概念です!(設計ツールとしての)型の全体的な目的は、セマンティック情報をエンコードすることです!ストレージ表現は実装の詳細で、通常はタイプにまったく属しません。(具体的にはオブジェクト指向言語で、表現の独立性がオブジェクト指向の主要な前提条件の1つであるため、この型に属することはできません。)


Cはハンガリー語表記が最もよく使用されていた場所ですが、OO言語ではありません。
ペテルトレック

4
@PéterTörök:OOはデザインパターンであり、言語の機能ではありませんが、Cはそうではないが、現代の言語は簡単にするように設計されています。
ジャン・ヒューデック

3
@PéterTörök:プレーンCで非常に多くのオブジェクト指向コードを作成しました。私が話していることは知っています。
Jan Hudec

1
重要な情報は名前ではなく変数の型に埋め込む必要があるのは事実かもしれませんが、言わなければならないが、どの型システムが表現できないかという多くの重要なことがあります。たとえば、if S1は、ユニバース内の任意の場所への唯一の参照でありchar[]、その所有者は必要に応じて変更できますが、外部コードに決して公開してはならずS2char[]誰も変更してはならないが共有できる参照それを変更しないことを約束したオブジェクトで、必要があるS1S2同じ「もののようなもの」と意味的にみなされますか?
supercat

1
@supercat-一意性タイプを説明しています。
ジャック

9

(設計ツールとしての)型の全体的な目的は、意味情報をエンコードすることです!

私はこの答えが好きで、この答えをフォローアップしたかった...

Haskellについては何も知りませんがxFoo + yBar、C、C ++、Javaなどの何らかのタイプセーフティをサポートする任意の言語の例のようなものを達成できます。C ++では、独自の型のオブジェクトのみを取得するオーバーロードされた「+」演算子を使用して、XDirクラスとYDirクラスを定義できます。CまたはJavaでは、「+」演算子の代わりにadd()関数/メソッドを使用して追加する必要があります。

私は常に、セマンティクスではなくタイプ情報にハンガリー語表記が使用されるのを見てきました(ただし、セマンティクスがタイプによって表される場合を除きます)。変数の型を覚えておくのに便利な方法。「スマート」プログラミングエディターの前の時代にさかのぼって、何らかの方法で型をエディターで表示します。


オブジェクト指向であることは、言語がxFoo + yBarユーザー定義型を許可するために必要でも十分でもありませんし、その例が機能するためにC ++のオブジェクト指向の側面も必要ではありません。
リュックダントン

OOではなく、タイプセーフです。回答を編集しました。
BHS

うーん xFoo + yBarほとんどすべての言語でコンパイルエラー(または少なくとも実行時エラー)が発生する可能性があるのは良い点です。しかし、たとえばJavaやC ++のXDirクラスとYDirクラスを使用した数学は、生の数値を使用した数学よりも遅いでしょうか?私の理解では、Haskellでは、コンパイル時に型がチェックされ、実行時に型チェックを行わない生の数学であり、したがって通常の数値を追加するより遅くはないということです。
ライアンC.トンプソン

C ++では、型チェックもコンパイル時に行われ、変換などはほとんどの場合最適化されます。Javaは演算子のオーバーロードなどを許可しないため、同様にそれを行いませんXCoordinate。たとえば、通常のintとして扱うことはできません。
cHao

5

「ハンガリー記法」というフレーズは元のものとは異なる何かを意味するようになったことに気づきましたが、質問には「いいえ」と答えます。セマンティックまたは計算タイプのいずれかを使用した変数の命名は、SMLまたはHaskellスタイルのタイピングと同じことを行いません。絆創膏でもありません。Cを例にとると、変数にgpszTitleという名前を付けることができますが、その変数はグローバルスコープを持たない可能性があり、ヌル終了文字列へのポイントを構成することさえできません。

より現代的なハンガリーの表記法は、強力な型推論システムからさらに大きな相違を持っていると思います。なぜなら、「セマンティック」情報(グローバルの「g」やフラグの「f」など)と計算型(「p」ポインター、 i "整数など)変数名がその計算タイプ(時間の経過とともに変化する)にあいまいな類似性のみを持ち、「次の一致」を使用できないほど似ているように見える不気味な混乱に終わります特定の関数で変数を見つける-それらはすべて同じです。


4

ハンガリー語の表記法はBCPLのために考案されました。BCPLはまったく型を持たない言語です。むしろ、データ型はワードという1つだけでした。単語は、使用方法に応じて、ポインタでも、文字、ブール値、または整数でもかまいません。これにより明らかに、キャラクターの参照解除のような恐ろしい間違いを犯しやすくなりました。そのため、プログラマが少なくともコードを見て手動で型チェックを実行できるように、ハンガリー語の表記法が考案されました。

BCPLの子孫であるCには、整数、ポインター、文字などの明確な型があります。これにより、基本的なハンガリー語表記がある程度不要になりました(intまたはポインターの場合、変数名にエンコードする必要はありませんでした)。しかし、このレベルを超えるセマンティクスはまだ型として表現できませんでした。これにより、ハンガリー語で「システム」と「アプリ」と呼ばれるものが区別されました。変数がintであると表現する必要はありませんでしたが、intがxまたはy座標またはインデックスであるかどうかを示すコード文字を使用できます。

最新の言語では、カスタム型の定義が可能です。つまり、変数名ではなく、型のセマンティック制約をエンコードできます。たとえば、典型的なオブジェクト指向言語には座標ペアと領域に特定のタイプがあるため、x座標をy座標に追加することは避けてください。

たとえば、Apps Hungarianを称賛するJoelsの有名な記事では、HTMLインジェクションを防ぐためにus、安全でない文字列とs安全な(htmlエンコードされた)文字列のプレフィックスの例を使用しています。開発者は、コードを慎重に検査し、変数プレフィックスが一致することを確認するだけで、HTMLインジェクションの間違いを防ぐことができます。彼の例は、VBScriptにあります。VBScriptは、カスタムクラスを最初は許可していなかった、現在は廃止された言語です。現代の言語では、問題はカスタムタイプで修正できます。実際、これはAsp.netがHtmlStringクラスで行うことです。このようにして、コンパイラは自動的にエラーを検出します。これは、人間の目で確認するよりもはるかに安全です。したがって、この場合、カスタムタイプの言語を使用すると、「Apps Hungarian」の必要がなくなります。


2

はい、そうでなければ十分に強力な型システムを持つ多くの言語にはまだ問題があります-既存の型に基づいた/類似した新しい型の表現可能性。

すなわち、型システムをさらに使用できる多くの言語では、名前といくつかの変換関数以外の既存の型と基本的に同じ新しい型を作成するオーバーヘッドが大きすぎるため、使用しません。

基本的に、これらの言語でハンガリー表記を徹底的に殺すためには、強く型付けされたtypedefのようなものが必要です(F#スタイルのUoMでもできます)


2

IDEには、変数のタイプを示すポップアップヒントがなかった時代があったことを思い出してください。IDEが編集しているコードを理解できなかったため、使用法から宣言に簡単にジャンプすることができませんでした。また、コードベース全体を手動で調べ、手作業で変更を加え、1つを見逃さないことを期待せずに、変数名をリファクタリングできなかった時代もありました。Customerを検索するとCustomerNameも取得されるため、検索と置換を使用できませんでした...

当時の暗い時代には、変数がどのタイプで使用されているかを知ることが役に立ちました。適切に保守されていれば(リファクタリングツールがないために大きい場合)、ハンガリー語の表記法でそれがわかりました。

最近作成された恐ろしい名前のコストは高すぎますが、それは比較的最近のものです。私が説明したIDE開発より前のコードがまだたくさんあります。


1
誤解していない場合、これはOPが求めているものとは異なるタイプのハンガリー表記に対処する別の答えです。
MatrixFrog

2
この回答では、「Systems Hungarian」と呼ばれるものについて説明しています。プレフィックスは言語レベルの「タイプ」を示します。質問では「Apps Hungarian」について尋ねられますが、「type」という言葉は誤解されておらず、意味タイプを意味します。システムハンガリー語は、最近ほとんど例外なく非難されています(そして当然のことながら、それはハンガリー語表記の本当の目的のろくでなしです)。ただし、Apps Hungarianは良いことです。
cHao

sCustomerName(viおよびemacsは2つの例です)を選択せず​​にsCustomerを検索できるエディターは、70年代から存在していました。
ラリーコールマン

@Larryかもしれませんが、80年代にプログラミングしていたシステムで実行することはできませんでした
mcottle

@cHAo、いいえ、そうではありません-私のポイントは、人々が一般に変数名に余分な情報を入れる理由を説明しようとしたことです。私は、ハンガリー語表記のどのバージョンにも言及することを熱心に避けました。「なぜソースコードで検索と置換が機能しないのか」セクションで説明した例は、「Systems Hungarian」のように見えますが、意図したものではありません。混乱を避けるために、先頭の「s」を削除しました。
mcottle

0

正しい!

アセンブラーなどのまったく型付けされていない言語以外では、ハンガリー語の表記法は不要で迷惑です。二重に、ほとんどのIDEがタイプセーフをチェックすることを考えると、あなたがタイプするときに、タイプセーフティをチェックします。

余分な「i」「d」および「?」接頭辞はコードを読みにくくするだけで、本当に誤解を招く可能性があります-「cow-orker」がiaSumsItemsのタイプをIntegerからLongに変更するが、フィールド名のリファクタリングを行わない場合。


9
あなたの応答は、元のスマートな「Apps」ハンガリー語と「Systems」ハンガリー語と呼ばれる馬鹿げた野郎との違いを理解していないことを示唆しています。joelonsoftware.com/articles/Wrong.html
ライアンカルペッパー
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.