4 ポイント 投稿者 GN⁺ 13 일 전 | 1件のコメント | WhatsAppで共有
  • 1970年代の米国国防総省におけるソフトウェア混乱の中で誕生したAdaは、強い静的型付けと仕様-実装分離を中核とする言語である
  • パッケージ構造と表現隠蔽によって完全なカプセル化を実現し、その後のJava・C#・Goなど現代言語のモジュールシステムに影響を与えた
  • 意味的制約型ジェネリック並行性(task)契約に基づく設計などは、Adaが数十年先んじて提示した概念であり、Haskell・Rust・Swiftなどがそれを受け継いでいる
  • SPARK Adaは形式検証によってデータ競合や論理エラーまで排除し、航空・鉄道・防衛システムなどの高信頼分野で使われている
  • Adaは大衆的な言語ではないが、**「静かに正しく動作する言語」**として、現代のプログラミング言語設計における根本原則を示した基盤である

Adaの誕生背景と設計哲学

  • 1970年代初頭、米国国防総省(DoD) は、兵器・物流・通信システムに450以上の言語と方言が混在している状況を調査した
    • 各システムは相互運用不可、保守不能、原著者不在といった問題を抱えていた
    • これによりソフトウェア調達危機が発生した
  • DoDは既存言語(COBOL, Fortran, PL/1など)を採用せず、5年にわたる要件定義プロセスを経た
    • Strawman → Woodenman → Tinman → Ironman → Steelman 文書へと発展
    • Steelman(1978)は、明示的なインターフェース分離、強い静的型付け、組み込み並行性、一貫した例外処理、機械独立性、可読性、検証可能性を要求した
  • 1979年、4チーム(Green, Red, Blue, Yellow)による競争で、Jean Ichbiahが率いるGreenチームが選定され、Adaと命名された
    • 名称はAda Lovelaceを記念して付けられ、言語の意図を象徴している

パッケージ構造とカプセル化

  • Adaの中心構造は**パッケージ(package)**で、仕様(specification)と本体(body)が物理的に分離される
    • 仕様は外部に公開される契約、本体は実装であり、コンパイラが両者の関係を強制する
    • クライアントコードは、仕様にない要素へアクセスできない
  • この構造はモジュールシステムの原型であり、その後の言語がこれを部分的に模倣した
    • Java, Python, JavaScript, C, Go, Rustはいずれも、Adaの完全な構造的分離を実装していない
  • private型は名前だけが公開され、内部表現は完全に不透明である
    • クライアントは型の内部構造を知ることができず、許可された演算だけを利用できる
    • これはJavaのprivateアクセス制御より強力な**表現隠蔽(representational invisibility)**である
  • JavaとC#は数十年をかけて、段階的にAda水準のカプセル化へと発展してきた

型システムと意味的制約

  • Adaは型とサブタイプの区別を数学的意味で定義している
    • 例: type Age is range 0 .. 150 は範囲制約を持つ別個の型を生成する
    • 不正な型間の受け渡しはコンパイル時エラーとして検出される
  • 1983年当時、Adaの型システムはC, Fortran, Pascalよりはるかに高い表現力を持っていた
    • 意味的制約型によってドメインエラーを防止する
  • **判別レコード(discriminated record)**は、値によって異なるフィールドを持つ構造である
    • これは現代言語の**直和型(sum type)または代数的データ型(ADT)**と同じである
    • Haskell, Rust, Swift, Kotlin, TypeScriptなどが数十年後に同じ概念を導入した

ジェネリックと多相性

  • Adaの**ジェネリック(generic)**は、型・値・サブプログラム・パッケージを引数に取る単位である
    • コンパイル時に型検証を行う**静的多相(parametric polymorphism)**を実装する
  • C++(1990), Java(2004), C#(2005), Go(2022)などは、Adaの後に数十年かけて類似機能を導入した
    • Javaは**型消去(type erasure)**により、実行時の型情報が失われる
    • Adaは実行時型の保持とパッケージのパラメータ化までサポートする
  • Adaのジェネリックは**高階多相(higher-kinded polymorphism)**水準の表現力を提供する
    • Haskellの型クラス、Rustのトレイト、C++20のconceptsに近い概念である

並行性モデルと安全性

  • Adaは1983年から**言語レベルの並行性(task)**を組み込んでいた
    • task宣言とrendezvous通信モデルにより、共有状態のないメッセージ受け渡しを実現する
    • Goのchannelは同じCSP(Communicating Sequential Processes)系統の概念である
  • Ada 95はprotected objectを導入した
    • データアクセスを保護し、procedure, function, entryに区分される
    • 自動バリア条件ロック不要の同期を提供する
  • SPARK Adaは形式検証によって、データ競合、例外、範囲エラー、事前・事後条件違反が存在しないことを数学的に証明する
    • Rustのborrow checkerはメモリ安全性のみを保証する一方、SPARKは論理的一貫性まで証明する

