EDIT 1ソースへのリンクをいくつか追加しました。Lisp の歴史的なストーリーを改善しました。Javaにプリミティブがある理由に答えました。
EDIT 2効率がもはやそれほど問題ではないことを説明する最新のスクリプト言語に関するコメント
昔は、メモリは高価でした。単純なコンピュータでさえ数キロバイトしかありませんでした。同意しなければならない一般的なサービス条件は、システム全体の RAM を超えます。つまり、データ構造は、現在設計できるものよりもはるかに小さくする必要がありました。
コンピュータは 1940 年代に英国と米国で始まりました。これらのエンジニアに必要な最小限の文字セットは、刺激的なアクセントのない西ヨーロッパのアルファベットでした。0 ~ 9、A ~ Z、および a ~ z は 62 文字です。31 個の制御文字、スペース、句読点を追加すると、すべてを 7 ビットに収めることができます。テレタイプに最適です。
現在、これらの 7 ビットは、異なるアーキテクチャで異なる方法で配置できます。IBM を使用していた場合、 ASCIIとはまったく異なるEBCDICを知っている必要がありました。
60 年代と 70 年代の言語はこれらの問題を反映しており、文字列を可能な限り小さなスペースに詰め込みました。
これらの言語のプログラマーとして、これはひどいものだと言えます。特に、ほとんどのビジネス プログラムでは多くのテキスト入力と操作が必要でした。メモリが安価になるにつれて、プログラマーは生産的なことを行うために何よりも先に文字列ユーティリティを作成する傾向がありました。
固定長の文字列 (Pascal など) は効率的でしたが、1 文字でも拡張または縮小する必要がある場合は厄介でした。
C の null で終了するアプローチには、長さが文字列と共に格納されないという欠点があるため、バッファを上書きしてアプリケーションをクラッシュさせるのは簡単です。このようなバグは、依然としてコンピューターのセキュリティを損なう主な原因となっています。これを解決するには、次の 2 つの方法があります。
- 書き込みごとに文字列の長さを確認します。これは、ヌル文字が見つかるまでメモリをスキャンすることを意味します。醜い
malloc
新しいメモリにコピーし、文字列を新しいメモリにコピーしてから、free
80 年代には、文字列を処理するために標準ライブラリがますます導入されました。これらは、ツール ベンダーと OS プロバイダーによって提供されました。標準化への大きな動きがありましたが、当事者は標準を管理するために歯と爪で戦い、醜いものでした。
国際化の進行は、国際文字セットという別の問題ももたらしました。最初に、ASCII はさまざまなヨーロッパ言語 (アクセント、ギリシャ語、キリル文字) のISO 8859-1として 8 ビットに拡張され、次にUnicodeによってコンピューターが世界の隅々まで完全に普及しました。そして、それはUTF-8やUTF-16などの文字エンコーディングの問題と、これらの異なるアプローチの間でどのように変換するかという問題をもたらしました。
また、 Lispがガベージ コレクションを導入したことにも注意してください。malloc
これにより、C の/の複雑さが解決されfree
ます。Lisp の信じられないほど強力な配列およびシーケンス ライブラリは、文字列に対して自然に機能します。
これらの傾向をまとめた最初の主要な人気のある言語は Java でした。言語の3 つの改善点を組み合わせました。
- 国際化と Unicode: 固有のデータ型
Character
とプリミティブchar
- カプセル化: 固定長とヌル終端の問題は、次の方法で回避されました。
- 不変であること
- VM と GC での巧妙な最適化
- ライブラリ: すべての基本的な文字列操作機能は言語で標準化されました。
現在、すべての値がオブジェクトである言語があります。しかし、Java が 90 年代後半に考案されたとき、GC および JIT/Hotspot テクノロジは現在ほど高速ではありませんでした (少なくとも部分的には RAM の制限が原因でしたが、アルゴリズムも改善されました)。Gosling はパフォーマンスに気を配り、プリミティブなデータ型を維持しました。
もう 1 つのポイント: Java では Character クラスが存在するのは当然です。これは、 や などの多くの操作とユーティリティ メソッドの自然なホームですisWhiteSpace()
。isLetter()
後者は、日本語、韓国語、およびインドの言語によって多少複雑になります。
Python は、文字を 8 ビット ASCII として定義するという不適切な初期の決定を下しました。微妙に異なり、互換性のない別のデータ型 (unicode) を最初に導入することで、結果として生じる問題を確認できます。これは、Python 3.x への複雑な移行によってのみ解決されます。
現代の言語 (スクリプト言語を含む) は、Java や Python に例示されるように、文字列ライブラリがどのように見えるべきかについて幅広いコンセンサスに従っています。
各言語は特定の目的のために設計されているため、さまざまな方法で競合する設計上の問題のバランスを取ります。現代の言語は、過去 60 年間にパフォーマンスとメモリが大幅に改善されたという利点があるため、CPU と RAM の効率よりも一般化、純粋性、および有用性を優先することができます。これは、スクリプトの性質上、既にその決定を行っているスクリプト言語に明確に当てはまります。したがって、現代の言語は、高レベルの文字列型のみを持つ傾向があります。
TL/DR初期のコンピューターはメモリが驚くほど限られていたため、最も単純な実装が必要でした。現代の言語は、GC が国際化 (8 ビットから 16 ビット) 文字を認識し、文字列データ型をカプセル化して、文字列操作を安全かつ簡単にすることの恩恵を受けています。