Live data from Hacker News

Should I choose Ada, SPARK, or Rust over C/C++? (2024)

blog.adacore.com

161–170 of 173 posts

Re: Should I choose Ada, SPARK, or Rust over C/C++? (2024)

#161
post #158

Earlier quoted context omitted.

As a more general rant - people who have maybe used 5% of the feature set of C++ come along and explain why language X is superior because it has feature Y and Z. News flash, C++ has every conceivable feature, it's the reason why it is so unwieldy. But you can even plug in a fucking GC if you so desire. Let alone stuff like basic meta programming.

GC was removed from the C++ standard in C++23 because all the compilers were like "hell no" and it was an optional feature so they could get away with not adding it. So this optional feature never actually existed and they removed it in later standards.

There are ways to do GC without language support. They are harder, but have been around in various forms for decades. They have never caught on though.

Re: Should I choose Ada, SPARK, or Rust over C/C++? (2024)

#162

Earlier quoted context omitted.

operator* can return exactly one type. You can choose which, but metric offers many possible choices, and with floating point math on computers you will lose precision converting between them in some cases so you need to take care to get the right on for your users - which will not be the same for all users.

One return type, for any given combination of parameter types, not to mention the possibility of templating to manipulate the return type….

See, more trade offs...

Re: Should I choose Ada, SPARK, or Rust over C/C++? (2024)

#163
post #44

Earlier quoted context omitted.

I'm super interested how you can do this in C++. Say, I need aggregate struct with a few 16 and 32 bit fields, some are little endian and some big endian. I do not want C++ to let me mix up endianness. How do I do it?

There's several libraries, including some supporting units and mathematical operations yielding the correct result types. And as usual, it mostly comes with zero overhead, beyond optional runtime range checking and unit conversions. But C++ is a meta-programming language. Making up your own types with full operator overloading and implicit and explicit conversions is rather easy. And the ADA feature of automatically…

But do these libraries allow using values in aggregates (i.e. structs that can be initialized by listing members in {} )? While preventing endianness errors

Re: Should I choose Ada, SPARK, or Rust over C/C++? (2024)

#164
post #158

Earlier quoted context omitted.

As a more general rant - people who have maybe used 5% of the feature set of C++ come along and explain why language X is superior because it has feature Y and Z. News flash, C++ has every conceivable feature, it's the reason why it is so unwieldy. But you can even plug in a fucking GC if you so desire. Let alone stuff like basic meta programming.

GC was removed from the C++ standard in C++23 because all the compilers were like "hell no" and it was an optional feature so they could get away with not adding it. So this optional feature never actually existed and they removed it in later standards.

The C++ standard has never included a garbage collector. It only provided mechanisms intended to facilitate the implementation of a GC, but they were useless.

Re: Should I choose Ada, SPARK, or Rust over C/C++? (2024)

#165
post #149

Earlier quoted context omitted.

If I remember correctly, he meant that only array accesses are used, because their length can be checked (as all arrays have a static length due to no dynamic memory).

Indeed, this is what many people do. But even if you use dynamic memory, if you replace pointer arithmetic by array indexing, you get bounds checking. And in C this also works for arrays of run-time length.

But can't I put any pointer arithmetic in array brackets, so it wouldn't limit anything?

Re: Should I choose Ada, SPARK, or Rust over C/C++? (2024)

#166

Earlier quoted context omitted.

> How did you prove that no one could just put in an arbitrary integer into that function? Does it fail to compile? The answer quite literally follows immediately after the code sample you quoted: > Attempting to prove the absence of runtime errors gives us the following warnings: buffer_overflow.adb:162:26: medium: unexpected exception might be raised 162 | Ada.Integer_Text_IO.Get (Index_To_Clear); | ~~~~~~~~~~~~~~~…

> The SPARK prover correctly notices that there's nothing stopping us from entering a value outside the array bounds. It also points out that the Get call we're using to read the integer from stdin can raise an unexpected Constraint_Error at runtime if you type in anything that can't be parsed as an integer. To me, this doesn't sound like something unique to spark. Let's return to the solution example: procedure Over…

> Again, I don't see how this is any different or special compared to any other programming language that would handle the error by asking the user to retry the function.

