Making a game in Ada with Raylib

I think it would be interesting for you to interview him.

As for GDB, use the catch command to catch all exceptions and b command to set a breakpoint, i.e. hello.adb:10 or mangled name to break at the start.

@Irvise It would be interesting for you to find others who have tried ada too, like getintogamedev (yt).

Shame that tomekw stopped doing them.

I finally finished watching Ep 4. I am glad it went much smoother for Tsoding, which made the video more enjoyable to watch. He even stated at one point that he really enjoyed working on the project. On to Ep 5…

In his tea break he says he isn’t convinced about doing anything serious in Ada because it feels “enterprisey” and “bureaucratic.”

People at the ARG should watch this bit specifically up until 2:34:55 and from 2:38:45 to 2:39:35.

This is VERY important.

Yeah, lack of sufficient documented examples is definitely a sore spot. However, I think it is more of an opportunity for the community to help address rather than the ARG.

You missed the point completely. The bit where he says “they’re killing the language,” is the bit that needs driving home.

In the segments I’ve seen I haven’t seen him find ada-lang.io at all in search results.

I’ve streamlined the process as much as possible for writing docs for ada-lang.io and a lot of people have done so - I’m going to forget people if I try to a full list, but at least Max, Fer, Simon, etc.

I was thinking of putting up demo programs on Alire and then having a “example program walkthrough” section on ada-lang.io. This would include my “Raytracer in a Weekend” example and a “How to send an ICMPv4 ping from scratch (writing your own binding to C) on Windows/Mac/Linux”.

2 Likes

He doesn’t scroll down too far in search results and the things he searches for don’t show this site up at the top.

I learned how to use GDB from its man page; so, directly in the terminal. :grin: As in, you’re not alone.

A breakpoint in Ada is not really that different from one in C imho :slight_smile:

Maybe things have improved since I last used gdb to debug Ada, but there was a while where the support for Ada wasn’t all that great compared to C/C++, roughly 6 years ago, as I recall, because that’s when I was learning Ada, and learned that certain things I was accustomed to doing in C/C++ didn’t work with Ada – not in the same way, anyway. Unfortunately, after 6 years the only thing I don’t remember what the issues were, and to be honest they are probably one reason I’ve avoided using gdb with Ada.

The other reason woudd be that Ada is such a great language I haven’t needed gdb. Then again, that may say more about how little I use Ada, and the tasks I use it for.

Here goes another summary of the videos with respect to Ada. This time, it includes videos up until Episode 13/20, which was streamed yesterday:

The Good Parts

  • He was kinda happy with generics when he actually had to implement a generic Queue.
    • Though he is still not happy about using them.
  • He was extremely pleased with the use of Enums in/as array indexes. He said that it is incredibly sad how modern programming has forgotten about this behaviour and he is very pleased with how simple they are to use and how close they are to look-up tables.
  • He pointed out that working with Ada has been an “extremely educational experience”.
    • Maybe this was said with a bit of bitterness, as in negative experience too.
  • He really liked that there are runtime checks for arrays.
  • He really likes Enums in general and that arrays are their own type.
  • During refactoring in Episode 12/20, he pointed out that some solutions in Ada are very elegant. He seemed proud of how “obvious”/“clean” the code looked in Ada.
  • When he implemented his Queue implementation he said “I implemented it first try, which I don’t like as I don’t know if I made any errors.”
    • He was pleased with how “easy” and direct everything went. But it seemed that he was honestly disappointed as he wasn’t sure that he had done everything correctly, but it all seemed to work so he just went ahead.
    • He also had a few bugs, so it wasn’t a clean “first try”, but it mostly “just worked”, which I believe he did like it a lot.

The bad parts

  • He struggled a bit with Files and IO in Ada. He did not understand and did not care to understand about Direct IO, File_IO, etc.
  • He struggled quite a bit on episode 11 with parsing and printing Floats in Ada. On Episode 13 he struggled A LOT and he became very bitter about the experience. He only wanted Floats to be printed like in any other language, not with scientific notation. He was very annoyed with regards to how numbers are transformed into strings in Ada.
    • By the end of episode 13 (the latest at the time of writing this post) he was VERY underwhelmed with Ada and he felt Ada just wasted his time.
    • He pointed that Floats are very anal in Ada.
  • Strings having their size fixed bit his ass a couple of times with regards to run time checks and code organisation/type use.
    • I think he does not know that strings can have their size undetermined up until they are declared…
    • But he was not mad about this: “Ada is anal, but it makes sense”.
  • He feels generics are unwieldy and very bureaucratic. He hates the idea of having to create a new package just to use generics.
    • But he liked them when he implemented his own Queue.
    • He also pointed out that it is “interesting” how generics are basically generating a specific package definition for the type you give it during compile time.
  • He did not seem to like that Ada does not allow for anonymous types in arrays, as, in his opinion, declaring a type just for a simple index is “Too many layers of bullshit”.
  • He had issues with exceptions and printing a message when they happen.
    • Once again he complained that there were no clear and simple examples on how to do this, just documentation and lengthy explanations.
  • He dislikes the cryptic nature of attributes. He would have preferred if they were just function that one can call and that learning/finding information about them were obvious and not “hidden away”.
  • He implemented his own Queue as he did not find one that he liked in the standard library.
    • In the end, performance wise, it was similar to the use of Vectors from the standard library, as the performance issue was in the algorithm.
    • I would be surprised if Ada did not have a Queue implementation that he would have kind liked?

General comments

  • He is now spending a bit less time dealing with Ada and spending more time with the game, this can be seen on his work of the pallet editor, map/game design and pathfinding/AI.
  • He said “Ada is not going to be my new goto language”
  • He said he has “mixed feelings about the language” on Episode 12/20.
    • I am pretty sure he really likes some features (types, Enums, checks, arrays), but he really dislikes the documentation, lack of examples, the bureaucracy of the language and the cryptic nature of type attributes.
