Writing C# and Loving It

3D rednering in XAML. Why not?

I’m writing some C# for the first time in a while. And I love it. It’s code I wrote ten years ago, and it seems like yesterday. Visual Studio Code is a great place to work, but Visual Studio 2022 just blows it away for sheer usability. Nothing to load or add - everything you need under your fingertips.

I love writing Python - it’s fun to just write a program and see what it does. JavaScript is amazing in the way that you can use it to create mostly working solutions really, really quickly. And C++ and C are hilarious if you want to tickle hardware directly and don’t mind things suddenly stopping for no reason.

But with C# you feel like you’re using a really well crafted tool to create your code. All of your silly mistakes are caught before it gets to run. The debugging experience in Visual Studio is sublime. And I love building UIs with XAML.

I’m going to have to get back into the C# habit.

The affair of the C# bang bang - !! - operator

A programming language is like any other language. It must evolve over time to reflect the ways that it is used. One of the things I love about C# is how it has grown over the years. One of the latest changes is the addition of a !! operator (otherwise known as the “bang bang” operator). This is causing a bit of debate, which is great because changes to a programming language should always be made on the basis of a proper discussion. But you might be wondering what all the debate is about. So here’s a quick explanation of what is going on.

C# has always had methods. A method is a thing you can ask an object to do. For example, you might have an object which you can ask to serve a drink:

barkeeper.serveBeer();
barkeeper.serveCoffee();

Then you might decide that rather than have a lot of different methods for different kinds of drink it would be easier to make a method that accepts an argument that tells it the kind of drink that is required:

barkeeper.serveDrink("Beer");
barkeeper.serveDrink("Coffee");

The serveDrink method can look at the value of the argument and decide what to do:

void serveDrink(string drinkName)
{
    // test the name and make an appropriate drink
}

So far so sensible, although we have made things slightly easier in one respect (we can use serveDrink method to serve any drink rather than having to make lots of methods) by making things slightly more difficult in another (the serveDrink method has to decide what drink is to be made and what to do if a matching name is not found). For example, what should happen when the following code runs?:

barkeeper.serveDrink("BEER");

The above code is asking for a beer, but the name is all capital letters. Does the method deliver a "Beer", or does it fail with an error. If it fails with an error, how does the user of the program know that an error has occurred? At this point we have to invent a convention for our application. We might say that the serveDrink method will throw an exception if it is given a drink type it doesn't recognise. That's fine as long as the behaviour is documented so that users of the method now how to use it.

But what about bang bang? I hear you ask. The operator is intended to make life easier for programmers by automating the handing of null references. Consider what would happen if someone did this:

barkeeper.serveDrink(null);

This code will ask for a drink but provide a null reference as the drink description. A null reference is not the same as an empty string, it is a reference that points to nothing. This is like asking the barkeeper for a drink and then falling over on the floor before you tell them what you want. An attempt by the serveDrink method to use this null reference will result in the method failing in some way.

Naughty hackers love this kind of situation. They might discover that asking for a null drink causes the serveDrink function to crash just after it has opened a bar tab, so that they can then continue to order drinks for free. They might find it serves out the most expensive drink in the bar.

As the person who is writing the serveDrink method you don't want anything like this to happen. So in the method you add a test to make sure that the argument is not a null value:

void serveDrink(string drinkName)
{
    if (drinkName is null) {
        throw new ArgumentNullException(nameof(drinkName));
    }
    // test the name and make an appropriate drink
}

The first thing this serveDrink method does is check to see if the drinkName is null. If it is null an exception is thrown which exits the method instantly. This exception may or may not be handled by the caller, that is up to them. However, we have made sure that the serveDrink method won't do anything stupid if given a null reference. (of course we now have to worry about the issues that might be caused by this method throwing an exception thougth - welcome to the world of error handling).

What the bang bang operator does is make the above test for us automatically.

void serveDrink(string drinkName!!)
{
    // test the name and make an appropriate drink
}

In this verson of the code an exception is thrown if drinkName is null. I don't have to remember to add the call. This might make my programs slightly safer. But it also means that readers of the code need to understand what !! means in this context. They might look at it and think that the drink is very important, or hot, or something else. They might not know what it does and add their own tests for null which don't do what they expect. Hence the debate.

