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/&strare 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
Indeximplementations 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.