News from the Ada front
The next revision of the Ada standard is now almost ready, so it's time for a status update on where GNAT and AdaCore stand on this front!
This new standard, called Ada 202x for now, is currently getting the final touches at the ARG (Ada Rapporteur Group) before official standardization by the relevant ISO bodies (WG9, SC22 and JTC1). If you want to know more about these groups, you can visit this page. In all likelihood, Ada 202x will become the new official version of Ada by the end of 2021 or early 2022, so may become Ada 2022.
In any event, we'll call it Ada 202x here, and GNAT Pro 21 will provide support for many of the new features under the -gnat2020 and -gnatX switches as detailed below. The 21.0 preview has just be released to our customers and the official 21.1 release will be available in February 2021.
Ada 202x contains many useful features that complement nicely the current Ada standard, in particular those related to expressiveness of the language and with a focus on programming by contract, introduced with Ada 2012. We'll detail some of these in this blog post.
Assessing Ada 202x and making some tough choices
In the past year or so, we have been working hard assessing and implementing most of these Ada 202x changes (called AIs: Ada Issues in ARG terms). The implementation work and feedback from first users allowed us to identify that a few of these features would need additional time and attention. This led us to make a difficult decision - in order to allow for more investigation and to avoid users to start to rely on constructs that may need to change or be replaced, we decided to put on hold the implementation of some of the changes in language. Of course, we’re currently engaged with the ARG to discuss these.
The main set of features that AdaCore and GNAT are putting on hold are related to the support for parallel constructs. While the overall vision is an exciting and promising one, we realized when looking at the state of the art and gathering user requirements that there were a lot more aspects to consider on top of those currently addressed by the AIs. Some of these are related to GPGPU (General Purpose GPU) support as well as their future CPU counterparts, and include topics such as control of memory transfer, precise allocation of tasks and memory on the hardware layout, target-aware fine tuning options as well as various other parametrization needs. These capabilities happen to be fundamental to obtain actual performance benefits from parallel programming, and providing them may require profound changes in the language interface. Consequently, we’re putting all parallel AIs on hold, including support for the Global and Nonblocking aspects beyond the current support in SPARK.
Note also as a reminder that GNAT Pro already takes full advantage of multicore environments on all its supported targets using Ada tasking, including on bare metal platforms via its Ravenscar and now Jorvik (see below) runtimes.
Ada 202x features already supported in GNAT Pro 21
So back to the Ada 202x support offered in GNAT Pro 21... We have already implemented over 200 AIs, including the following new features:
Jorvik is a subset of the Ada tasking capabilities, similar to Ravenscar and which imposes fewer restrictions, removing the following ones compared to the Ravenscar profile:
- Max_Entry_Queue_Length => 1
- Max_Protected_Entries => 1
- No_Dependence => Ada.Calendar
- No_Dependence => Ada.Synchronous_Barriers
The configuration pragma
pragma Profile now supports
Jorvik as a possible value to enforce the restrictions and is available as part of the
ravenscar-full runtimes on bare metal platforms.
Improvements to the 'Image attribute
A number of improvements have been done in the way the ‘Image attribute works. In particular, this attribute can be used directly on objects and now applies to any type, and not just scalar types.
A new attribute and aspect
Put_Image has been introduced, allowing a custom implementation for any type as a replacement of the default supplied one. The exact form of the user supplied Put_Image procedure is still under finalization at the ARG and is provided in an intermediate form in GNAT Pro 21 which will likely change in release 22.
Four new packages,
System.Atomic_Operations.Modular_Arithmetic now support accessing processor-specific atomic operations, allowing users to write thread-safe concurrent code without the use of system locks. Support for volatile and atomic objects are also further refined via the
Full_Access_Only aspect to ensure that objects are always read and written entirely.
Support for infinite precision numbers
Two new packages
Ada.Numerics.Big_Numbers.Big_Reals provide support for unbounded integer and real numbers with arithmetic operations implemented in software.
Literals for user types (Integer, Real, String) can also be specified and are supported by default for the infinite precision number types.
Variadic C function import
Importing variadic functions was not portable and not easily done in practice without resorting to writing C wrappers. It is now supported via a new convention,
C_Variadic_N, where N is the number of fixed parameters in the C profile:
procedure printf (format : String; optional_param1 : int) with Import, Convention => C_Variadic_1; printf ("value is %d" & LF & NUL, 20);
Improved expression and contract expressiveness
Ada 202x now allows declaring constants and renamings inside a declare expression, which facilitates writing more complex preconditions and postconditions:
Val : Integer := (declare X : constant Integer := Random_Value; begin X + X);
This Ada feature replaces the SPARK 'Update attribute and allows modifying partially the copy of an object:
Record_Object := (Record_Object with delta Field1 => X, Field2 => Y);
Contracts on Access-to-Subprogram
Aspects Pre and Post can now be specified on access to subprogram types. As a consequence, when a call is made from such a type, the contract of the type will be executed, together with the specific contracts of the called subprogram if any.
Static expression functions
Ada 202x defines a new aspect Static that can be specified on expression functions. Such an expression function can be called in contexts requiring static expressions when the actual parameters are all static, allowing for greater abstraction in complex static expressions. For example:
function Half_Size (S : Integer) return Integer is (S / 2) with Static; type T is range 0 .. 10 with Size => Half_Size (Integer'Size);
Iterators can now be provided with an optional filter. This can be used in loops or in the new container aggregates and reduce expressions. For example:
for E of Some_Array when E /= 0 loop Put_Line (E'Image); end loop;
Indexes in array aggregate
Array aggregates now support a for-loop like syntax:
(for Index in 1 .. Count => Function_Returning_Limited (Index))
Assignment target name @
Ada 202x provides a convenient shortcut to refer to the left hand side of an assignment statement, as in:
Some_Very_Long.And_Complex (Expression) := @ + 1; Another_Very_Long.And_Complex (Expression) := Function_Call (@);
Renames with type inference
The type information in a renames clause now becomes optional, as in:
X renames Y;
This means also that named numbers can now be renamed as well:
PI : constant := 3.1415926; PI2 renames PI;
A new attribute
'Reduce is available for experimentation under the -gnatX switch. It supports performing a map/reduce operation over the values of a container. For example:
X : Integer := (1, 2, 3)'Reduce ("+", 0);
Will add 1, 2 and 3, and store the result (6) in X.
You can now initialize a container object via the aggregate notation, e.g:
V : Vector := (1, 2, 3);
In GNAT Pro 22, we will complete the implementation of all the relevant AIs, and at the same time have started a language prototyping and experimentation effort to prepare future Ada (and SPARK) revisions, including many exciting or most wanted features such as a simplified model for accessibility checks and anonymous access types, generalized case statements on any type (aka pattern matching), simplified and universal storage pools, more static guarantees (e.g. on object initialization), improved string processing in the standard library, simplified finalization support, implicit generic instantiations, ... If you are interested, you can follow and give your input and ideas on this effort via the Ada & SPARK RFC open platform.