A feature that for a long time was missing from most languages, but which has been adopted by many during the last decade, is to accept separator characters in numbers, to improve the readability of long numerical constants.

Ada introduced this in 1979, by allowing "_" in numbers. Cobol, in 1960, allowed hyphens in identifiers, for better readability. Because hyphens can be confused with minus, IBM PL/I, in 1964, replaced hyphen with low line, which remains in use until today in most programming languages. Ada extended the usage from identifiers to numbers. Most languages have followed Ada and also use "_" for this purpose, except C++ 2014, which based on a rationale that I consider to be extremely wrong, has substituted the low line with single quote.

While this is an example of an Ada feature that could be easily adopted in any other language, other features are more difficult to adopt without important changes in the language, so they did not spread much.

An example is the specification of the procedure/function parameters as being of 3 kinds, in, out and inout.

This feature was not invented by the Ada team, but by one of the authors of the DoD IRONMAN language specifications, maybe by David Fisher, but the DoD documents do not credit any authors.

In the predecessor of Algol, IAL 1958, the procedure parameters had to be specified as in or out. However this feature was dropped in ALGOL 60. Nevertheless, there was a programming language, JOVIAL, which, unlike most programming languages, was derived directly from IAL 1958, and not from the later version, ALGOL 60.

So JOVIAL inherited the specification of parameters as in or out. JOVIAL happened to be used in many DoD projects, and because of this it influenced the initial versions of the DoD requirements, which eventually resulted in Ada.

The first DoD requirements included the specification of in and out parameters, but in the beginning the authors did not have a good understanding about how the parameter specification should be used, so the DoD requirements had a bad wording, implying that this specification is meant to determine whether the parameters shall be passed by value or by reference.

After several revisions of the DoD requirements, in 1977, the IRONMAN requirements were issued, which were very much improved. By the time when IRONMAN was written, the authors had realized that whether the parameters are passed by value or by reference is an implementation detail that must be decided by the compiler and which must be transparent for the programmer.

Moreover, they realized that 3 categories must be specified, i.e. out and inout must be distinct, because the semantic is very different and the compiler must do different actions to implement them correctly.

Many current programming languages are much more complicated than necessary because they lack this 3-way distinction of parameters.

The language most affected by this is C++, which has struggled for 30 years, from 1980 until 2011, until it has succeeded to include in the language the so called "move semantics", to avoid redundant constructions and destructions of temporaries. Even if now the extra temporaries may be avoided, this requires a contorted syntax.

All such problems could have been trivially avoided since the beginning, if C++ had taken from Ada the "out" and "inout" specifications. During the transition from C with Classes to C++, in 1982-1984, C++ was nonetheless strongly influenced by Ada in the introducing of overloaded functions, overloaded operators and generic functions (templates).

While C++ has introduced the reference parameters, to avoid to write large quantities of "&" and "*", like in C, it would have been much better to apply the Ada method, where it is completely transparent whether the parameters are passed by value or by reference and the programmers never have to deal with "&", unless they use explicit pointers and pointer arithmetic, wherever pointers are really needed for their extra features, not for telling the compiler how to do its job.

This purpose is as obsolete as the use of the keyword "register" for telling the compiler where to allocate variables. Even the C/C++ compilers ignore the fact that the programmer writes that an input parameter shall be passed by value and they pass it by reference anyway if the parameter is too large. This should have been the rule for any kind of parameters.