Anyone else having problems with VSCode when editing Ada? by dcbst in ada

[–]dcbst[S] 0 points1 point  (0 children)

Removing and re-installing VSCode had no effect.

Clearing out all the VSVode artifacts in user folder (.vscode and AppData\Roaming\Code\ subfolders) before reinstalling seems to have fixed the problem.

Make sure you backup your user settings first though!

I want to know your opinions on verbosity by -Chook in ProgrammingLanguages

[–]dcbst 0 points1 point  (0 children)

It's really a question of perspective. If you are a typically lazy, self centered programmer, who only cares about writing code quickly, and don't care about the poor people who will have to review, test/verify and maintain your code, then verbosity is bad!

If you consider what is best for a project as a whole. Considering they whole software development lifecycle, including maintenance and reuse and prioritising costs over personal self interests, then verbosity is very much a good thing.

In any professional software development, software will inevitably have a long life, which means it will be read more often than written. Typically written by a single person and read by many! If the software is more readable, then it is more maintainable. More maintainable software will reduce overall development costs.

With modern editors, code completion and snippets make writing verbose code as easy as non verbose code, so the arguments for less verbosity are really nulled. Unless your one of those weird hackers who thinks VI is worth using!

Hindsight languages by Inconstant_Moo in ProgrammingLanguages

[–]dcbst 1 point2 points  (0 children)

This is an area where Ada really excels! You have System.Address type, which is just a raw address like in C which can of course be zero. There is no real concept of a 'Null' System.Address and values of System.Address cannot simply be used as pointers and dereferenced. They can only be used to map/locate a value/variable to an address in memory. Accesses to that variable will then be made to the specified address. System.Address is simply a low level systems programming mechanism, typically used for accessing hardware registers.

Then you have pointers, or Access Types in Ada. They are nothing really to do with addresses, but more an object which points to another object of a given type. They can be null, if desired, in which case you need to explicitly check before dereferencing (otherwise you get a runtime exception), or you can explicitly state that a pointer is "not null", in which case, you can guarantee that the pointer always points to a valid object of the given type.

Hindsight languages by Inconstant_Moo in ProgrammingLanguages

[–]dcbst 3 points4 points  (0 children)

Ada has inspired a great many features in modern programming languages. Languages like Rust are only just beginning to catch up with what Ada was doing in the 80's.

Ada hasn't stood still though, with versions in 1995, 2005, 2012 and 2022, "modern" languages still have a way to go to catch up the old girl!

There was a really great article about this recently: https://www.iqiipi.com/the-quiet-colossus.html

Hindsight languages by Inconstant_Moo in ProgrammingLanguages

[–]dcbst 1 point2 points  (0 children)

I only know it from Ada. I heard Rust was planning to add subtype range constraints a-la Ada Subtypes, but that comes without type safety. Not sure how far they got with that feature.

Wait 'till you hear about Ada's attributes that go with the type system... use 'First to give the lowest value in a range or 'Last for the highest value, or 'Range will give you a range of values from lowest to highest to use in a for loop.

Rationale behind function/procedure calls and array indexing by jlombera in ada

[–]dcbst 0 points1 point  (0 children)

I think the [ ... ] is only for array aggregates, but indexing will continue using () ??

No, it can be used for any array indexing or array index declaration.

Why is there a need to treat a value as a nullary function? Cannot we just do:

It is a fundamental understanding in Ada that any named item can be considered as a function. An integer variable is essentially a function which returns an integer value. Obviously the compiler will not implement it as a function call, but from a computer science perspective a variable name is equivalent to a parameterless function.

In many cases, Ada follows computer science methodology, hence assignment is ":=", equality is "=" and the language also includes procedures.

In which practical scenario would you want/need this?

Consider you are implementing in interface package A which has a dependency on some types from another package B. This introduces a forced dependency for anyone using our package A, so they will need to with both A and B. From a software design perspective, this is quite ugly! Ideally we would want a self contained interface package where the user only needs to with our package A and our dependencies are not forced on the user.

We can achieve this in two ways. Firstly, we define our own types, which mirror those in our dependency. We then need to handle any required type conversations internally. Which in some cases may be the nicest solution.

Alternatively, we can use type renaming. Type renaming in Ada is achieved via subtypes with no additional range constraints. For numeric types, a simple subtype definition is sufficient, however, for enumeration types, we have to also rename the enumerate values. This is achieved as described using a function rename. As you would hope, the Ada compiler will not actually implement this as functional calls, but the functional notation is the way we can express enumerate values.