契約に基づく設計とnull安全性

  • Ada 2012は**契約(contracts)**を言語に統合した
    • 事前条件(precondition)事後条件(postcondition)、**型不変条件(invariant)**を明示できる
    • SPARKツールチェーンはこれを静的証明に活用する
  • Eiffel(1986)のDesign by Contract概念を言語レベルで正式化した
    • C++, Java, Python, Rustなどは部分的実装またはライブラリレベルの実装にとどまる
  • Ada 2005はnot null型を導入し、コンパイル時のnull排除をサポートした
    • 既定では実行時例外(Constraint_Error)が発生し、安全な失敗を保証する
    • C# 8.0のnullable referenceに近いアプローチである

例外処理構造

  • Ada 83は最初期に**構造化例外処理(structured exception handling)**を導入した
    • 例外は宣言してから使用し、スコープ単位で処理され、伝播規則も明確である
  • Javaのchecked exceptionはAdaより発展した形で、呼び出し側が例外を明示しなければならない
    • Adaは例外伝播を自由に許可する
  • Rustは例外を廃し、Result型ベースのエラー処理を採用した
    • Adaの貢献は、例外伝播を構造化し予測可能にした点にある

Annexと標準化構造

  • Ada標準はAnnexという選択的拡張構造を持つ
    • Annex C〜Hは、システム、リアルタイム、分散、数値、高信頼分野ごとの機能を定義する
    • コンパイラはAnnexごとに独立認証を受けなければならない
  • ACAAACATSテストによって標準適合性を検証する
    • DO-178C航空ソフトウェア認証にAdaの標準構造を直接活用できる
    • C/C++でも同じ認証は可能だが、Adaのほうが構造的に適している

Adaの影響と認識の不均衡

  • Adaは政府主導の言語であるため、シリコンバレー文化圏では注目されにくかった
    • Cベースの簡潔な文法を好む文化との対比がある
  • Adaの成功事例(航空、鉄道、防衛システム)は、失敗がないため可視性が低い
    • 信頼性の高いシステムは議論や事件を生まない
  • 現代言語の発展方向は、Adaがすでに示していた原則へと収束している
    • 仕様-実装分離静的型検証言語レベル並行性契約ベースの安全性など
  • Adaは今なお航空機、鉄道、宇宙船などの高信頼システムで運用中であり、 **「静かに正しく動作する言語」**として残っている

