ラルフウィリアムゴスパーJrによる次のような引用があります。
データ構造は単なる愚かなプログラミング言語です。
これはどういう意味ですか?残念ながら、Googleで見つけることができるのは、文脈のない引用自体の容赦ないコピー/貼り付けだけです。
ラルフウィリアムゴスパーJrによる次のような引用があります。
データ構造は単なる愚かなプログラミング言語です。
これはどういう意味ですか?残念ながら、Googleで見つけることができるのは、文脈のない引用自体の容赦ないコピー/貼り付けだけです。
回答:
さて、声明の核心は次のように思われます。
データ構造はただの...プログラミング言語
あなたがそれについて考えるならば、それは全く本当です。結局のところ、コンパイラは常にこの推移性に依存しています。プログラミング言語を取得し、それをデータ構造に変換し、そのデータにいくつかの変換を行った後、結果を別のプログラミング言語に変換します。
実際、Cデータ構造のようなクレイジーなものを作成したい場合は、さまざまなメソッドを呼び出すことでCコードを記述できます(たとえば、C#で使用しています)。
var C = new HorribleCObject(); C.Function <int>( "main"、typeof(char [] [])、typeof(int)) .Variable( "i"、typeof(int)、0) .While( "i"、Func(i)=> i <10)) .Call( "printf"、 "%d"、 "i") .PostIncrement( "i") .EndWhile(); .Return(0) .EndFunction();
さて、完全な引用については、なぜそのようなものは、(C)自身で書くことに比べてバカなのでしょうか?これは冗長であり、Cの同等のものほど読みにくいことは明らかです(実際には、Cでできることのすべての範囲をサポートしていない可能性があります-typedefには注意が必要です)。したがって、このデータ構造は単なる「愚かな」プログラミング言語であり、「実際の」プログラミング言語に組み込まれています。同じロジックを、考えられるあらゆるデータ構造に一般化できます。リンクリストはLispの「愚かな」バージョンであり、ハッシュマップは理論的なハッシュプログラミング言語(Hasp?)の「愚かな」バージョンです。
ただし、ハッシュマップとやり取りするためにHaspを常に作成する必要はありません。これは、すべてのドメイン固有言語が抱える問題です。一方で、十分に実装されたDSLは、基礎となるモデルが実行できるすべてを表現するのに十分強力です。一方、最初にDSLを実装する必要があり、次に他の人がそれを学習する必要があります。それにはおそらく彼らが費やしたくない時間と労力がかかります。結局、私は自分のハッシュマップに物事を入れて、そこに他のものが入っていることを確認したいだけです。ハッシュ指向プログラミングの複雑さをすべて学びたくありません。
そのため、ほとんど考えずに、これらの理論的に非常に具体的で非常にスマートなプログラミング言語を採用し、それらをデータ構造に組み込まれた少数の愚かな操作に分解します。リンクリストには、単純なメソッドの小さなコレクションが1つあります。ハッシュマップには他にもいくつかあります。データ構造に対して潜在的に実行できる他のより強力な操作は無視します(たとえば、ほとんどのLinkedList実装には.Mapや.ForEach関数がありません。Haspで何をするか想像もできません)。親プログラミング言語でそれらを明示的に実装することに賛成-これはほとんどのプログラマーが精通しているものです。
データ構造は、本質的に、概念的に表現する問題空間への親言語の愚かな拡張です。十分にスマートな拡張には、新しい特定のプログラミング言語が必要であり、ほとんどの人はそれを学びたくないでしょう。
データ構造は、プログラミング言語の表現です。しかし、特に「鋭い」ものではありません。
これは、以下のwiki記事にあるような「ノード図」から見ることができます。
http://en.wikipedia.org/wiki/Root_node#Terminology
それにも関わらず、データ構造はプログラミング言語としては不完全です。なぜなら、それはプログラマーにとってわかりやすい構文と完全な思考を欠いているからです。データ構造の「言語」は、「私、寒い。コートをゲット」などと言った子供に例えることができます。
「言語」は壊れていますが、理解できます。子供は「寒いので、もっとたくさんの服を被ってほしい」と言っています。子供の発話は英語の「愚かな」バージョンであり、同様にプログラミング言語に関連したデータ構造です。
ビルゴスパーが意図していたのは、すべてのデータ構造が適用可能性が制限された単なるプログラミング構造であると信じている。これは、「言語設計はライブラリ設計であり、ライブラリ設計は言語設計である」という考えにも関連しています[1]。
この問題について考える1つの方法は、データ構造を単にアルゴリズムに基づいて考慮することです。これらは単に補助的なものであるため、現時点ではストレージ要件や注釈を入力しないでください。
たとえばmap
、2つの方法で連想配列(一部の言語ではaと呼ばれます)をコード化できます。メモリに格納されたある種のインデックスを使用するか、単純なcase式を使用します。
Haskellでは、連想配列をデータ構造として体系化できます...
let assocArray = [("a", 1),("b", 2),("c", 3)]
let key = "b"
lookup key assocArray
...またはケース式を使用して...
let key = "b"
case key of
"a" -> 1
"b" -> 2
"c" -> 3
...またはさらに直接...
let key = "b"
if key == "a"
then 1
else if key == "b"
then 2
else if key == "c"
then 3
else undefined
ラムダ計算を見ると、データ構造とコード間のこの種のミラーリングが可能であることがわかります。任意の値はラムダ計算の関数で表すことができ、計算自体は普遍的です(チューリング完了)。
[1]引用はBjarne Stroustrupのおかげです。
すべてのデータがコードであるJavascriptを検討してください。すべてのデータがコードであり、すべてのコードがデータであるLISPを考えます。
始まり、終わり、そしてその間のあらゆる場所で、データは単なるビットです。私たちがビットをテキストと記号でオンログ化して人間が読みやすく、人間が変換できるようにすることは、a)定義言語を学び、b)抽象化の漏れを学ぶことを必要とする抽象化の層です。
たとえば、C#では、構造体とクラスの違いを学習するには、値型と参照型の等価比較の違いを学習する必要があります。すべてのデータオントロジーには、学習して順守する必要がある独自のルールセットが必要です。また、他の言語と同様に、一般的な考え方にすばやく到達できますが、問題の実際の真実に近づきたいほど、自分でバイナリを見る必要があります。
最後に、Bツリーまたは類似のデータ構造を検討する場合、ツリーの構造をナビゲートして他の種類の操作を実行するには、ツリー、構造、または言語間で必ずしも転送できない特殊な種類の構文が必要です。