A comparison of Ada and Rust, using solutions to the Advent of Code

Ada ecosystem, tooling, and third‑party libraries

  • Several commenters are pleasantly surprised Ada has a mature open‑source compiler (GNAT) and tooling (Alire), but see lack of libraries as the main barrier to broader use.
  • Desired ecosystem items include networking (e.g., NATS), GUIs, document formats, crypto, etc.; some exist via Alire or C bindings, but the “Lego‑brick” style of development is harder than in Rust or mainstream languages.
  • Binding directly to C libraries is common; “thick” wrappers are seen as sometimes counterproductive.

Range types, subranges, and safety

  • Ada’s (and Pascal’s) bounded integer types are widely praised for catching logic errors (bounds, positivity, nonzero, etc.), with examples drawn from safety‑critical control systems.
  • Others argue subranges cause brittle crashes when assumptions change (e.g., age limits), preferring manual validation and more flexible types.
  • Related techniques appear in Nim, F#, C#, and can be emulated in C++ and Java via refinement/“parse, don’t validate” patterns.
  • Debate centers on compile‑time vs runtime enforcement, performance costs of checks, and how well constraints age as requirements evolve.

Formal verification and safety models (Ada/SPARK vs Rust)

  • Ada/SPARK is highlighted as offering integrated, industrial‑grade formal verification (absence of runtime errors, contracts, ownership‑style alias analysis), with use in avionics, rail, automotive, etc.
  • Rust’s ownership model is seen as excellent for memory and data‑race safety, but higher‑level correctness requires external tools (e.g., Kani, Prusti, Verus, Creusot) and is less integrated and less mature.
  • There’s an extended back‑and‑forth on whether Rust can ever match SPARK’s whole‑program, certifiable proofs given unsafe, macros, evolving semantics, and lack of a fully formalized spec; some say structurally no, others say it’s possible but a lot of work.

Language specs, certification, and alternative compilers

  • Ada has a stable, prescriptive standard; Rust historically used rustc as de facto spec but now has the Ferrocene Language Specification, aimed at safety‑critical certification.
  • Questions are raised about how complete this spec is and whether Rust’s compatibility guarantees match traditional standards.
  • Qualified Rust compilers (e.g., Ferrocene, an AdaCore effort) exist, but typically for a subset of the standard library; Ada tools have a longer certification track record.

Strings, arrays, and typing differences

  • Ada strings are arrays of character types (including wide ones); this makes indexing straightforward but can lead to UTF‑32‑style representations.
  • Rust String/&str are UTF‑8 text types; you slice by ranges, not arbitrary indices, and invalid boundaries panic. For AoC‑style ASCII, byte slices are often more appropriate.
  • Ada arrays can be indexed by arbitrary discrete types; Rust can emulate this via Index implementations but not with built‑in arrays.

Readability, ergonomics, concurrency

  • Several participants feel Ada code is more readable and its OO mechanisms more orthogonal than Rust’s, while Rust wins on lifetimes and modern ergonomics for concurrency and ownership.
  • The article’s suggestion that Rust lacks “out‑of‑the‑box” concurrency support is disputed: threads are in the standard library; async needs runtimes like Tokio mainly for scale or specific platforms.
  • Overall sentiment: Ada is conceptually elegant and safety‑oriented; Rust has momentum, tooling, and ecosystem, so choice often comes down to project domain and library needs.