1件のコメント

 
GN⁺ 13 일 전
Hacker Newsのコメント
  • 私はAdaが好きだ。だが型の話をしながら、ML系言語(ML、SML、CML、Caml、OCaml など)を完全に外しているのは驚きだった
    これらの言語は構造的型付けをコンパイラレベルでサポートしている。Ada は PL/I、PHP、Perl のように言語自体が大きすぎて文法が複雑だったのが問題だった。記事ではそれを長所としているが、個人的には Annex に分離された標準拡張のほうが優れていたと思う。もしコア言語を小さくし、Annex 中心で進めていたなら、もっと広く使われていた気がする

    • ML 言語では、ユーザーがbounded Integer/Floating point 型を自分で定義することはできない。Ada の中核機能の一つがまさにこうした型システムだ。Ada の型システムを体験すると、コード品質と信頼性がどれほど高まるかに驚かされる
  • Ada が敬遠された理由の一つは、コンパイラの価格が数万ドルだったことだ。無料やオープンソースのコンパイラがなかった時代、他の言語はただで使えた。それが決定的な要因だった

    • Ada がニッチを抜け出せなかったのは、いくつもの要因が重なっていた。言語の複雑さと当時のコンパイラ技術では、1980年代のマイクロコンピュータでまともに動かせなかった。Intel は Ada の概念をハードウェアに落とし込んだ i432 を作ったが、性能はひどかった。その後マイクロコンピュータが世界を席巻し、C とアセンブリの遺産が20年以上続いた
    • 私は Ada を数年使っていたが、同僚たちが趣味では別の言語を使っていたことも Ada の普及にはプラスにならなかった。文字列処理も弱く、速度も遅かった。特に並行処理が OS スレッドを使わないので不便だった。結局、HPUX のリアルタイム拡張を使って複数プロセスで動かしていた
    • 90年代半ばからGNATは存在しており、その頃には商用コンパイラも珍しくなかった。Ada が伸び悩んだ理由は、「不要なオーバーヘッド」という認識のせいだった。つまり、軍用や安全システム以外では使う理由がないという評判があった
    • GNU Ada Compiler(GNAT) は 1995 年に初めて公開された
    • 実際、80年代はどの言語でもコンパイラ品質は今ひとつだった。GCC も後半になってようやく実用的になった。新しい言語を使えばコンパイラが未熟なのは当然だった。C++ も当時は Ada よりずっと遅れていて、「C++ のキラー機能」は実質的にC のように使えたことだった。Ada が Pascal 互換モードを提供していたら、歴史は違っていたかもしれない
  • 記事を読みながら Ada も記事自体も興味深かったが、いくつか事実誤認が目についた。たとえば Ada だけが実装と仕様を完全に分離すると書いていたが、JavaScript でも ES6 モジュールで private 要素を定義できる。Java の private 可視性の説明も間違っていた。こうした誤りのせいで記事の信頼性が下がってしまう

    • Ada では private 型を定義すると、外部から内部フィールドにアクセスできない。一方 JavaScript では、どんなオブジェクトにも自由にプロパティを追加・削除できる。つまり、Ada のコンパイル時保護の水準は JS とは比較にならない
    • Java ではreflectionで private メンバーにアクセスできる。setAccessible(true) によって String の内部を変更することさえできる
    • LLM が人間の読者向けに文章を書くとき、Gell-Mann amnesia のように作用するという指摘が印象的だった
  • 記事全体は良かったが、繰り返し出てくる「言語 X ではこの機能が Ada より後になって導入された」という文が退屈だった。コード例があれば、はるかに説得力があったと思う

    • 実際、Ada の多くの機能は既存言語(PASCAL、CLU、MODULA、CSP など)から借用されたものだった。完全に新しい概念というより、実証済みのアイデアを統合した結果だった
    • Ada が先に導入したと主張される概念の一部は、実際には実装がかなり異なる場合が多い。だから比較例が必要だった
    • この記事は「Ada が最高だ」と主張するものではなく、Ada が安全性と信頼性のためにどのような設計をしたかを示すものだ。年代比較にはその文脈で意味がある
    • 私は Claude に Ada のデモコードを頼んでみたが、かなり良かった。Ada は昔から知っていたが、実際に触ってみるとFOMOを感じた
    • Ada 開発者の立場からすると、こうした比較パターンは長年繰り返されてきたので、うんざりするものに感じられるかもしれない
  • この Twitter アカウント は 2026 年 4 月に作られ、著者が明記されていない。短期間で驚異的な生産性を見せているが、名前を出していない点が興味深い

    • 著者がいないのはボットだからだという意見もある
  • 「すべての言語がこの20年で sum type を追加したが、Ada には最初からあった」という主張は事実だが、その起源が Ada というわけではない。Hope 言語 や NPL のほうが先だった

    • 実際、sum type の起源は 1964 年の John McCarthy による “Definition of new data types in ALGOL X” という論文にある。彼は UNION キーワードを提案し、その後 ALGOL 68、Hope、Miranda などで発展した。C の union はこの概念とは異なる
  • 記事があまりにも気に入ったので AI が書いたものでなければいいと思ったが、Twitter への投稿速度が速すぎて疑わしく感じた

    • 文章が少し冗長で反復的だったので、AI っぽく感じられた
    • 最近はブログ記事を自動でリライトする AI ツールが多いので、疑いが生じる
    • 私も楽しく読んだが、110 個の em dash を見て初めて「もしかして AI?」と思った。今ではブログ記事ですらメディアリテラシーを働かせて読むようになったのが悲しい
    • 私も3年間で50本の記事を書いたが、大半は未公開のままだ。もしかするとこの著者も似たような状況で、最近になって勇気を出しただけかもしれない。AI と誤解されることがどれほど挫折感のあることかは理解できる
    • もし AI がこのレベルの文章を書けるなら、時間を奪われてもいいと思えるほど価値がある
  • 米空軍は当初 Ada を使う予定だったが、開発が遅れたためJOVIALを使った。私は 1981 年に JOVIAL で最初のプロジェクトを行ったが、そのとき Ada はまだ仕様策定段階だった

    • JOVIAL は ALGOL 60 の前身である IAL から派生した言語で、Ada 開発初期の要求仕様(STRAWMAN~STEELMAN)に影響を与えた。その後 Ada は JOVIAL の機能を改良し、in/out パラメータの明示のような革新を導入した。これにより、C++ のような複雑なコピーコンストラクタや move semanticsを必要としなかった
  • サイトのトップに「これは立場表明ではなく提案だ」という文句があり、それを根拠にAI が書いたサイトだと主張している

    • しかし、その文自体は AI 執筆の証拠にはならない
  • 記事では「JavaScript のモジュールシステムは Ada のように型の内部表現を隠せない」と述べていたが、実際には JS モジュールでも export しなければ十分に隠せる。Ada が特別に優れている点があるのか疑問だった

    • TypeScript を基準に見れば、JS オブジェクトには依然として外部からプロパティを追加したり変更したりできる。Ada ではprivate 型インスタンスに対して、定義された API 以外の操作は不可能だ
    • 具体例は このコメント を参照できる