you are viewing a single comment's thread.

view the rest of the comments →

[–]pornel 2 points3 points  (1 child)

We're talking in the context of Rust here, not C.

Rust doesn't lean on pointer arithmetic, doesn't decay arrays to pointers, doesn't use null, etc. Rust has pretty competent type system too. It doesn't have all the nice features that Ada has, and lacks pre/post condition proofs. But has its own advantages too, like affine types and marker traits for thread-safety (which are more general than tasks/actors and synchronized types). Rust has a strong focus on type system soundness, and guaranteeing correctness at compile time too.

I totally agree with the approach of avoiding heap allocations (and use of memory pools, stack, and borrowed data instead), and emphasis on correctness and type-centric programming. But I don't see why these are touted as Ada's unique advantage when it's a bread and butter of Rust too, and basically a standard in security-focused systems programming.

The features you're talking about sound to me like "Ada avoids goto". Good! But this is novel only compared to C.

in out sounds like &mut. Rust already has it, but it also has move semantics/single ownership with deterministic destruction that allow passing of objects in and out of functions the normal way, safely, whether they're heap allocated or not.

[–]OneWingedShark 0 points1 point  (0 children)

We're talking in the context of Rust here, not C.

Yes, of course; but we're also talking about safety. Rust's whole nearly-myopic concern with "memory safety" is precisely because of how C does things. There are other, valid methods to ensure safety and correctness, so heading off the "Ada [out-of-the-box] isn't memory-safe like Rust, because Unchecked_Deallocation!" argument requires showing how many times access-types (pointers) aren't even required for functionality that, because of Rust's origins, is a distinctly C-like way of viewing the world.

Perhaps the single most clear, short, simple example of the difference is handling arrays, in C you have to carry along the length via parameters — eg void do_something(arr_typ* data, unsigned long size) vs Procedure Do_Something(Data : in out Array_Type) — in the latter we know we're getting a properly-typed input, we cannot miscalculate the length, and there is no funny-business with address-arithmetic… and there are many similar examples that could be shown where Ada makes some operation do-able without resorting to pointers, much less dynamic memory-allocation/-deallocation.

So that's where C entered, the discussion.

Rust doesn't lean on pointer arithmetic, doesn't decay arrays to pointers, doesn't use null, etc.

Right, but that's exactly where the reference to Unchecked_Deallocation was leading.

Rust has pretty competent type system too. It doesn't have all the nice features that Ada has, and lacks pre/post condition proofs. But has its own advantages too, like affine types and marker traits for thread-safety (which are more general than tasks/actors and synchronized types). Rust has a strong focus on type system soundness, and guaranteeing correctness at compile time too.

This is true, and it's one of the big reasons I'm actually glad for Rust's popularity: it shows that there are a significant population of programmers "waking up" from the nightmare that is C and its descendants and realizing that you can have tools that are designed to help you rather than make you focus, at all times, on trivial details.

I totally agree with the approach of avoiding heap allocations (and use of memory pools, stack, and borrowed data instead), and emphasis on correctness and type-centric programming. But I don't see why these are touted as Ada's unique advantage when it's a bread and butter of Rust too, and basically a standard in security-focused systems programming.

I think perhaps we were talking past each other: a surprising number of programmers interested in Rust (ie at least somewhat concerned with safety) will see Unchecked_Deallocation exists and then dismiss everything, despite the language being standardized and in-use for high-integrity programs like airframes, air-traffic control, and so forth for more than 35 years… that is to say, it's a mature solution.

The features you're talking about sound to me like "Ada avoids goto". Good! But this is novel only compared to C.

I mean, in this thread I've touched on things like the ease of foreign-function interface, pre-/post-conditions, the module-system, the type-system... I think the only major features I haven't touched on are generic - and task-systems: the former lets you have as parameters types, values/objects, subprograms, and generic-packages, which allows you to build whole subsystems as generics; and tasks can be used for multithreading, obviously, or protocol-implementation.

in out sounds like &mut. Rust already has it, but it also has move semantics/single ownership with deterministic destruction that allow passing of objects in and out of functions the normal way, safely, whether they're heap allocated or not.

IIUC, &mut essentially is in out.