My opinion? I split language features into two categories. Cake and icing. This is definitely icing. I'd never use it personally, as I like my error handling code to be very visible to someone reading my programs. Plus I don't like situations where readers need to know "special stuff" to make sense of what they see. However, it's not a thing I'd stress about too much either way. I just love the way that C# is still striving to move forwards.

You can find out more about this proposal and the debate here.

How to be a programmer

At the end of the C# Yellow Book I include a few links to useful resources for readers. One of them is to “How to Be a Programmer”, an article I came across many years ago.

I got an email from a reader who’d made it all the way to the end of the book and found that the link doesn’t work any more. I did some digging and I found a link to a free version hosted on GitHub here. You can also buy a proper printed copy, or get it on Kindle by clicking the image above.

It is a really good read. Everyone who wants to be a programmer (or just make things for people) should read it. And then go back and read it again every few years.

Become a better programmer: Watch this video

This is a great video. I think every programmer should watch it. It was given at “C++ on Sea”, a splendid conference that I’d love to go to one day. But you don’t have to know any C++ to learn from it. The video describes the way that emotions end up in program code. And how to make sure that the emotions that you put in what you write are positive ones.

If I was still teaching I would make sure that all my first year students watched this. And I’d also change the marking schemes for software projects to include some consideration of it specifically. Not because I think you can mandate this kind of behaviour, but because I would want my students to find out first hand the benefits of doing it.

Strings and C++ Warnings

warning.png

When I build code I try to work in a “zero warnings” mode. That is, when I build the code I don’t see any mutterings about stuff the compiler thinks might think is stupid. However, sometimes I get warnings that I don’t think I deserve. For example, I tend to do things like this:

char * name;

name = “Rob”;

I know what I’m doing here. I’m creating a character pointer and then making it refer to a string literal. It’s how big chunks of the control code for my “Connected Little Boxes” work. In the land of C it is OK to do this (- at least I think it is). However, C++ is now all grown up, has a String type and thinks it’s OK to moan at me for doing this.

I’ve got round the problem by telling the compiler to ignore this particular warning:

#pragma GCC diagnostic ignored "-Wwrite-strings"

This is an instruction to tell the compiler disable that specific warning. The -Wwrite-strings bit is how I tell the compiler the warning that I want it to ignore. I did a bit of soul searching before I added this statement. Most of the time I really want to know if I might be doing something stupid. But I reckon this is a case of “greater good” in that it makes other mistakes more likely to stand out.

Compile early and compile often

yet more leaves.png

I’ve been writing a big and complicated program for a while. I’m not sure if it is supposed to be big and complicated, it just seems to be turning out that way. And one of the things I’ve remembered from my days of doing this kind of thing is “compile early and compile often”. If you wait a while before hitting the compile button you can sometimes get so many errors that it can take you a while to figure out. Modern editors are quite good at spotting coding mistakes as you write, but there is nothing like letting the compiler take a proper look at your code.

I’ve been hitting compile every time I’ve written a few lines. That way, if I get an error I don’t have to look through much text. I do this even though I’ve no intention of running the program at that stage. It’s just that when I’ve done a bit that I think should compile it is worth getting the proper opinion on the matter.

When I was teaching programming we used to get people come in with 500 line programs that didn’t compile and they weren’t sure why. They’d written all the code down and then hit compile and were surprised by the number of errors they got. I used to tell them that a good way to start would be with an empty program that compiles and then add the statements a small amount at a time, compiling at each stage.

Maketober Day 21: Null Discoveries

pixels.png

It turns out that nothing is important. Programs need a way of explicitly denoting that something is empty of meaningful content. C++ uses the value NULL. [I did have this awesome idea for a nerdy T shirt with the slogan “HULL != NULL” which I thought would be a great way of bigging up the local area, but I digress].

Anyhoo, my lovely sprite library uses a linked list of sprites that can be added to a frame for display. Each sprite contains a link to the next one in the list. The “next sprite” link last Sprite in the list contains the value NULL to indicate that there are no more sprites. I like this because there are no constraints on the number of Sprites I an put in a Frame. I can just keep adding them if I want more. The frame contains a variable that refers to the first sprite in the list and when I want to work on all the sprites I just start at the first one and then get each one in turn.

