From bfee8bccc6beee4ff5fc916af0fc89e7110c0324 Mon Sep 17 00:00:00 2001
From: "Luke A. Guest" <laguest@archeia.com>
Date: Fri, 12 Jan 2024 18:18:30 +0000
Subject: [PATCH] [language/en] Add ada (#4821)

* Add initial Ada docs.

* Change wording.

* Update Empty.

* Remove old comments which have been added to the code.
Have one code block now.

* Update source.

* Add bash to the code block so I get syntax colouring in vscode.

* Add extra on context clauses.

* Update source.

* Add loops.

* Add a warning about the source.

* Update source.

* Add real-time to the description.

* Add info on aspects/contracts.

* Add links to RM.

* Add string/character/array.

* Update source.

* Add new package.

* Add extra info on what's left from Pascal.

* Add fixed/floats.

* Add link to the RM.
Change wording.

* Add distributed with link.

* Fix typo.

* Add a statement on package use.

* Add extra info re the warnings.

* Add more context re Pascal.

* Separate paragraphs.

* More clarification.

* Fix typo.

* Change aspect-oriented to contract-based.

* Add about having to download the gnat toolchain.

* Rejig paragraph.

* Add the extra run commands.

* Add Fer's changes.

* Fix typo.

* Remove extraneous ---, don't know how that got there.

* Fix filename.

* Remove extra comment.

* Remove another empty comment.

* Add back in the generic Swap which was removed for some reason.

* Correction on style.
GNAT definition added.

* Fix definition of starting index of strings.

* Add extra context and examples for String initialisation.

* Remove line to install the toolchain.
Add note about this.

* Add https://learn.adacore.com as a link.

* Add Fabien's contributor link for the extra context added in the previous commits.

* Fix typos.
Add better explanations.

* Add info on limited types.

* Fix typos.

* Add explanation of the generic parameter.

* Add a location of where I referenced OOP.

* Fix text.

* Remove markdown from comments.

* Remove comma.
---
 ada.html.markdown | 416 ++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 416 insertions(+)
 create mode 100644 ada.html.markdown

diff --git a/ada.html.markdown b/ada.html.markdown
new file mode 100644
index 00000000..a06792b3
--- /dev/null
+++ b/ada.html.markdown
@@ -0,0 +1,416 @@
+---
+language: Ada
+filename: learn.ada
+contributors:
+    ["Luke A. Guest", "https://github.com/Lucretia"]
+    ["Fernando Oleo Blanco", "https://github.com/Irvise"]
+    ["Fabien Chouteau", "https://github.com/Fabien-Chouteau"]
+    ["Manuel", "https://github.com/mgrojo"]
+---
+
+Ada is a strong statically typed imperative, [object-oriented](https://ada-lang.io/docs/arm/AA-3/AA-3.9), [real-time](https://ada-lang.io/docs/arm/AA-D), [parallel](https://ada-lang.io/docs/arm/AA-9) and [distributed](https://ada-lang.io/docs/arm/AA-9) programming language from the Pascal/Algol family of languages, but nowadays, it only has a passing resemblance to Pascal, with the only remnants left being the ```begin/end``` keyword pair, the ```:=``` assignment symbol, records and ```if/case``` control statement structures.
+
+Ada was originally designed to be an [object-based](https://ada-lang.io/docs/arm/AA-3/AA-3.3) language and to replace 100's of languages in use by the US government. This means that all entities are objects, not in the object-oriented sense. The language became [Object-Oriented](https://ada-lang.io/docs/arm/AA-3/AA-3.9) in 1995, and added [interfaces](https://ada-lang.io/docs/arm/AA-3/AA-3.9#Subclause_3.9.4) derived from Java in 2005. [Contract based](https://ada-lang.io/docs/arm/AA-13/AA-13.1#Subclause_13.1.1) programming was introduced with Ada 2012.
+
+Ada was designed to be easy to read and learn, even for non-programmers, e.g. management within an organisation, therefore programs written in the language tend to be a bit more verbose.
+
+Ada is a modern programming language, and now has a package manager like other modern languages, Alire, see below.
+
+```ada
+--  Comments are written with a double hyphen and exist until the end of
+--  the line.
+
+--  You do not need to call the entry point "Main" or "main," you should
+--  name it based on what the program does.
+procedure Empty is
+   --  This is a declarative part.
+begin
+   --  Statements go here.
+   null;  --  Do nothing here.
+end Empty;
+
+--  Ada compilers accept compilation units which can be library packages,
+--  tasks, sub-programs, generics, etc.
+
+--  This is where "context clauses" go, these can be pragmas or "with"
+--  statements. "with" is equivalent to "include" or "import" in other
+--  languages.
+with Ada.Text_IO;  --  Get access to a library package.
+
+procedure Hello is
+begin
+   Ada.Text_IO.Put_Line ("Hello, world");
+
+   Ada.Text_IO.Put ("Hello again, world");
+   Ada.Text_IO.New_Line;
+end Hello;
+
+
+--  Ada has a real module system. Modules are called packages and are split into
+--  two component parts, the specification and a body.
+--  It is important to introduce packages early, as you will be using them from
+--  the start.
+package Stuff is
+   --  We could add the following line in order to tell the compiler that this
+   --  package does not have to run any code before the "main" procedure starts.
+   --  pragma Preelaborate;
+
+   --  Packages can be nested within the same file or externally.
+   --  Nested packages are accessed via dot notation, e.g. Stuff.Things.My.
+   package Things is
+      My : constant Integer := 100;
+   end Things;
+
+   --  If there are sub-programs declared within the specification, the body
+   --  of the sub-program must be declared within the package body.
+   procedure Do_Something;  --  If a subprogram takes no parameters, empty
+                            --  parentheses are not required, unlike other
+                            --  languages.
+
+   --  We can also make generic sub-programs.
+   generic
+      type Element is (<>);  --  The "(<>)" notation specifies that only
+                             --  discrete types can be passed into the generic.
+   procedure Swap (Left, Right : in out Element);
+
+   --  Sometimes we want to hide how a type is defined from the outside world
+   --  so that nobody can mess with it directly. The full type must be defined
+   --  within the private section below.
+   type Blobs is private;
+
+   --  We can also make types "limited" by putting this keyword after the "is"
+   --  keyword, this means that the user cannot copy objects of that type
+   --  around, like they normally could.
+private
+   type Blobs is new Integer range -25 .. 25;
+end Stuff;
+
+
+package body Stuff is
+   --  Sub-program body.
+   procedure Do_Something is
+      --  We can nest sub-programs too.
+      --  Parameters are defined with the direction of travel, in, in out, out.
+      --  If the direction of travel is not specified, they are in by default.
+      function Times_4 (Value : in Integer) return Integer is
+      begin
+         return Value * 4;
+      end Times_4;
+
+      I : Integer := 4;
+   begin
+      I := Times_4 (I);
+   end Do_Something;
+
+
+   --  Generic procedure body.
+   procedure Swap (Left, Right : in out Element) is
+      Temp : Element := Left;
+   begin
+      Left  := Right;
+      Right := Temp;
+   end Swap;
+begin
+   --  If we need to initialise something within the package, we can do it
+   --  here.
+   Do_Something;
+end Stuff;
+
+
+with Ada.Unchecked_Conversion;
+with Ada.Text_IO;
+with Stuff;
+
+procedure LearnAdaInY is
+   --  Indentation is 3 spaces.
+
+   --  The most important feature in Ada is the type. Objects have types and an
+   --  object of one type cannot be assigned to an object of another type.
+
+   --  You can, and should, define your own types for the domain you are
+   --  modelling. But you can use the standard types to start with and then
+   --  replace them later with your own types, this could be called a form of
+   --  gradual typing.
+
+   --  The standard types would only really be a good starting point for binding
+   --  to other languages, like C. Ada is the only language with a standardised
+   --  way to bind with C, Fortran and COBOL! See the links in the References
+   --  section with more information on binding to these languages.
+
+   type Degrees is range 0 .. 360;  --  This is a type. Its underlying
+                                    --  representation is an Integer.
+
+   type Hues is (Red, Green, Blue, Purple, Yellow);  --  So is this. Here, we
+                                                     --  are declaring an
+                                                     --  Enumeration.
+
+   --  This is a modular type. They behave like Integers that automatically
+   --  wrap around. In this specific case, the range would be 0 .. 359.
+   --  If we added 1 to a variable containing the value 359, we would receive
+   --  back 0. They are very useful for arrays.
+   type Degrees_Wrap is mod 360;
+
+   --  You can restrict a type's range using a subtype, this makes them
+   --  compatible with each other, i.e. the subtype can be assigned to an
+   --  object of the type, as can be seen below.
+   subtype Primaries is Hues range Red .. Blue;  --  This is a range.
+
+   --  You can define variables or constants like this:
+   --  Var_Name : Type := Value;
+
+   --  10 is a universal integer. These universal numerics can be used with
+   --  any type which matches the base type.
+   Angle : Degrees := 10;
+   Value : Integer := 20;
+   --  New_Angle : Degrees := Value;  --  Incompatible types won't compile.
+   --  New_Value : Integer := Angle;
+
+   Blue_Hue   :          Primaries := Blue;  --  A variable.
+   Red_Hue    : constant Primaries := Red;   --  A constant.
+   Yellow_Hue : constant Hues      := Yellow;
+   Colour_1   : constant Hues      := Red_Hue;
+   --  Colour_2   : constant Primaries := Yellow_Hue;  --  uncomment to compile.
+
+   --  You can force conversions, but then you are warned by the name of the
+   --  package that you may be doing something unsafe.
+   function Degrees_To_Int is new Ada.Unchecked_Conversion
+     (Source => Degrees,   --  Line continuations are indented by 2 spaces.
+      Target => Integer);
+
+   New_Value_2 : Integer := Degrees_To_Int (Angle);  --  Note, space before (.
+
+   --  GNAT is the GNU Ada Translator (compiler).
+   --  Ada has a style guide and GNAT will warn you to adhere to it, and has
+   --  option to check your style so that you can correct it so that all Ada
+   --  source looks consistent. However, the style can be customized.
+
+   --  Yes, you can even define your own floating and fixed point types, this
+   --  is a very rare and unique ability. "digits" refers to the minimum
+   --  digit precision that the type should support. "delta" is for fixed
+   --  point types and refers to the smallest change that the type will support.
+   type Real_Angles is digits 3 range 0.0 .. 360.0;
+   type Fixed_Angles is delta 0.01 digits 5 range 0.0 .. 360.0;
+
+   RA : constant Real_Angles  := 36.45;
+   FA : constant Fixed_Angles := 360.0;  --  ".0" in order to make it a Float.
+
+   --  You can have normal Latin 1 based strings by default.
+   Str  : constant String    := "This is a constant string";
+   --  When initialising from a string literal, the compiler knows the bounds,
+   --  so we don't have to define them.
+
+   --  Strings are arrays. Note how parentheses are used to access elements of
+   --  an array? This is mathematical notation and was used because square
+   --  brackets were not available on all keyboards at the time Ada was
+   --  created. Also, because an array can be seen as a function from a
+   --  mathematical perspective, so it made converting between arrays and
+   --  functions easier.
+   Char : constant Character := Str (Str'First);  --  "'First" is a type
+                                                  --  attribute.
+
+   --  Ada 2022 includes the use of [] for array initialisation when using
+   --  containers, which were added in Ada 2012.
+
+   --  Arrays are usually always defined as a type.
+   --  They can be any dimension.
+   type My_Array_1 is array (1 .. 4, 3 .. 7, -20 .. 20) of Integer;
+
+   --  Yes, unlike other languages, you can index arrays with other discrete
+   --  types such as enumerations and modular types or arbitrary ranges.
+   type Axes is (X, Y, Z);
+
+   --  You can define the array's range using the 'Range attribute from
+   --  another type.
+   type Vector is array (Axes'Range) of Float;
+
+   V1 : constant Vector := (0.0, 0.0, 1.0);
+
+   --  A record is the same as a structure in C, C++.
+   type Entities is record
+      Name     : String (1 .. 10);  --  Always starts at a positive value,
+                                    --  inclusive range.
+      Position : Vector;
+   end record;
+
+   --  In Ada, array bounds are immutable. You therefore have to provide a
+   --  string literal with a value for every character.
+   E1 : constant Entities := ("Blob      ", (0.0, 0.0, 0.0));
+
+   --  An alternative is to use an array aggregate and assign a default value
+   --  to every element that wasn't previously assigned in this aggregate.
+   --  "others" is used to indicate anything else that has not been
+   --  explicitly initialized.
+   E2 : constant Entities := (('B', 'l', 'o', 'b', others => ' '),
+                              (0.0, 0.0, 0.0));
+
+   --  There are dynamic length strings (see references section) available in
+   --  the standard library.
+
+   --  We can make an object be initialised to its default values with the box
+   --  notation, "<>". "others" is used to indicate anything else that has not
+   --  been explicitly initialized.
+   Null_Entity : constant Entities := (others => <>);
+
+   --  Object-orientation is accomplished via an extension of record syntax,
+   --  tagged records, see link above in first paragraph.
+
+   --  We can rename objects (aliases) to make readability a bit better.
+   package IO renames Ada.Text_IO;
+begin
+   --  We can output enumerations as names.
+   IO.Put_Line ("Blue_Hue   = " &  --  & is the string concatenation operator.
+                Blue'Image);       --  ' accesses attributes on objects.
+                  --  The Image attribute converts a value to a string.
+                  --  Ada 2022 has extended Image to custom types too.
+                  --  Access this with -gnat2022 compiler flag.
+   IO.Put_Line ("Yellow_Hue = " &
+                --  We can use the type's attribute.
+                Primaries'Image (Yellow_Hue));
+
+   --  We can define local variables within a declare block, this can be made
+   --  more readable by giving it a label.
+   Enum_IO : declare
+      package Hue_IO is new IO.Enumeration_IO (Hues);
+
+      --  Using a package makes everything inside that package visible within
+      --  this block, it is good practice to only do this locally and not on
+      --  a whole package within the context clause.
+      use Hue_IO;
+   begin
+      --  We can print out the enumeration values too.
+      Put (Purple); --  Note we don't have to prefix the Put procedure with
+                    --  Hue_IO.
+      IO.New_Line;  --  We still need to prefix with IO here.
+      Put (Red_Hue);
+      IO.New_Line;
+   end Enum_IO;
+
+   --  Loops have a consistent form. "<form> loop ... end loop".
+   --  Where "form" can be "while" or "for" or missing as below, if
+   --  you place the "loop ... end loop;" construct on their own lines,
+   --  you can comment out or experiment with different loop constructs more
+   --  easily.
+   declare
+      Counter : Positive := Positive'First;  --  This is 1.
+   begin
+      --  We can label loops so we can exit from them more easily if we need to.
+      Infinite :
+      loop
+         IO.Put_Line ("[Infinite loop] Counter = " & Counter'Image);
+
+         Counter := Counter + 1;
+
+         --  This next line implements a repeat ... until or do ... while loop construct.
+         --  Comment it out for an infinite loop.
+         exit Infinite when Counter = 5;  --  Equality tests use a single "=".
+      end loop Infinite;  --  Useful when implementing state machines.
+   end;
+
+   declare  --  We don't have to have a label.
+      Counter : Positive := Positive'First;  --  This is 1.
+   begin
+      while Counter < 10
+      loop
+         IO.Put_Line ("Counter = " & Counter'Image);
+
+         Counter := Counter + 1;  --  There is no explicit inc/decrement.
+
+         --  Ada 2022 introduced @ for LHS, so the above would be written as
+         --  Counter := @ + 1;  --  Try it, -gnat2022.
+      end loop;
+   end;
+
+   declare
+      package Hue_IO is new IO.Enumeration_IO (Hues);
+
+      --  We can have multiple packages on one line, but I tend to use one
+      --  package per line for readability.
+      use IO, Hue_IO;
+   begin
+      Put ("Hues : ");  --  Note, no prefix.
+
+      --  Because we are using the 'Range attribute, the compiler knows it is
+      --  safe and can omit run-time checks here.
+      for Hue in Hues'Range
+      loop
+         Put (Hue);
+
+         --  Types and objects know about their bounds, their First .. Last
+         --  values. These can be specified as range types.
+         if Hue /= Hues'Last then  --  The /= means "not equal to" like the
+                                   --  maths symbol ≠.
+            Put (", ");
+         end if;
+      end loop;
+
+      IO.New_Line;
+   end;
+
+   --  All objects know their bounds, including strings.
+   declare
+      C : Character := Str (50);  --  Warning caused and exception raised at
+                                  --  runtime.
+      --  The exception raised above can only be handled by an outer scope,
+      --  see wikibook link below.
+   begin
+      null;  --  We will never get to this point because of the above.
+   end;
+exception
+   when Constraint_Error =>
+      IO.Put_Line ("Caught the exception");
+end LearnAdaInY;
+```
+
+Now, that's a lot of information for a basic intro to Ada, and I've only touched the surface, there's much more to look at in the references section below. I haven't even touched on dynamic memory allocation which includes [pools](https://ada-lang.io/docs/arm/AA-13/AA-13.11), this is because for the most part, Ada programs don't need it, you can do a lot without it.
+
+As I stated above, Ada barely looks like Pascal and if you look at the original [Green specification](https://apps.dtic.mil/sti/trecms/pdf/ADB950587.pdf) (Warning: Huge 4575 page scanned PDF - starting on page 460), it looks nothing like it at all (page 505 of that PDF).
+
+The above source code will compile, but also will give warnings showing the power of the strong static type system.
+
+## Download this source
+
+If you already have the GNAT toolchain installed, you can cut and paste the above into a new file, e.g. ```learn-ada-in-y.ada``` and then run the following:
+
+```bash
+$ gnatchop learn-ada-in-y.ada # This breaks the program into its specification ".ads" and body ".adb".
+$ gnatmake empty.adb # gnatmake takes care of compilation of all units and linking.
+$ gnatmake hello.adb
+$ gnatmake learnadainy.adb
+```
+
+Or, download [Alire](https://alire.ada.dev), copy it to somewhere in your PATH and then do the following:
+
+**N.B.** Alire will automatically install the toolchain for you if you don't have one installed and will ask you to select which you want to use.
+
+```bash
+$ alr search learnadainy
+$ alr get learnadainy
+$ cd learnadainy
+$ alr run empty
+$ alr run hello
+$ alr run learnadainy
+```
+
+## Further Reading
+
+* [Ada Programming Language](https://ada-lang.io)
+* [Ada 2022 Reference Manual](https://ada-lang.io/docs/arm)
+* [Ada Style Guide](https://ada-lang.io/docs/style-guide/Ada_Style_Guide)
+* [Learn more Ada/Spark at AdaCore's site](https://learn.adacore.com)
+
+## References from the source above
+
+1. [wikibook](https://en.wikibooks.org/wiki/Ada_Programming/Exceptions#Exception_handlers)
+2. [C](https://ada-lang.io/docs/arm/AA-B/AA-B.3)
+3. [Fortran](https://ada-lang.io/docs/arm/AA-B/AA-B.5/)
+4. [COBOL](https://ada-lang.io/docs/arm/AA-B/AA-B.4/)
+5. [dynamic length strings](https://ada-lang.io/docs/arm/AA-A/AA-A.4#Subclause_A.4.5)
+
+### Multi-line comments
+
+Multi-line comments are not allowed as they are error prone.
+
+> Such comments would require a closing comment delimiter and this would again raise the dangers associated with the (unintentional) omission of the closing delimiter: entire sections of a program could be ignored by the compiler without the programmer realizing it
+>
+> [Ada 83 Rationale](http://archive.adaic.com/standards/83rat/html/ratl-02-01.html#2.1)
+