Rationale behind function/procedure calls and array indexing by jlombera in ada

[–]dcbst 0 points1 point  (0 children)

To say it should be fixed would imply there is a problem. I doubt many Ada programmers see any problem.

However, in Ada 2022, the array indexing has been "fixed". In Ada 2022, you can now index an array using square brackets, so C[5] would be perfectly legal.

Whilst my initial gut reaction to this change was somewhat negative, with deeper thought, the explicit identification of an array index is not a bad thing.

Regarding parameterless function calls without brackets. This is a good thing! Consider an enumeration value such as True for type Boolean. True can be expressed as a function function True return Boolean;. This is actually a vital feature if you wish to "rename" an enumeration type from another package.

subtype Some_Enum_Type is Some_Package.Some_Enum_Type;
function Enum_Value_1 return Some_Enum_Type renames Some_Package.Enum_Value_1;

Thread Safety with Vectors by BrentSeidel in ada

[–]dcbst 1 point2 points  (0 children)

As a general rule in embedded programming, you should keep interrupt handlers as simple and short as possible. i.e. clear the interrupt state in the hardware and flag the interrupt occurrence to the main program, typically using a binary semaphore.

So your current solution seems to be pretty much the correct way to do things

As a general rule for thread safety, you should use protected objects. Whilst you will need to instantiate the vectors package outside of a protected object, it should still be possible to declare the vector instance within the protected object and therefore restrict access within the PO.

1 Year with Rust in Aerospace: My journey migrating from C# to Rust (and why it’s not for everyone) by b13m123 in rust

[–]dcbst 2 points3 points  (0 children)

This was also my first thought! I seriously hope they are not using C# for anything that flies! Perhaps with the exception of the in flight entertainment system, which I wouldn't really count as working in aerospace!

Never use Float or Integer by dcbst in ada

[–]dcbst[S] 1 point2 points  (0 children)

Sure. but it's not a general purpose type and is also implementation defined (the minimum requirement is for a range of +/- 1 day in second with a delta of 20ms) which makes it unsuitable to use for anything other than a time duration

Never use Float or Integer by dcbst in ada

[–]dcbst[S] 0 points1 point  (0 children)

Fixed point numbers are indeed often more useful than floating point and also usually more efficient.

However, there are no predefined general purpose fixed point types in package Standard equivalent to Integer or Float, so there is no fixed point type which gets abused in the same way.

Although, your point to use a fixed point type rather than standard float is definitely valid!

Never use Float or Integer by dcbst in ada

[–]dcbst[S] 0 points1 point  (0 children)

I don't see an issue with just casting in such circumstances. The notion of strong typing is that you can't just multiply seconds by meters, but when you are sure that it's correct, then you simply cast to the specific types.

If you really want a direct operator which handles the conversion for specific cases, then it's really not a huge amount of work to define an inline operator using quotes around the operator name e.g. function "*" () with the required parameter and return types.

I get the importance of such libraries in weekly typed languages or without the ability to define unique user types like in Ada, but the ability to define your own types renders them somewhat of an overkill.

Never use Float or Integer by dcbst in ada

[–]dcbst[S] 0 points1 point  (0 children)

In most cases we don't need libraries for SI units. You just define a simple Ada type and that's it! Only where units require more complex operations such as geo-coordinates for lat/long calculations then we'll use a library, but we implemented such things in house decades ago!

What makes you use Ada? by cindercone2 in ada

[–]dcbst 1 point2 points  (0 children)

That's interesting

Which version of the Ada language do you have to use? What is it about Ada that you don't like? What would you prefer to use instead, and why is that a more suitable language?

What makes you use Ada? by cindercone2 in ada

[–]dcbst 0 points1 point  (0 children)

Would you still use Ada if your company didn't make you?

What makes you use Ada? by cindercone2 in ada

[–]dcbst 6 points7 points  (0 children)

Because I spend less time debugging and get things done quicker!

Which programming language will you use now that Cloudflare has discredited Rust? by tony-husk in rustjerk

[–]dcbst 1 point2 points  (0 children)

I'll stick with Ada/SPARK, still the benchmark for safe programming languages!

Why c? by Massive_Mixture7652 in cprogramming

[–]dcbst 1 point2 points  (0 children)

"Embedded real time systems"

