HN user

onox

58 karma
Posts0
Comments25
View on HN
No posts found.

I do not know the exact rationale of the Alire devs, but Ada already uses (since 83) the word "package" to indicate a module or namespace, so calling dependencies a "crate" seems to avoid confusion with an Ada "package".

The crates of the community index [1] are somewhat vetted because they are added to the index using a PR on GitHub. You're not required to use these external crates though, you can create your own monorepo if you want.

My personal experience has been that a package manager (for any language) makes it much easier to download and build some project.

There's a decent amount of packages in the Ada standard library, but it's not up to the level of Go's. Ada has a subset called SPARK for functional specification and static verification, so you can write, and some of the crates are actually written in SPARK.

It's quite fun to write some parts of the code in SPARK and get it to prove it with the gnatprove tool (which you can get with `alr get gnatprove` and run it on your code with `alr gnatprove`).

AdaCore also has a variant of the runtime library for embedded systems that is partially proven with SPARK [2].

[1] https://github.com/alire-project/alire-index [2] https://blog.adacore.com/proving-the-correctness-of-gnat-lig...

This website is just a community effort to modernize parts of the online resources, because many parts like the current Ada Reference Manual look like they're from the 90s.

The text at the bottom says "unless otherwise noted". The .md files for the AARM are autogenerated and it seems the legal + foreword pages are missing. These indeed need to be added. The announcement was done by an external person, but nonetheless thanks for bringing it to our attention. The website is still work in progress and is intended to be handed off to the Ada community.

Arrays in Ada start at the index based on the index type of the array. You can even use an enumeration type as the index:

    type Day is (Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday);
    type Hours is array (Day range <>) of Natural;

    V : Hours (Monday .. Friday);
Which index type you should use depends on the problem that you're trying to model. You can find out the lower/higher end of a type/variable with the 'First and 'Last attributes.

IIRC there's an RFC though to force the lower end of the index to a certain value like 1 or any other number/enum.

I had a similar problem last month where I needed to compute some results on multiple datasets (with a little bit of concurrency per dataset). In the end I just ported the code to Ada which makes it very easy to create task hierarchies. You can define variables of task types on the 'stack' and the program leaves the enclosing block when the variables can go out of scope after every task has finished. I can now easily put all cores to maximum use. The list comprehensions in Python became a little bit more verbose though because I had to use an older revision (2012) instead of the new 2022 revision.

In Ada you can do something similar:

    delay 0.3;
Or with package Ada.Real_Time:
    delay To_Duration (Milliseconds (300));
Or use `delay until`:
    delay until Clock + Milliseconds (300);
`delay until` is useful in loops because `delay` sleeps at least the given duration, so you get drift. (You call Clock only once and store it in a variable before the loop and then update it adding the time span each iteration)

Sorry, but I disagree. Maybe in the 80s when developers were all yelling while coding :p Does this look like cobol to you?

   type GUID_String is new String (1 .. 32)
     with Dynamic_Predicate => (for all C of GUID_String => C in '0' .. '9' | 'a' .. 'f');
The only thing Ada has in common with cobol is that you can define decimal fixed point types (you specify the number of digits and a delta, which must be a power of 10) [1]

I usually use ordinary fixed point types:

   type Axis_Position is delta 2.0 ** (-15) range -1.0 .. 1.0 - 2.0 ** (-15)
     with Size => 16;
or (from wayland-ada [2]):
   type Fixed is delta 2.0 ** (-8) range -(2.0 ** 23) .. +(2.0 ** 23 - 1.0)
     with Small => 2.0 ** (-8),
          Size  => Integer'Size;
[1] https://en.wikibooks.org/wiki/Ada_Programming/Types/delta#Di... [2] https://github.com/onox/wayland-ada

I've been using ReScript for a few months now. So far I mostly like it, but it takes some time to get used to it. The error messages can be confusing though so I try not to depend too much on type inference. The other downside is that some bindings for some of the web apis seem to be missing (like for the types in the Dom module).

Btw, for Material UI there are already bindings [1]

[1] https://github.com/cca-io/rescript-material-ui

Linux Rust Support 5 years ago

* Ada has pointer arithmetic, you can overflow buffers or read out of bounds.

Not true. Arrays have bounds and those are checked. However, you can do arithmetic with the type ptrdiff_t of the package Interfaces.C.Pointers. You can also do an Ada.Unchecked_Conversion on a pointer that you get from a C function. Obviously that's unsafe.

* Dynamic allocation is straight unsafe and unchecked

If allocation on the heap fails, it will raise a Storage_Error, but you can catch it. Also, the language has a lot of restrictions on when you may copy and store a pointer.

* Accessing uninitialised variables is not forbidden.

True, but there are pragmas like Normalize_Scalars (to initialize them to invalid values) or Initialize_Scalars.

* You can dereference null pointers

True, but dereferencing will raise an exception. Also you can define non-null pointers like this:

    type Foo_Ptr is not null access Foo;
or add a "not null" constraint to a nullable pointer type:
    procedure Bar (Value : not null Foo_Access);

Couldn't you add the Bit_Order and Scalar_Storage_Order attributes (or aspects in Ada 2012) to your records/arrays? Or did Scalar_Storage_Order not exist at the time?

Ada's type system allows you to separate the high-level specification of a type (which models a problem) and its low-level representation (size, alignment, bit/byte order, etc.). The language also requires explicit conversions for two different types even if their underlying representation on the hardware is the same.

Example 1:

   type Byte_Count is range 1 .. 4
     with Static_Predicate => Byte_Count in 1 | 2 | 4;  -- Aspects are Ada 2012

   type Component_Count is range 1 .. 4;

   V1 : Byte_Count      := 3;   --  compiler error: expression fails predicate check
   V2 : Component_Count := V1;  --  compiler error: requires explicit conversion
For these two types I'm not really concerned about how they are represented by the hardware, but I could if I needed to.

Example 2:

Extra constraints added to some pre-defined types:

   subtype String8 is String
     with Dynamic_Predicate => String8'Length <= 8;

   subtype Even_Integer is Integer
     with Dynamic_Predicate => Even_Integer mod 2 = 0,
          Predicate_Failure => "Even_Integer must be a multiple of 2";
Example 3:

Use big-endian for some network packets:

   type Packet_Type is record
      Header : Header_Type;
      Data   : Data_Type;
   end record;
Low-level representation (placed in the private part of a package spec):
   for Packet_Type use record
      Header at 0 range   0 .. 255;
      Data   at 0 range 256 .. 1855;
   end record;

   for Packet_Type'Bit_Order use System.High_Order_First;
   for Packet_Type'Scalar_Storage_Order use System.High_Order_First;
   for Packet_Type'Size use 232 * System.Storage_Unit;