• A Package to Simplify Ada Programming

    From John Herro@user13545@newsgrouper.org.invalid to comp.lang.ada on Mon Jan 5 10:52:58 2026
    From Newsgroup: comp.lang.ada


    My name is John Herro. I'm a retired Sr. Software Engineer, and I continue to program in Ada as a hobby.

    I've written a package called Simplify to simplify Ada programming and make Ada code less cluttered. I've used it with almost all my programs for several years now, and would like to make it available to the Ada community without charge (and without warranty!). Simplify.ada is about 775 lines long, so it's not posted here. Since I don't have access to newsgroup binaries, if you'd like a copy of the package, please email me (desertpete at duck dot com). The package will work with any version of Ada, 1995 or later. Here are a few of its features:

    STRINGS:
    Unbounded_String can be abbreviated to Ustr.
    Unary minus converts both ways between Ustr and String so you don't have to clutter your code by writing To_Unbounded_String() and To_String(), and you can write -"" instead of Null_Unbounded_String.
    Unary plus returns the length of a Ustr or a String, e.g., for I in 1 .. +U loop ...
    A String can be concatenated with a number; the number will first be converted to a String.
    Overloaded procedures Inp simplify text input of a Ustr or a numeric variable. Foe example,

    with Ada.Text_IO, Simplify; use Ada.Text_IO, Simplify;
    procedure greet is
    Name : Ustr;
    Age : Natural;
    begin
    Inp("What is your name? ", Name);
    Put_Line(-Name & ", it's good to meet you!");
    Inp("How old are you? ", Age);
    Put_Line("Congratulations on being " & Age & " years old!");
    end greet;

    Here's another example of how much the unary minus can reduce clutter:
    Names : array(1 .. 4) of Ustr := (-"Alice", -"Bob", -"Carol", -"Dan");

    TEXT FILES:
    You can optionally omit the mode designators In_File and Out_File. If omitted, In_File is assumed when opening a text file and Out_File is assumed when creating a text file. Overloaded procedures Inp simplify input of a Ustr or a number from a text file. E.g.,

    with Ada.Text_IO, Simplify; use Ada.Text_IO, Simplify;
    ...
    F1, F2 : File_Type;
    First_Line : Ustr;
    ...
    Open(F1, "input.txt");
    Create(F2, "output.txt");
    Inp(F1, First_Line);
    ...

    COMMAND LINE:
    Overloaded procedures Get_Arg simplify getting arguments from the command line. E.g.,
    procedure Get_Arg(Prompt : in String; N : in Positive; I : out Integer);
    gets the Nth command-line argument and converts it to an Integer. If the argumennt is not present on the command line, the procedure prints Prompt and gets the input from the user.

    There's more. For example, there are procedures and functions concerning directories and random numbers, all designed to simplify programming and make the code less cluttered.

    The package is free for the asking, and is unconditionally guaranteed to be worth exactly the price. :)

    As a fun exercise, I used Simplify in creating an Ada version of the famous ELIZA script. (Weizenbaum, Joseph [January 1966]. "ELIZA--A Computer Program for the Study of Natural Language Communication Between Man and Machine," Communications of the ACM. 9: pp. 36–45.) I'll send you a copy of eliza.ada (about 820 lines) along with Simplify.ada.

    I welcome your comments and suggestions. Enjoy!
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From John Herro@user13545@newsgrouper.org.invalid to comp.lang.ada on Tue Jan 6 12:41:16 2026
    From Newsgroup: comp.lang.ada


    Nioclás Pól advised me to post just the specification of simplify.ada,
    so here it is. You can still get the entire package, along with eliza.ada,
    by emailing me.

    ----------

    -- The purpose of this package is to help simplify programming in Ada. It's in -- the public domain with no warranty. I welcome your comments and suggestions. -- You can find my email address and postal address at bible73.com.
    -- John Herro 2026-01-05

    with Ada.Text_IO, Ada.Strings.Unbounded, Ada.Characters.Handling;
    with Ada.Directories, Ada.Strings.Fixed;
    use Ada.Text_IO, Ada.Strings.Unbounded;
    package Simplify is

    ------------------------------------------------------------------------------- -- Renames and functions to make Ada software less cluttered -------------------------------------------------------------------------------
    subtype Ustr is Unbounded_String;
    subtype Hex2_Range is Integer range 0 .. 16#FF#;
    subtype Hex4_Range is Integer range 0 .. 16#FFFF#;
    subtype Hex8_Range is Long_Integer range 0 .. 16#FFFFFFFF#;
    function "-"(U : in Ustr) return String renames To_String;
    function "-"(S : in String) return Ustr renames To_Unbounded_String;
    function "+"(U : in Ustr) return Natural renames Length;
    function "+"(S : in String) return Natural; -- Returns S'Length
    function Img(I : in Integer) return String renames Integer'Image;
    function Img(L : in Long_Integer) return String renames Long_Integer'Image;
    function Img(F : in Float) return String renames Float'Image;
    function Img(G : in Long_Float) return String renames Long_Float'Image;
    function Img(B : in Boolean) return String renames Boolean'Image;
    function Val(S : in String) return Integer renames Integer'Value;
    function Val(S : in String) return Long_Integer renames Long_Integer'Value;
    function Val(S : in String) return Float renames Float'Value;
    function Val(S : in String) return Long_Float renames Long_Float'Value;
    function Chr(I : in Natural) return Character; -- Returns Character'Val(I)
    function Cpos(C : in Character) return Natural; -- Returns Character'Pos(C)
    function Floor(F : in Float) return Integer;
    function Floor(G : in Long_Float) return Integer;
    function Ceiling(F : in Float) return Integer;
    function Ceiling(G : in Long_Float) return Integer;
    function Round(F : in Float) return Integer;
    function Round(G : in Long_Float) return Integer;
    function Rand(Lo, Hi : in Integer) return Integer;
    function Rand(Lo, Hi : in Float) return Float;
    -- Rand returns a random number between Lo and Hi, inclusive.

    ------------------------------------------------------------------------------- -- Functions and procedures to simplify string handling -------------------------------------------------------------------------------
    function StripL(S : in String) return String; -- Strips leading white space.
    function StripR(S : in String) return String; -- Strips trailing white space.
    function Strip(S : in String) return String;
    -- Strips leading and trailing white space.
    function "abs"(Right : in String) return String; -- Right enclosed in quotes.
    -- Used in debugging to see trailing white space in strings.
    function StrL(S : in String; Width : in Positive) return String;
    function StrR(S : in String; Width : in Positive) return String;
    -- Justifies a string to the left or right to a specified width, padding
    -- with spaces. If Width is insufficient, returns all asterisks.
    function Comma(I : in Integer) return String;
    -- E.g., if I = 1234560 then Comma(I) = "1,234,560"
    function Money(Cents : in Integer) return String;
    -- E.g., if Cents = 1234560 then Money(Cents) = "12,345.60"
    function Comma(L : in Long_Integer) return String;
    function Money(Cents : in Long_Integer) return String;
    procedure Replace(U : in out Ustr; S1, S2 : in String);
    -- Replaces every occurrence of S1 with S2 in U.

    -- These four functions allow concatenating a number with a string by first
    -- converting the number to a string. E.g., Put_Line("2**12 = " & 2**12);
    function "&"(Left : in Integer; Right : in String) return String;
    function "&"(Left : in String; Right : in Integer) return String;
    function "&"(Left : in Float; Right : in String) return String;
    function "&"(Left : in String; Right : in Float) return String;

    -- Exporting these commonly-used control characters often makes it
    -- unnecessary for programs to with and use Ada.Characters.Latin_1. Many
    -- programs need only with and use Ada.Text_IO and Simplify.
    Bel : constant Character := Character'Val(7);
    Tab : constant Character := Character'Val(9);
    LF : constant Character := Character'Val(10);
    FF : constant Character := Character'Val(12);
    CR : constant Character := Character'Val(13);
    Esc : constant Character := Character'Val(27);

    ------------------------------------------------------------------------------- -- Procedures to simplify text input -------------------------------------------------------------------------------
    procedure Inp(Prompt : in String; U : out Ustr);
    -- Prints Prompt, gets a line of text from the user, and stores it in U.
    procedure Inp(Fil : in out File_Type; U : out Ustr);
    -- Gets a line from a text file and stores it in U. For compatibility
    -- with files created either on Windows or Linux systems, if the last
    -- character read is CR, it is discarded.

    procedure Inp(Prompt : in String; I : out Integer);
    procedure Inp(Prompt : in String; L : out Long_Integer);
    procedure Inp(Prompt : in String; F : out Float);
    procedure Inp(Prompt : in String; G : out Long_Float);
    procedure Inp(Fil : in out File_Type; I : out Integer);
    procedure Inp(Fil : in out File_Type; L : out Long_Integer);
    procedure Inp(Fil : in out File_Type; F : out Float);
    procedure Inp(Fil : in out File_Type; G : out Long_Float);
    -- These eight procedures simplify inputting a number. They get a line
    -- of text from the user or from a text file and convert it to a number.

    -- Renames for developing Ada software on a smartphone, where line length is
    -- limited. Get_Line is not included because procedures Inp are usually used
    -- instead of Get_Line:
    procedure PL(S : in String) renames Ada.Text_IO.Put_Line;
    procedure PL(F : in File_Type; S : in String) renames Ada.Text_IO.Put_Line;
    subtype Int is Integer;
    subtype Char is Character;

    ------------------------------------------------------------------------------- -- Variables to strings -------------------------------------------------------------------------------
    function Str(I : in Integer) return String;
    -- Converts an Integer to a string, removing any leading
    -- space. To keep any leading space, use Img(I) instead.
    function Str(F : in Float) return String;
    function Str(G : in Long_Float) return String;
    -- These two functions return a "nicely formatted" string from a Float
    -- or a Long_Float. Based on the magnitue of the number, they decide
    -- whether or not to use scientific notation. When scientific notation is
    -- not used, they suppress any trailing zeros after the decimal point.
    -- These functions also suppress a leading space, if present.
    function Str(B : in Boolean) return String; -- Returns "T" or "F".
    function Str(I : in Integer; Width : in Positive) return String;
    function Str(F : in Float; Width : in Positive) return String;
    function Str(G : in Long_Float; Width: in Positive) return String;
    -- These three functions convert a number to a string, Width characters
    -- wide, with the number is right-justified and padded on the left with
    -- spaces. If Width is too small to contain the number, the functions
    -- return a string of all asterisks.
    function Str0(I : in Natural; Width : in Positive) return String;
    -- Converts a Natural to a String, Width characters wide, with the number
    -- right justified and padded on the left with zeros. If Width is too
    -- small to contain the number, returns a String of all asterisks.
    -- E.g., Str0(2, Width => 3) = "002"
    function Hex2(I : in Hex2_Range) return String;
    function Hex4(I : in Hex4_Range) return String;
    function Hex8(L : in Hex8_Range) return String;
    -- These functions return a 2-, 4-, or 8-character hexadecimal String.
    function Dec(Hex_Str : in String) return Natural; -- Hex to decimal ------------------------------------------------------------------------------- -- File operations -------------------------------------------------------------------------------
    procedure Open(Prompt : in String; F : in out File_Type);
    procedure Create(Prompt : in String; F : in out File_Type);
    -- These two procedures prompt for the name of a file, opening the
    -- file with mode In_File or creating the file with mode Out_File.
    procedure Open(F : in out File_Type; Name : in String);
    procedure Create(F : in out File_Type; Name : in String);
    -- These procedures open or create a file when the name is already known.
    function More(F : in out File_Type) return Boolean;
    -- True if the file F has not reached end of file.
    function Exist(Name: in String)return Boolean renames Ada.Directories.Exists;

    ------------------------------------------------------------------------------- -- Procedures to access the command line -------------------------------------------------------------------------------
    procedure Get_Arg(Prompt : in String; N : in Positive; I : out Integer);
    procedure Get_Arg(Prompt : in String; N : in Positive; L : out Long_Integer);
    procedure Get_Arg(Prompt : in String; N : in Positive; F : out Float);
    procedure Get_Arg(Prompt : in String; N : in Positive; G : out Long_Float);
    procedure Get_Arg(Prompt : in String; N : in Positive; U : out Ustr);
    -- These procedures get the Nth command-line argument. If the argument
    -- is not present, they print Prompt and get the input from the user.

    ------------------------------------------------------------------------------- -- Functions and procedures from child packages of Ada -------------------------------------------------------------------------------
    -- These functions often make it unnecessary to with and use child packages
    -- of Ada. In many cases it's sufficient to with and use only Ada.Text_IO and
    -- Simplify.
    function "&"(Left : in Ustr; Right : in Ustr) return Ustr renames
    Ada.Strings.Unbounded."&";
    function "*"(Left : in Natural; Right : in Character) return String renames
    Ada.Strings.Fixed."*";
    function "*"(Left : in Natural; Right : in String) return String renames
    Ada.Strings.Fixed."*";
    function Lower(C : in Character) return Character renames
    Ada.Characters.Handling.To_Lower;
    function Lower(C : in String) return String renames
    Ada.Characters.Handling.To_Lower;
    function Upper(C : in Character) return Character renames
    Ada.Characters.Handling.To_Upper;
    function Upper(C : in String) return String renames
    Ada.Characters.Handling.To_Upper;
    function Index(Source : in String; Pattern : in Character) return Natural;
    function Index(Source, Pattern : in String) return Natural;
    function Seg(Source : in Ustr; Low : in Positive; High : in Natural) return
    String renames Slice;
    function Elem(Source : in Ustr; Index : in Positive) return Character renames
    Element;
    procedure Repl_Elem(Source : in out Ustr; Index : in Positive;
    By : in Character) renames Replace_Element;
    procedure Repl_Seg(Source : in out Ustr; Low : in Positive; High : in Natural;
    By : in String) renames Replace_Slice;

    ------------------------------------------------------------------------------- -- Functions and procedures involving directories -------------------------------------------------------------------------------
    procedure Start_Dir(Pattern : in String := ""); -- Starts a directory search.
    procedure Next_File; -- Sets One_File to the next file in the dir. search.
    function More_Files return Boolean; -- True if there are more files in Srch.
    function File_Name return String; -- Returns name of One_File.
    function Bytes return Long_Integer; -- Size of File_Name in bytes.
    function Bytes(Name : in String) return Long_Integer; -- Size of Name.
    function File_Ext return String; -- Returns extension without the dot.
    function File_Base return String; -- Returns name without extension and dot.
    procedure End_Dir; -- Ends a directory search.

    -- For example, this program shows the names of all of the .txt files in the
    -- current directory:
    -- with Ada.Text_IO, Simplify; use Ada.Text_IO, Simplify;
    -- procedure list_text_files is
    -- begin
    -- Start_Dir("*.txt");
    -- while More_Files loop
    -- Next_File;
    -- Put_Line(File_Name);
    -- end loop;
    -- End_Dir;
    -- end list_text_files;

    function dir return String renames Ada.Directories.Current_Directory;
    procedure cd(Dir : in String) renames Ada.Directories.Set_Directory;
    procedure rm(Name : in String) renames Ada.Directories.Delete_File;
    procedure cp(From, To : in String; Form : in String := "") renames
    Ada.Directories.Copy_File;
    procedure mv(From, To : in String);
    -- These last four procedures mimic the Linux commands
    -- for change directory, remove, copy, and move.
    end Simplify;
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Lawrence =?iso-8859-13?q?D=FFOliveiro?=@ldo@nz.invalid to comp.lang.ada on Tue Jan 6 20:12:07 2026
    From Newsgroup: comp.lang.ada

    On Tue, 06 Jan 2026 12:41:16 GMT, John Herro wrote:

    -- These four functions allow concatenating a number with a string by first
    -- converting the number to a string. E.g., Put_Line("2**12 = " & 2**12);
    function "&"(Left : in Integer; Right : in String) return String;
    function "&"(Left : in String; Right : in Integer) return String;
    function "&"(Left : in Float; Right : in String) return String;
    function "&"(Left : in String; Right : in Float) return String;

    Given many years of painful experience with languages that have this
    sort of thing built-in (namely JavaScript and PHP), this is the sort
    of “feature” that wise heads would not want to spread any further ...
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From John Herro@user13545@newsgrouper.org.invalid to comp.lang.ada on Wed Jan 7 13:26:17 2026
    From Newsgroup: comp.lang.ada


    Lawrence =?iso-8859-13?q?D=FFOliveiro?= <ldo@nz.invalid> posted:

    On Tue, 06 Jan 2026 12:41:16 GMT, John Herro wrote:

    -- These four functions allow concatenating a number with a string by first
    -- converting the number to a string. E.g., Put_Line("2**12 = " & 2**12);
    function "&"(Left : in Integer; Right : in String) return String;
    function "&"(Left : in String; Right : in Integer) return String;
    function "&"(Left : in Float; Right : in String) return String;
    function "&"(Left : in String; Right : in Float) return String;

    Given many years of painful experience with languages that have this
    sort of thing built-in (namely JavaScript and PHP), this is the sort
    of “feature” that wise heads would not want to spread any further ...

    Dear Lawrence,
    You probably know a lot more about programming than I do. Only two people have written me for a copy of the package, and they're free to remove - and
    probably should remove - any dangerous "features." You could still write Put_Line("2**12 = " & Str(2**12));
    and
    Put_Line("Congratulations on being " & Str(Age) & " years old!");
    On a side note, I apologize for re-posting my entire original message when Nioclás Pól advised me to post the package specification. I had no idea that the reply to the original post would include the entire original! Sorry!
    Happy programming!
    - John

    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From thanks-to@thanks-to@Taf.com to comp.lang.ada on Wed Jan 7 18:00:37 2026
    From Newsgroup: comp.lang.ada

    On Wed, 7 Jan 2026, John Herro wrote: |----------------------------------------------------------------------------| |"[. . .] | |On a side note, I apologize for re-posting my entire original message when | |Nioclás Pól advised me to post the package specification. I had no idea that|
    |the reply to the original post would include the entire original! Sorry! | |Happy programming! | |- John" | |----------------------------------------------------------------------------|

    There is nothing to apologize for here. I do not see that this entire
    original message is posted again: perhaps John is using a new display
    program which shows him an entire thread. Even if a re-posting happened
    and I do not see it - so what? This group needs more posts instead of
    fewer posts and redundancy is a good way for backups. Furthermore, not all USENET sites succeed to pick up all posts in a subscribed newsgroup.

    One year (i.e. 2025) of comp.lang.ada has only circa 275 articles and only circa 710 kilobytes - small enough for a 3.5" medium.

    Below are statistics for all years before 2025 estimated from the archive
    by Jeremy Grosser's Legitimate Data Company . . .

    results-dt-19820101000000.19821231000000.mbox megabytes = 0
    approximate quantity of articles = 15 results-dt-19830101000000.19831231000000.mbox megabytes = .1
    approximate quantity of articles = 79 results-dt-19840101000000.19841231000000.mbox megabytes = .1
    approximate quantity of articles = 60 results-dt-19850101000000.19851231000000.mbox megabytes = 1.1
    approximate quantity of articles = 491 results-dt-19860101000000.19861231000000.mbox megabytes = 1.4
    approximate quantity of articles = 701 results-dt-19870101000000.19871231000000.mbox megabytes = 1.7
    approximate quantity of articles = 833 results-dt-19880101000000.19881231000000.mbox megabytes = 2.2
    approximate quantity of articles = 1017 results-dt-19890101000000.19891231000000.mbox megabytes = 3.2
    approximate quantity of articles = 1275 results-dt-19900101000000.19901231000000.mbox megabytes = 3.0
    approximate quantity of articles = 1319 results-dt-19910101000000.19911231000000.mbox megabytes = 4.0
    approximate quantity of articles = 1935 results-dt-19920101000000.19921231000000.mbox megabytes = 2.5
    approximate quantity of articles = 1256 results-dt-19930101000000.19931231000000.mbox megabytes = 6.6
    approximate quantity of articles = 3315 results-dt-19940101000000.19941231000000.mbox megabytes = 8.1
    approximate quantity of articles = 2990 results-dt-19950101000000.19951231000000.mbox megabytes = 7.0
    approximate quantity of articles = 2913 results-dt-19960101000000.19961231000000.mbox megabytes = 32.5
    approximate quantity of articles = 13023 results-dt-19970101000000.19971231000000.mbox megabytes = 30.2
    approximate quantity of articles = 12341 results-dt-19980101000000.19981231000000.mbox megabytes = 18.1
    approximate quantity of articles = 7613 results-dt-19990101000000.19991231000000.mbox megabytes = 25.3
    approximate quantity of articles = 11159 results-dt-20000101000000.20001231000000.mbox megabytes = 19.6
    approximate quantity of articles = 8596 results-dt-20010101000000.20011231000000.mbox megabytes = 42.3
    approximate quantity of articles = 15491 results-dt-20020101000000.20021231000000.mbox megabytes = 35.4
    approximate quantity of articles = 13995 results-dt-20030101000000.20031231000000.mbox megabytes = 40.0
    approximate quantity of articles = 14664 results-dt-20040101000000.20041231000000.mbox megabytes = 28.3
    approximate quantity of articles = 10348 results-dt-20050101000000.20051231000000.mbox megabytes = 21.5
    approximate quantity of articles = 8029 results-dt-20060101000000.20061231000000.mbox megabytes = 14.8
    approximate quantity of articles = 5499 results-dt-20070101000000.20071231000000.mbox megabytes = 18.8
    approximate quantity of articles = 6230 results-dt-20080101000000.20081231000000.mbox megabytes = 14.5
    approximate quantity of articles = 5182 results-dt-20090101000000.20091231000000.mbox megabytes = 14.9
    approximate quantity of articles = 5141 results-dt-20100101000000.20101231000000.mbox megabytes = 22.0
    approximate quantity of articles = 7251 results-dt-20110101000000.20111231000000.mbox megabytes = 18.3
    approximate quantity of articles = 6096 results-dt-20120101000000.20121231000000.mbox megabytes = 20.6
    approximate quantity of articles = 6882 results-dt-20130101000000.20131231000000.mbox megabytes = 14.1
    approximate quantity of articles = 4457 results-dt-20140101000000.20141231000000.mbox megabytes = 22.6
    approximate quantity of articles = 6696 results-dt-20150101000000.20151231000000.mbox megabytes = 12.6
    approximate quantity of articles = 4518 results-dt-20160101000000.20161231000000.mbox megabytes = 10.2
    approximate quantity of articles = 3691 results-dt-20170101000000.20171231000000.mbox megabytes = 10.3
    approximate quantity of articles = 3754 results-dt-20180101000000.20181231000000.mbox megabytes = 15.4
    approximate quantity of articles = 5241 results-dt-20190101000000.20191231000000.mbox megabytes = 7.1
    approximate quantity of articles = 2501 results-dt-20200101000000.20201231000000.mbox megabytes = 6.6
    approximate quantity of articles = 2366 results-dt-20210101000000.20211231000000.mbox megabytes = 5.7
    approximate quantity of articles = 2143 results-dt-20220101000000.20221231000000.mbox megabytes = 3.0
    approximate quantity of articles = 1190 results-dt-20230101000000.20231231000000.mbox megabytes = 3.1
    approximate quantity of articles = 1109 results-dt-20240101000000.20241231000000.mbox megabytes = 1.0
    approximate quantity of articles = 470

    (S. HTTP://Gloucester.Insomnia247.NL/ fuer Kontaktdaten!)
    --- Synchronet 3.21a-Linux NewsLink 1.2