class Sprite
{
public:
    Frame* frame;
    void update();
    Sprite* nextSprite;
};

This is an extract from the Sprite class header. You can see the nextSprite reference. Note that C++ uses the * character to denote that a variable is a reference.

class Frame
{
public:
    Sprite * sprites;
};

This is an extract from the Frame class. Now, when I want to update all the sprites I can use this:

Sprite* currentSprite = sprites;

while (currentSprite != NULL) {
    currentSprite->update();
    currentSprite = currentSprite->nextSprite;
}

The loop starts at the beginning of the list and works through them, updating each one. Good stuff. I ran this code in my ESP8266 device and it worked a treat. Much happiness. Then I ran it in my ESP32 device and it exploded. Much unhappiness. These are the worst kinds of bugs. The ones that are just not supposed to happen.

After a bit of head scratching I worked out what was going wrong. Turns out I’d done something stupid. When I make a new Sprite I have to make sure that the nextSprite reference is set to NULL. Otherwise my update function will head off trying to update sprites that don’t exist. Which will end badly. I’d not done this. In C++ if you create something you just get the space. It is not set to any sensible value.

Friendly languages like C# will automatically set sensible initial values to variables. It just so happened that in the ESP8266 version the nextSprite references had been set to NULL even though I’d not done it. So the program worked. However, in the ESP32 version they references just pointed at random pieces of memory which turned out the a recipe for “kaboom” when the program tried to follow them.

Moral of story: make sure that when you make a new something you set it to a sensible value. Sometimes you can get away with this, but not always.

Adventures in function names: saveItem or storeItem?

lego functions.png

I’m writing Begin to Code with JavaScript at the moment and I was struck with how the choice of function names can be confusing. I’ve made the point that a good way to come up with a function name is to make them out of a verb and a noun. So storeItem sounds like a good name for a function. Store the item. What could be simpler?

Unfortunately this has the potential to be confusing. It’s because the word store can be a verb (do the storing) or a noun (a store that contains things). So storeItem might mean an item from the store. My strong advice is to try and pick unambiguous verbs, which is why I much prefer saveItem.

Perhaps I’m overthinking this (it has been known) but I’ve been surprised how many times I’ve picked confusing names for things based on distinctions like these. One of the great things about modern development is the ease with which you can rename identifiers, so if you do decide that the name you first came up with is confusing you can change it.

Making Shadows in CSS

crazy adventurefunland.png

You can get some quite nice effects in CSS to make 3D text. Above you can see a heading for one of the exercises in the Begin to Code with JavaScript book (get the draft chapters here). It was simple to set up as a style:

.menuHeading {
font-size: 4em;
font-family: Impact, Haettenschweiler, 'Arial Narrow Bold', sans-serif;
color: red;
text-shadow: 3px 3px 0 blue, 10px 10px 10px darkblue;
}

A shadow is specified by three values and a colour. The first two values give the X and Y offset of the shadow and the third controls how diffuse the shadow is. You can add multiple shadows to a single style, which is how I got the sharp blue shadow and then the blurred deep blue shadow behind that.

Quite fun.

Using Multiple Inheritance for Good

Multiple inheritance sounds like a good thing. After all, why would you not want to inherit a bunch of stuff? But some programmers don’t like it. They say it makes things confusing, they say that a class made from multiple parents will be neither one thing nor the other. And mostly I think they are right. However, when the alternative is something even more confusing, I can be persuaded to think of multiple inheritance as a good thing.

My problem was that I wanted to make a driver class to control a Furby toy over Bluetooth BLE from an ESP32. The ESP32 has a bunch of Bluetooth libraries and they work fine, but they expose their callbacks the form of class instances that contain overridden versions of the class callback methods. Ugh.