5 Likes

He says he doesn’t do much on twitter, but might be worth asking him if he would be willing to be interviewed by you about it all?

Re: the generics stuff, Shark8 submitted a proposal to automatically instantiate them.

1 Like

You’re making a true new-user experience analysis with this subject :slight_smile: I hope this can be used for improving some aspects in the language ecosystem and community.

I think the big hurdle is there are still ARG members that are resilient against making ease of use changes. The default response is that they aren’t interested in making ease of writing better and that Ada is about ease of reading, but I don’t think a lot of them understand that the two can be related to each other.

Take the standard way to do iterators. It is really really annoying to properly design an iterator for your type using the Iterator_Interfaces package. It takes a lot of scaffolding, it requires the use of a cursor (there are ways to design iterators without any cursors involved, they just seem to want to reuse the cursor type I guess??). And the big detriment to iterators is a reader can really get lost in the sea of code to make one and not fully understand how it works easily (found this out in a few code reviews).

I like the additional new iterator syntax in Ada 2022, but I don’t think there are gonna be a lot of good example for new programmers and I am not sure if GNAT implements it yet (I didn’t get a warning to use the gnat2022 switch when I tried to use it, it just failed to compile, but I could have done something wrong).

EDIT: And never ever use the word anonymous with some of the suggestions to the ARG. Like I think it wold be great if child packages of generic packages without generic formal parameters would be nicer to use if you could just “dot” operator them from the main package you instantiate (as an option, you could stilll use “new” to get separate instances). Someone suggested that in the past, but it was considered anonymous and 2 folks auto balked on the idea. And I get that it is technically anonymous in Ada terminology, but in reality it is being used in reference to a named/instantiated parent package, so it isn’t quite as bad as a real anonymous package. It’s basically just compiler syntax sugar to not have to re-new every child package you have.

If Ada allowed it, I would break my code up more into child packages when making generics (which I feel is easier for reading) but for now I feel burdened to stuff as much as I can into the parent package just to avoid the eye bloat and the name bloat (making up new names for every child package instantiation)

1 Like

I’ve been on sdlada again for the last few days and one of the things I wanted to go through and remove was the chars_ptr parameters type to stop any memory allocations. But even with char_array, you have to copy. One of the things Ada could’ve done was to map the Ada String onto the C array so conversions weren’t as expensive.

   procedure Get (Buffer : in out String) is
      function SDL_Get_Error_Msg (C_Str : in C.char_array; Max_Length : in C.int) return C.Strings.chars_ptr with
        Import        => True,
        Convention    => C,
        External_Name => "SDL_GetErrorMsg";

      Buffer_Ptr : constant C.Strings.chars_ptr := SDL_Get_Error_Msg (C.To_C (Buffer), Buffer'Length);
   begin
      Buffer := C.Strings.Value (Buffer_Ptr);  -- 2 Copies!
   end Get;

I don’t think the spec prevents compilers from using whatever representation they want for String, but you still need a couple bytes allocated somewhere to store the length.

1 Like

I think also the first index at least, incase the string’s first index isn’t 1?

Tsoding’s Ada repositories. Besides Game of Life, there is something with AWS. It includes links to the streams. Not yet the new game with Raylib.

Yeah he mentioned he wanted to keep it private for now. he wasn’t interested in people sending him comments on it just yet.

Ada number formatting and printing is painful compared to other languages. There was an RFC about interpolated strings, but I’m not sure what happened to it. There’s probably an embedded efficiency reason for that leading space in front of positive integers, but Ada is the only of more than a dozen languages I’ve used which adds it.

Indefinite types and strings especially are one of the sharp edges in Ada, until you learn a bunch of tricks to lessen the hurt.

Coming from any other language I know, they would be super confusing. Once you get to “Oh, I instantiate it and then use it like normal!” they’re easier, but it’s harder than expected to reach this point.

I only discovered by accident that you can instantiate a generic package in a separate .ads file.

e.g.

package Trendy_Terminal.Lines.Line_Vectors is new Ada.Containers.Vectors(
   Index_Type   => Positive,
   Element_Type => Trendy_Terminal.Lines.Line,
   ="          => Trendy_Terminal.Lines."="
);

With generics, I also only recently realized that you can use a subtype to avoid Long.Train.Of.Package.And.Type:

package Byte_Code_Arrays is new Adalox.Array_Lists (Byte);

-- Shorted some names to be amiable and more specific.
subtype Byte_Code_Array is Byte_Code_Arrays.Array_List;

I wrap all the entry functions of my executables with a exception catch to print any escaping exceptions with the GNAT extensions.

Very true, reading Barnes’ book gets you about 75% of the way there, the rest for me was a lot of stumbling around finding things.

They don’t exist in other languages that I’m aware of, and were never discussed directly in any literature that I came across. There’s a list in Barnes’ book of them and that’s what I used. I had to wrap my version of “Programming in Ada 2012” with contact paper because it’s entirely coming apart from use. The Ada Language Server provides help text when hovering over them and also provides completion for them in Visual Studio Code (which is awesome @Max).

I know there’s a synchronized one. I used Barnes again here to figure out how to use it though, but I never had a multi-threading issue that I can recall writing Septum:

package String_Queue_Interface is new Ada.Containers.Synchronized_Queue_Interfaces
            (Element_Type => Ada.Strings.Unbounded.Unbounded_String);
package String_Unbounded_Queue is new Ada.Containers.Unbounded_Synchronized_Queues
            (Queue_Interfaces => String_Queue_Interface);
3 Likes