Ubuntu: not GNU anymore. An opportunity for Ada/SPARK?

I can even anticipate a backlash for Rust in this particular case: if a memory leak bug is identified in one of these utilities, the news will spread worldwide, whereas the same bug in the original C utility would interest no one. But since Rust’s promise is to end these bugs, everyone will talk about it.
Do we want that for Ada?

Yep, we had our Ariane V. I must shamelessly confess that I would have a good deal of schadenfreude if something similar happened to Rust, even if Rust were blamed as undeservedly as Ada was.

This was discussed in the Github issue as being difficult because Rust is not standardised.
I wouldn’t count on Interfaces.Rust until Rust gets some semblance of stability

Both interface to C, so you can probably export your functions using Rust FFI to C and import on the Ada using convention C (or vice versa). You shouldn’t need any actual C code, just use the ABI to link the two languages.

How can I show a concrete example of something that I don’t even have syntax for?
Again, I am trying to solve this problem, but at this point there’s no syntax — this is fine, but you’re asking for the end-result pizza before even deciding on the toppings, much less cooking it.

This is perhaps the big sticking-point: it “works”, but is tied to dozens of horrible design-choices, and could be done much, much better… but it “works”, which means that at the psychological level everything that is done prior to having a usable successor is wasted effort. (Moreover, in order to actually do things well would entail much of what amounts to a redesign of portions of the OS — and at that level it’s probably easier inertia-wise [and psychologically] to write a new OS, keeping to better design-principles.)

Somewhat agreed: you need to introduce an order-of-magnitude better quality (usability or speed or correctness) in order for such a replacement to be noticed/recognized… but even if you do, a significant “it’s different!” might tank the reception.

TBH, I’ve been puzzled why Ada hasn’t been adopted by two groups: (a) device-driver producers, and (b) open-source projects. Ada’s (and particularly SPARK’s) concern for correctness makes it an obvious choice for driver-work; Ada’s pre- and post-conditions [and type-system], conjoined with its ease of foreign-function interfacing, makes it very well-suited for open-source projects where you want a robust system/library that (a) catches errors as quickly as possible, and (b) rather points/assists in using it correctly.

There’s no standard for Rust, so in order to implement an Interfaces.Rust you would be tying yourself to a particular implementation — this might not be a bad thing, as you could do something like a unified Rust/Ada compiler and use such Interfaces.Rust within. (There was something kinda-similar in the mid 80s with Ada/Lisp: Symbolics put out an Ada compiler which tied into the underlying Lisp, apparently able to take advantage of their LISP’s BigNum implementation and things like the tail-recursion optimization.)

This is the biggest thing, and TBH, I consider the lack of stability and standard to undermine essentially all the claims of safety (in all but the “academic interest” aspects).

This is terrible, shit-tier advice… even/especially if it works.
It’s the sort of “it works” that boils things down to the shittiest common-denominator and locks everything to it; the sort of technical debt that is never paid and never addressed, always cropping up in inconvenient manner… the sort of limitations that you get when your public-facing APIP is obviously using RegEx to “parse” CSV, but which will never be addressed with proper parsing because now the API is codified with those restrictions.

TL;DR — I hate C as a dependency.

Can you keep the insults out of this please? I was just trying to give the person something they can at least work with in the near term. If you think it is a bad idea, then fine, let them know there are better ways and give them a better way to accomplish it, but that response is horribly insulting. You could have approached that way better. I don’t like my options there either, but things are what they are in the current state.

If you dislike me this much, then please just put me on ignore so you don’t have to see my crappy posts.

It’s not that I dislike you.
It’s that I’m so, So, SO tired of C (and, to an extent, Unix/Linux) as the “least common denominator” such that everything is crippled for the sake of “compatibility”, because “it works”.

Why can’t we pass arrays that know their own length? Because C.
Why can’t we have exception-based handling in [low-level-ish] libraries? Because C.
Why can’t we have sane enumerations? Because C.
Why can’t we have structured, formatted, uniform command-line processing? Because C/Unix. (Check out Amiga and VMS.)
Why can’t we have a good build-system? Because C. (Literally, the preprocessor and treating everything like text combine to make the “simple” of compiling into a rat’s-nest of configuration and process management.)
Why can’t we have portability? Because C.

Take a “portable” C program, compare it with @VMo’s experience: compiling a DIANA frontend with a compiler that didn’t exist, on an OS that didn’t exist, with minimal changes — instead of programming to the problem-space, C forces you to program to the [current-]archetecture, and then pretends like that’s “portable”.

Now, yes, I was a bit harsh, and insulting, too: I apologize.
(I’m in the middle of updating an API, written in C, for 16-/32-bit Windows [with “portability” to other OSes], and so am quite frustrated with C: especially when I’m going to have to "iron-out " the whole thing for the mismatches in 16-/32-bits and 64-bit systems, while trying to figure out the documentation-gaps… -fdump-ada-spec is of very limited use, and the reference-implementation code goes from commented to… not.)

I appreciate that. Thank you.

And for what it’s worth, I dislike working in C myself, but my job requires it so I continue on. And in some cases it is potentially the only means to an end (in the current time, the future is what we make it).