Wow. That sounded cool didn’t it. But did it make sense? Probably not. Here’s the thing in bullet points:

  • When a program connects to something over Bluetooth BLE it needs a way that the Bluetooth BLE library can tell it things. In other words, if the BLE library receives a message from the Furby it needs to be able to deliver this to the program.

  • One way to do this would be to pass the Bluetooth BLE library a reference to a function for the library to call when the message arrives. I like this method, lots of other things use it. However, the BLE library doesn’t. For some reason it likes to be given a C++ class instance.

  • A class is an object that can contain methods (lumps of program code a name). If I pass the Bluetooth BLE driver a reference to the object the driver can then call the methods in it.

  • The Bluetooth BLE library provides templates in the form of abstract classes (classes with method names but no implementation) which I can override with my own methods in new message passing classes that I base on the abstract parents. I then pass references to instances of these message passing classes into the Bluetooth BLE driver so that it can call the methods in them and tell my program things. But this is a right pain, because if I want these methods to interact with the data in my program (which I do) I have to make these objects aware of their context. Which is a mess.

I hope that’s cleared that up. Anyhoo, rather than implement lots of message passing classes and then pass references around between them (ugh), or make everything static so that everything can see everything (double ugh) I simply make my Furby adapter class inherit from all the abstract BLE library message classes and then drop the overridden methods from these classes right into my driver class. Because the methods are now inside my driver they can use all elements inside the driver and it just works. So, a good use for multiple inheritance. Yay!

Unfortunately, the Bluetooth BLE driver writers have thrown in some function references too, which means that I need some static members in my driver class, but I’m in a happy place at the moment.

One of the things that occurred to me as I was writing the code was how much effort I would have had to put in to avoid using multiple inheritance. When you are programming it is important to remember that the final outcome should be a program that solves the problem. Worrying to much about the “right” way to do that can sometimes send you backwards if you are not careful.

Tkinter tip: putting buttons back to their original colours

Another of those “blog posts that you write so that in six months time, when you hit the same problem you can search for it and find the answer that you wrote for yourself…”

I’m building a little editor for Hull Pixelbot HullOS programs. The editor can deploy code via MQTT or serial terminal so my editor has buttons that let you select which connection you are using. I thought it would be neat to make the buttons change colour to indicate which connection type is in use. Making buttons go green is easy:

button["bg"] = "green"

You can regard a display element as a dictionary (everything in Python is a dictionary) and one of the keys lets you set the background colour.

However, getting a button back to its original colour is a bit more tricky. Word on the street was that the default button background colour is “light grey” but this didn’t work. Perhaps I spelt “grey” wrong. Anyhoo, the correct way to do this is to use the following:

button["bg"] = "SystemButtonFace"

The colour “SystemButtonFace (why am I thinking of boat names?) is the colour that you need.

Writing up code as you write it

I’ve found a good use for all that time I seem to be spending waiting for my programs to compile and deploy to my hardware. I’m writing up what I’m trying to do. This is what I wrote today:

  • fixed a bug whereby only the latest reading and not the average environmental values are sent in an MQTT reading.

  • changed the handling of timeout so that an incomplete reading is sent rather than just skipping a reading

  • bug in modification so that the air quality reading was not sent when only the environmental sensor was disabled. This is because the reading age was less than the reading timeout. So a reading taken at the start of the reading period would be "out of date" by the time that the reading had timed out. Fix this by increasing the reading age to 60 seconds. Also modified the reading timeout setting so this cannot be set more than 60, so that a user couldn't cause this by silly settings.

  • added a 1 second delay before powering down after a message has been sent so that we can send MQTT messages to the device when we know it is awake. Managed this delay to ensure that it is none blocking.

  • found a nasty bug in MQTT message decoding that broke the decoding of incoming messages. Put the MQTT message decode into the main thread rather than calling the JSON decoder on the callback which is running on a network interrupt because it broke the Serial.print output. Added better decoding of the message types (better as in working).

Not all Arduino C++ Compilers are the same

When I was writing the code for the Heltec Cube I came across something that has caused me problems before. When you switch from one Arduino device to another you sometimes change compilers.

The compiler is the program that takes your source code and converts it into the low level instructions that the hardware will follow when the program runs. Different processors have different compilers and, what with C++ being a language with a few grey areas, this can change what happens when your program compiles.

In the case of the Heltec Cube I got errors when using structures in function parameters. In C++ you make a structure like this:

struct InputSwitchSettings {
int controlInputPin;
boolean controlInputPinActiveLow;
};