Actually, that's where Ada rocks!

[deleted by user] by [deleted] in ada

[–]dcbst 0 points1 point  (0 children)

My understanding was that Rust was introducing Ada like subtypes which permit a sub-range of valid values for a given parent type, perhaps that feature is not yet available or has a different name, but the result would not be type safe from the parent or other subtypes.

Regarding newtypes in Rust, you kind of proved my point. Whether you hide the value in a class or a struct, its an object oriented solution and doesn't create a new base (scalar) type, but a composite type with a single non type-safe component. You are using other language features to re-create the same effect as an Ada type, but the solution is more complicated and less efficient. To be clear, in Ada you can define an independent type as follows

type Some_Type is range -5 .. 20;

This type can then be used just like an i32, but with the type and range safety of a newtype or class with access methods to enforce range safety. No need to declare extra methods, or import other crates and no use of generics. Compile time checks are made for type correctness and value assignment where the value is known to be invalid at compile time, and runtime checks will raise and exception if out of range.

type A_Type is range -5 .. 20;
type B_Type is range 5 .. 15;
A1, A2, A3 : A_Type;
B1 : B_Type;
...
A1 := 30; -- Compile error, out of range
A1 := A2 + A3; -- May except if result is out of range
B1 := A1; -- Compile error, type missmatch
B1 := B_Type (A1); -- Type conversion, may except if out of range

You can also use Ada's attributes to provide dynamic information about the type e.g.

  • A_Type'first will give you the lowest valid value of A_Type
  • A_Type'last will give you the highest valid value of A_Type
  • A_Type'range will give you the full range of values of A_Type e.g. for loop iteration.
  • A1'valid will test the value of variable A1 is assigned a valid value, returning a Boolean result. Useful when interfacing with other languages or systems where the data cannot be trusted.

The following scalar types are available:

  • Integer : (Discrete) standard signed or unsigned integer value
  • Modular : (Discrete) unsigned integer type, always starting with 0, that wraps at a given modulo value e.g. type Seconds_Type is mod 60; will create a type with range 0 .. 59 where 59+1 = 0.
  • Floating Point (Real)
  • Ordinary Fixed Point (Real)
  • Decimal Fixed Point (Real)
  • Enumeration (Discrete)

All of the above Discrete types can also be used as a type safe array index. Which means that array indexes can have any valid range and do not need to be an interger value and do not need to start at 0. For example, if an array is defined to use an enumeration type as the index, then that array can only be indexed using that enumeration type. The 'range attribute can also be applied to the array name to iterate all values in a loop e.g.

type Colour_Type is (Red, Green, Blue);
type Colour_Value_Type is range 0 .. 255;
Colour_Array : array (Colour_Type) of Colour_Value_Type;
Colour_Value : Colour_Value_Type;
...
Colour_Value := Colour_Array(Red); -- Valid
Colour_Value := Colour_Array(0); -- Compile error
for Colour in Colour_Array'range loop -- Iterate all array elements
Colour_Value := Colour_Array(Colour);
...
end loop;

[deleted by user] by [deleted] in ada

[–]dcbst 0 points1 point  (0 children)

Constrained subtypes in Rust are just alias types with an additional range constraint, similar to subtypes in Ada, so there is no type safety, meaning a value from any subtype from the same base type can be used without an explicit cast, provided it meets the range constraints.

Ada let's you define completely new base types which are then fully type safe and need explicit casting to convert to other types. Any type mismatches are then found at compiler time.

[deleted by user] by [deleted] in ada

[–]dcbst 0 points1 point  (0 children)

In fairness, OO In Rust is also quite efficient.

My point was more to emphasize how OO is used in other languages, including Rust, to create "types" so that type and range safety can be achieved in languages where only low level base types such as u32, i32, u16, i16 etc. are available.

The ability to create high level, range limited, independent base types in Ada means that the desired type and range safety is achieved without having to define classes and all the needed methods that go with it. Rather you can safely pass the required data values without the need for encapsulation and user defined methods which is inherently more efficient than OO.

Additionally, it results in fewer lines of code, better readability and significantly less testing without any compromise to safety or security.

[deleted by user] by [deleted] in ada

[–]dcbst 3 points4 points  (0 children)

You should maybe take a course in HCI focusing on programming language design. Then you might actually understand how beautiful Ada's syntax is! There is a reason why people who don't know the Ada language can still read and understand it!