Syntax is irrelevant. You claimed that no dispatch and no classes were needed. So I asked how this were supposed to work. You made that claim on other occasions before. But always refusing to explain what you mean, e.g. how, for example, a widget library can be designed without run-time classes.

Ah!
Ok, so I think I see now — the conceptual-level.

Here’s how you would do the specific of e.g. [[Wide_]Wide_]String

  1. Assume Abstract-part #1: Have a abstract-interface, in particular the indexing-mechanism;
  2. Assume Abstract-part #2: Have the structural/consistency mechanism;
  3. Combine #1 # #2 into the particular type, or alternate-phrasing, declare that the type is implementing the abstractions/interfaces.

In current Ada the closest we can come is something like:

Generic
  Type Character is (<>);
  with To_Uppercase( X : Character ) return Character;
  --…
Package String_Base is 
End String_Base;

Generic
  with package Characters is new String_Base( others => <> );
  Type Index is (<>);
Package Strings is
  Type String_Type is Array(Index range <>) of Characters.Character;
  -- String operations.
End Strings;

So, just as generic is static-polymorphism, so we can use the same “technique” in a static-metalanguage for Ada — to vomit out some C-ish code, so that no one will mistake it for the syntax I’d propose:

// How the language/code interfaces/uses the thing:
class Abstract_String<index, character>
{
	private:
		virtual RANGE<index,index>;
	public:	// All the abstract operations of the type; virtual when it's part/renaming of the structure,
			//   const if the operation is essentially a Pure_Function... and static for attributes.
		virtual character &operator [](index I); //Indexing, .
		const Abstract_String &operator + (Abstract_String A, character C);       // Append a character.
		const Abstract_String &operator + (Abstract_String L, Abstract_String R); // Concat a string.
		/*  ... */
		static const index First();
		static const index Last();
		static const RANGE<index,index> Range();
		/*  ... */
}

//similar but different thing for UNICODE, as the previous is about how the language uses the thing, this is about specifying the properties, so that you can hang proofs, akin to Abstract Data Types as taught in CS.
class Unicode<Abstract_String>
{
  private:
     bool is_valid( Abstract_String );
}

And, let’s hijack at and for in Ada as specifying these and have:

  Type Unicode_String for UNICODE at ABSTRACT_STRING is Private;
  -- Or whatever; the important thing is that we're telling the language/compiler 
  -- "Hey, UNICODE_STRING is an array of CODEPOINTS!" and also telling the compiler
  -- "Hey, UNICODE_STRING has X provable/validity rules!"… once we can "factor out"
  -- the how-you-use-it of e.g. Indexing, Finalization, Attributes, etc it simplifies
  -- a *LOT* of implementation-code; once we can "factor out" the provable-properties
  -- we have a system where we can "hang" proofs on, and tie them to the type, thus
  -- allowing the compiler to handle the book-keeping, as well as allowing proofs to
  -- be more incremental/parameterizable.

No need for dynamic anything, no need for tags, no need for dispatch: it is entirely static.

The example is completely irrelevant. Start with UTF-8 and UCS-4 strings. Explain how a program, like Put_Line can be written to work with instances of both. (Hint: this what interface is for)

See as above. Write a program that can use any instance of Abstract_String. Note that this is already possible in Ada!

You do not even arrive at the point where UTF-8 is also an array of octets and UCS-2 is an array of words (little or big endian).

Same, show this factorisation just as above. Let X be an instance of Abstract_String. You do not know if it UTF-8 or UCS-4. How indexing X (I) is supposed to work?

For my part, I see no interest in recoding in another language something that works very well and has been extensively tested.

For a rustacean, all existing code must be recoded in rust.

I think they’re gonna get tired ;>

They are also looking into moving to sudo-rs.

P.S.: there is GitHub - atalii/adage: ada privilege escalation for an Ada-Sudo replacement (WIP)

Great question!

I love the enthusiasm, but I feel like we are lacking serious man-power and not just to write the code, but also to promote it, talk about it, create blogs, comparisons as to why it is better than any of the alternatives, etc… I talk about this issue here https://www.youtube.com/watch?v=TAFlWVsLM-I

They could all use a low level library of common functionality, most likely making them 80% the same, so I agree.

You bring up a very interesting and important point. Rust has backing and momentum, which most people care about (dammed by technical aspects). Ada has none of that.

SPARK to the rescue!

I know about this… But what if we used Ada 2022 vararg improvements and duplicated/tripicalted/nth… (say up-to 5 varargs) the typical functions with varargs and dealt with them independently? Could that solve 99% of all use cases?

Some new standard utilities that people are writing (most in Rust and Go) are now capable of outputing JSON for example. So people are thinking about this and working towards it.

Great point, Ada has little to no history of being used for applications for the general public (I am sure this is not true for a lot of commercial/hidden projects).

+1

+1

I believe you are referring to this video https://www.youtube.com/watch?v=Zugoflsv37A

(note, emphasis mine) This is a very important point. Some people are just very used to something that others are not. Spanish is very simple and clear to me, may not be for a German person though. Trying to sell Ada to a seasoned C++ or Rust developer by showing their own code and the comparison to Ada is just not going to work.