This is the type that describes the input port that allows the user to switch the device into configuration mode. It sets the physical pin number and also whether that pin is active low. Once I’ve got my structure I can then create a variable of that type:

struct InputSwitchSettings configPin;

I might make a function that wants to use the value of configPn, which means the function must have a parameter which is a reference to the variable:

void showPinSettings (struct InputSwitchSettings * switchRef)
{
Serial.println(switchRef->controlInputPin);
Serial.println(switchRef->contrlInputPinActiveLow);
}

The function showPinSettings will print the settings of the given input switch. Note that in the declaration of the function I’ve told the compiler that InputSwitchSettings is a structure (that’s what the word struct does).

However, some compilers let you leave this struct out (because the compiler can work out this information for itself). The compiler for the ESP32 is relaxed like this. However, the Cube compiler insists on having struct there. It took me a while to work out why code that I’d been using for ages suddenly broke. I guess it serves me right for being lazy.

If you start having problems when you target a different device on the Arduino platform, remember that you are not in Kansas any more where compilers are concerned.

Debug Code by Writing Comments

Here’s a programming tip for you. If you have a bug and you’re not sure why (or even where) it is occurring, spend some time writing comments in the code as you work through what it is supposed to do.

This is a great way to “explain to yourself” what the program does and it might even be useful information in the future. You never know. You can also spend some quality time refactoring the code so that variable and function names properly reflect what they are used for.

I like this approach because you then don’t look back on the time spent debugging as wasted. When you find the mistake that you made you can at least reflect that fixing it made the code better.

Updated C# Yellow Book available for download

I got an email over the weekend from Drew about a glaring typo in my downloadable edition of the C# Yellow Book. I was about to respond that I’d fixed the error when I thought I’d better check first. It turned out that I hadn’t.

So I’ve spent this morning going through all the reports of issues with the book and fixing them. Most of them have been typing mistakes but I’ve also made a few changes to make some things easier to understand. I’ve completely reworked the section on thread safety to incorporate a more meaningful example.

Thanks to Liz, Dina, Lilli, Neil, Richard, William, Don, Bram, Mitch, Jaswinder, Javi, Peter, Justin, James, Mike, Ian, Papartis, and Drew who took the trouble to get in touch and help me make the book even better.

You can download it here.

Byte ordering is a thing....

I’m upgrading the Air Quality sensor software so that I can send configuration messages over LoRa to the sensor. The thing I’m most interested in is the ability to tell the sensor the rate at which it should send readings. It would be useful to have a message sent every five minutes or so for testing, and then dial back the rate once the sensor has been installed. I’m using a tiny packet format to do this. The packet is three bytes long:

01 58 02

The first byte is the command number (there is only one command at the moment). The other two bytes are the number of seconds the sensor should wait between sending each reading. The value I want to send won’t fit into a single byte (a byte can represent an unsigned integer up to the value 255 and I want to have intervals longer than 255 seconds) so I’m using two bytes. The first byte is the “low” byte of the value I’m sending and the second byte is the “high” byte. In the tiny sample above the low byte is HEX 58 and the high byte is 2. This gives an interval of 2 * 256 + whatever 58 hex is in decimal. This boils down to an interval value of 600 seconds, or 10 minutes.

I wrote the software, tested it, installed it in all four of the sensors we are building and then set them off. I then sent the above command to the sensors to set 10 minute updates and then relaxed in the knowledge of a job well done.

And all my sensors stopped transmitting completely. Wah.

Turns out that I am an idiot. I’d done everything right except the last bit, when I’d sent the following command:

01 02 58

I’d got the MSB and LSB bytes the wrong way round. Rather than having 2*256 I now have HEX 58 times 256. A big number. A six hour or so number. So all my sensors were now not going to transmit for six hours.

Sending the new command wasn’t a problem, but because of the way that we are using LoRa the sensors only look for new commands when they send a reading. So I had to wait for six hours before the command would get picked up and acted on. This is something to bear in mind about LoRa. The remote node is not always listening for a message, it only turns on after it has sent something. This is one way they manage to get such impressive battery life for LoRa connected devices.

I managed to solve the problem by turning the sensors off and on again. They always transmit a packet when they start up so I was able to update the timing with more sensible values without having to wait six hours.