The blog's emphasis is that SPARK catches the possible error at compile time, so you can't forget/neglect to handle the error. Notice that neither rustc nor clippy complain at compile time about the potential OOB access in the Rust program that precedes the SPARK demo, while SPARK catches the potential issue in the naive translation.

> But I think the discussion here is about Rust, Ada, C/C++ no?

Sure, but my point is that type systems are not all equally capable. I don't think it's controversial at all that Rust's type system is capable of proving things at compile time that C++'s type system cannot, the most obvious examples being memory safety and data race safety. Likewise, SPARK (and C++, for that matter) is capable of things that Rust is not.

> The type system in Rust, Ada, and C++ are all robust enough at least to accomplish this.

I'm not sure about that? You might be able to approach what SPARK could do, but at least off the top of my head you'll need to make a check the compiler can't verify somewhere.

And that's just for this instance; I don't think Rust nor C++ are able to match SPARK's more general capabilities. For example, I believe neither Rust nor C++ are able to express "this will not panic/throw" in their type systems. There are tricks for the former that approximate the functionality (e.g., dtolnay/no_panic [0]), but those are not part of the type system and have limitations (e.g., does not work with panic=abort). The latter has `noexcept`, but that's basically semantically a try { } catch (...) { std::terminate(); } around the corresponding function and it certainly won't stop you from throwing or calling a throwing function anyways.

> Exactly! This is the root of my issue: you can accomplish this magical "proof" you speak of without using SPARK or Ada or any special "contract" language.

Perhaps I wasn't clear enough. I was trying to say that it's contradictory to complain about formal proofs while also claiming you can accomplish the same using other programming languages' type systems because those type systems are formal proofs! It's like saying "You don't need formal proofs; just use this other kind of formal proofs".

I don't think that assertion is correct either. The reason separate languages are used for this kind of proof is because they restrict operations that can't be proven, add constructs that provide additional information needed for the proof, or both. Perhaps as an extreme example, consider trying to make compile-time proofs for a "traditional" dynamically-typed language - Smalltalk, pre-type-hints Python, Lua, etc.

[0]: https://github.com/dtolnay/no-panic

Re: Should I choose Ada, SPARK, or Rust over C/C++? (2024)

#167

Earlier quoted context omitted.

What needs to be "maintained" in a flying aircraft? If it's in need of an update, why was it certified to fly that way in the first place? Also in safety critical apps, being "difficult" can be a feature, not a big. Should we have easier turbofans so we can pop them open and swap out blades and rings for tiny little improvements? No. Every flight critical component should be fully understood as a prerequisite for use…

> why was it certified to fly that way in the first place? Are you under the impression that software for aircraft is exceptionally good? A lot of the software for aircraft (for LRUs, avionics, whatever) are made by the same kind of developers as most other software.

You have no idea what you're talking about

Re: Should I choose Ada, SPARK, or Rust over C/C++? (2024)

#168

Earlier quoted context omitted.

> why was it certified to fly that way in the first place? Are you under the impression that software for aircraft is exceptionally good? A lot of the software for aircraft (for LRUs, avionics, whatever) are made by the same kind of developers as most other software.

You have no idea what you're talking about

Nearly 20 years in the aerospace industry, you're right, no clue.

Re: Should I choose Ada, SPARK, or Rust over C/C++? (2024)

#169

Earlier quoted context omitted.

One return type, for any given combination of parameter types, not to mention the possibility of templating to manipulate the return type….

See, more trade offs...

honestly, I’m not seeing the problem you’re seeing

Re: Should I choose Ada, SPARK, or Rust over C/C++? (2024)

#170
post #90

Earlier quoted context omitted.

Though if you do that km times km isn't km it is a volume - so your custom type would be wrong to have all operations. what unit km times km should be isn't clear.

These libraries already exist. God how people underestimate C++ all the time. Of course you can use a unit type that handles conversions AND mathematical operations. Feet to meter cubed and you get m³, and the library will throw a compile error if you try to assign it to anything it doesn't work with (liters would be fine, for example)

Do they really? Their types really have no custom constructors and you can use designated initializers for your data? I would really much like to have been underestimating C++, could you show an example of such a library?
Post reply on HN