Take this talk as an example https://youtu.be/pnaZ0x9Mmm0?si=CFVQUFiHnl3cfWH1&t=2837 (go to 47:20 if it does not do so automatically) and watch 20 seconds: “Simple, readable, safe”. Those are the words of a very seasoned C++ programmer. Ada had that by default, built-in, no special functions or wierd things like in C++… 40 years ago… What do you think he would think about Ada’s integers?

I very much like Rust’s declarativeness and functionality ^^

This is a nice point. Rust has been designed to be a better C++, so they (and the C people) are the target audience. Someone who is not familiar with those languages may find Rust strange, such a Python or Lua dev. Thing is C/C++/Java/JS all have a very similar style in nature, building on top of each other, so their general ethos is the baseline for the vast majority of programmers.

I FULLY agree, but it is not just Ada. For people who are fully new to programming, they have no preconceived ideas, they are a blank canvas. Most people find LISP/Scheme horrible, but when you are new and you grow up with its design, it can actually be easier to follow! (well, after 5 mins of trying to find my video source, I just cannot find it… but you can check SICP in the MIT as an example).

Agreed.

When they say that, hit them hard, very hard with the following answer: “Well, with what other language would you have said the same thing? Do you want me to show you the same example in Kotlin or modern C++ and you tell me if it is obvious or not? Would you prefer to work in a language that you have difficulties understanding what is going on?” People are highly unimpressed by Ada because they understand it. THIS must become an important selling point. We need to point out the Stockholm syndrome most people have.

See the C++ video I linked above. Programmers want to feel smart, they think that when they solve a problem they created, they are smart. They feel empowered when they don’t shoot themselves in the foot (or leg) because they have some kind of arcane knowledge. Maybe I am a bit cynical, I work in the Nuclear industry, we do not try to be smart. We find pleasure in making things work okay, not in feeling smart or playing around. But that is why I like programming…

This bring a great point. A lot of production code does not tend to be public, other types of programs are. I like watching Bloomberg’s engineers talk in Cppcon, their code is HEAVILY annotated, guarded, etc; and no body would like to work like that. BUT, that is not the C++ code you are sold. You are sold the simple examples, the ones where you don’t care about exceptions, about correctness, etc… This can be applied to Rust for example. How much code is out there that uses .unwrap()? Plenty. Should you be using it? Maybe not. But the explicit handling of the error case does not look as good as .unwrap(), so the Rust people leave that point as a footnote…

And then there is C++ for maps… https://www.youtube.com/watch?v=lkgszkPnV8g (minute 7:00) and for key-values (minute 13:30).

And Fabien hits the Bullseye once again!

There were no paying jobs when Rust was getting started and growing initially… I discuss that in the first video I linked. It is a chicken and an egg problem. Rust persevered, showed the world the value it brought, it kept on going, it kept on making sure people knew about it. Eventually it won.

105% agree!

NVIDIA chose Ada/SPARK for a reason! And SPARK is less “fun”, so if you have limited time for hobbies/open-source, would you like to write something that half-way works, or do you want to make sure it is SPARK level of goodness?

There will be in little time!

Heaven IMHO.

EDIT: regarding my Stockholm syndrome, this blog post summarizes things quite well Matt Godbolt sold me on Rust (by showing me C++) (hey, strong typing is good! who would have guessed, thanks Rust!)

Not really. Formal verification cannot prevent algorithmic errors, it can and does implementation errors.

Outputting JSON isn’t hitting the design-level core that I’m trying to get at and impress on you.
Consider, for a moment, the MVC-pattern and how it dovetails directly into this discussion:

  • the model: is the thing-the-underlying-system operates on, the “type” (ie inputs),
    (for ls/dir/mkdir/rm/etc, this is the file-system: its structure and files/objects.)
  • the controller: is the thing whereby user-manipulations are handled,
    (for FS, this would be search/query, and attribute/property manipulation, & CRUD ops.)
  • the view: is the thing than handles display (ie data-output)
    (This would be the thing that handles the typed-stream output and either passes it on, or displays it.)

As you can see, this isn’t merely about “oh, we need ls to be free of algorithmic errors and buffer-overflow”, but a more holistic: “we need to have the underlying concept (structured containers) codified, correct, and then address the ‘how do we de-serialize the information.’

I do not understand your point. Since then Ada has moved towards large application development.

Djikstra called it a cult and he wasn’t wrong.

At least you cannot blame rustaceans of being lazy.

Some Adaists have the opposite stance, like: “Someone (but not me) will just do a C wrapper, that’s so easy!”

Binding to C is a good way to burn out. I’d lay money on Rust having good C->Rust transpilers and binding generators.

Successful open-source operating systems (Linux, FreeBSD…) are written in C, then C is the natural language to develop drivers. Nowadays, Rust seems to be considered for writing Linux driver too, but there are some opposition. There are multiple obstacles which can be common between Ada and Rust : multiplying needed langage to know, complexity (bindings, Makefile), limiting the number of targets if the OS is ported to architectures not supported by the Ada or Rust compiler.