Friday, 29 November 2024

Meeting C++ 2024

I went to Berlin again to speak at Meeting C++. The conference has been going for a while now, and has been in Berlin for 10 years. 

I first went in "before times", in 2019, because Jens invited me to keynote. I went back last year, partly for the talks but also because the conference has a friendly vibe and there is a great mix of beginners to experts, so everyone can learn something.

Titus Winters gave the opening keynote, "Fear in tech". He said he wanted us to normalise talking about feelings, and reminded us a good person is better than a good programmer. He talked about recognising and managing fear, as well as using tools to reduce fear. Tools can provide a "formal source of truth", cutting through the "It works on my machine" thing. Little things like clear instructions on how to build code and run tests make a big difference.   

He talked about "bogus productivity" and hype plus FOMO. He told us to cut through the buzzwords. Learning and understanding can be a cure for the hype cycles. Listen to his talk when it's online, it covers so much and suggests ways to do better.  


Titus' talk possibly started a background theme of "Imposter syndrome". This was mentioned by so many speakers! 

After the opening keynote, sessions ran on four tracks. One in the main room, two in smaller rooms and one online. The conference is hybrid, allowing people who can't afford the cost or time of travel to Berlin to join in. The staff, or Jens, read out any online questions at the end of the sessions, so everyone could be involved properly. 

I went to Design Patterns - The Most Common Misconceptions (2 of N) by Klaus Iglberger first. He talked about virtual functions and pros and cons of

  • The curiously recurring template pattern (CRTP)
  • std::variant
He reminded us about duck typing in C++ and concepts as alternative approaches. His impression of Darth Vader going "quack" was magnificent. You had to be there.


I went to Portable floating-point calculations by Guy Davidson next. Adding up is surprisingly interesting! Fused multiply add (FMA) got a mention on more than one occasion. My final note says "Basically, speed or precision". (With an implicit "not both.")

Next I went to Classes C++23 style by Sebastian Theophil. The main thing he reminded me was about ref qualifiers. If you had forgotten about them too, Andreas Fertig's blog explains. He gives an example returning data items. Note the & and && after the functions:

class Keeper {

  std::vector<int> data{2, 3, 4};

public:
  ~Keeper() { std::cout << "dtor\n"; }

  A For lvalues
  auto& items() & { return data; }

  B For rvalues, by value
  auto items() && { return data; }
};

This isn't a C++23 feature, but talking about classes meant a good talk with several bonus details. It is amazing how much can come from one simple title.

That evening there was a C++ quiz.  You had to be there. Code with emojis. Some memcpy and other horror. But much laughter too.

The next day started with a center keynote by Hana Dusíková called "My favorite data structures". She started simple, then said "Most of the C++ library should be const evaluable." She asked us which C++ containers are constexpr. (Clue: very few.) 


Hannah did tell us her favourite data structure in the end: a "hash array mapped trie" (HAMT). I know all the words, but putting them together gives something new, to me at least. 

I went to my husband, Steve Love's talk Testable By Design next. He started by saying he actually is an imposter! He used to do a lot of C++, but has settled on C# for a day job recently. He blogs here. His talk was about writing code for a thermostat. Another simple place to start that provided lots to talk about. He mentioned using my Learn C++ by Example book to get back up to speed with C++. I had a few copies with me, and Ivan Cukic bought one.


After lunch I went to C++ Concepts: What you should know and how to use them right by Nicolai Josuttis. He said "New feature, new bugs" near the start. He is very good at pulling out some weird behaviour, and always says "Good!" afterwards. His main example was trying to write an add function which would apply to a set or a vector. There were lots of useful points in his talk, including a reminder to use static_assert to test your concept does what you need. 

Next I went to Stories from a parallel universe by Jana Machutová. She talked about the standard library parallel algorithms. She started simple, using std::execution::par_unseq in a for_each loop. So, something like

std::for_each(std::execution::par_unseq, 
    std::begin(v), std::end(v), [](){ do(); }

for some container v and some function do. No explicit threads because clever thread management is already there for you. She then got more complicated, pointing out new algorithms, including reduce instead of accumulate, transform_reduce instead of inner_product, and partial_sum becoming either inclusive_scan or exclusive_scan. The main differences are obvious if you have a non-associative binary operator. I need to play with a few examples. She then gave a few examples for when to use  the different execution policies like par_unseq, or par. 

Herb Sutter gave a talk that evening, called "Peering forward - C++'s next decade". He covered loads, but it was late and I didn't take any notes. He did talk about C++26's erroneous behaviour though. 



We stayed up far too late after that, discussing interfaces in C++ versus C#. I was talking the next day, so maybe this wasn't the best choice! I gave An introduction to swarm intelligence algos, and had some demos embedded in PowerPoint, but they wouldn't play. I managed a few live demos at the end instead. Note to self: stop using PowerPoint. Swarm algorithms are part of machine learning. Each item in a swarm explores and tries to exploit better solutions. The whole swarm communicates and you get some kind of emergent intelligence or a solution to a problem. They aren't that hard to code and make for good practice. My first book, Genetic Algorithms and Machine Learning for Programmers, has a chapter devoted to them. 
 
I missed the very beginning of Contracts for C++ by Timur Doumler, because I wanted to drop my laptop in my room and just breathe for a moment after my talk. Timur pointed out the first contracts proposal was 20 years old. In my head, contracts has turned into a big tangle, however Timur made it seem less gnarly. If we do end up with something like a better assert, that will be great. 

There were "secret" lightning talks next. They don't show on the program, but people who had been before probably expected them. 

The closing keynote was Peter Sommerlad on "Collective Amnesia?" He talked about the things we have forgotten and some reasons why. He started with five main points. 

  1. Well known knowledge is not applied
  2. Proven practices are not well known
  3. Scientific evidence is ignored
  4. Timeless principles are forgotten
  5. Complicated stuff is favoured over simplicity
Peter said one of the reasons for forgetting is powerful men trying to make money, and he clarified he did mean men. He got a bit more general than just computing at that point :-). We also often fall for hype/new shiny. But other things have an effect too - like trying to keep university teaching materials up to date. Listen to his talk when it's online. 



We stayed in Berlin on the Sunday to explore. We went for a long walk, starting at the Tier Garden, in the West. A nice big space for a walk.


 

We started walking East back towards the hotel. We found the Computer game museum and played a variant of Pong. Yes, that's for up to 5 players. So, the computer controlled three bats. Yes, that's four controls each: left, right, clockwise rotate and anti-clockwise. Oh my!


We then stopped at the Rockcafe HALFORD back near the hotel. Someone mentioned it to us over lunch at the conference. Thank you, whoever you were. 



Tuesday, 29 October 2024

AI for the Rest of Us

 I spoke at AI for the Rest of Us last week. This new 2-day event happened in London, and wanted to help attendees understand what AI is about and how to use it, in plain language. Some talks also considered potential issues, including bias and ethics.  

The mornings had various keynotes, then the afternoon split into 3 tracks, some on Thursday and some on Friday:

  1. Back to Basics: AI Fundamentals
  2. AI in Action: Real World Stories and Lessons Learnt
  3. AI in the Workplace: Productivity Game Changers
  4. Business Strategy Meets AI: Embrace Change and Unlock Opportunity
  5. Developer Experience: How AI is Changing Software Engineering
  6. Responsible AI: Safety, Security, Guardrails and Governance

I was speaking at AI fundamentals, and tried to explain curve fitting, why it's sometimes called regression, and neural networks in under 30 minutes. A challenge, but people talked to me afterwards so I may have succeeded. 

If you don't know why we sometimes use the word regression here's a clue. Francis Galton wrote a paper called "Regression towards Mediocrity in Hereditary stature." Wikipedia has quite a good overview. He observed the heights of children and parents, and spotted they all tended towards a median value. Nothing that profound really, though there is a bias loitering in there. Anyway, the talks were recorded and my talk is now on YouTube

I have copious notes, but some highlights were Rachel Lee-Nabors reminding me of Russell and Novig's book, Artificial Intelligence: A Modern Approach. I read that when I started my PhD many years ago. I probably read an older edition but Rachel suggested the 4th edition. It covers a lot of ideas and is a great introduction if you want a good book. Rachel also mentioned Trask's Grokking Deep Learning book. Rachel's title was "AI cram session", explaining lots of details about LLMs and more besides.




Several talks tried to explain LLMs, going into various levels of detail. Ideas from embedding to attention and multilayer perceptrons were covered. These are fundamental parts of LLMs, so no surprise there, for me anyway. The talk is here.

Of course, there's more to AI than LLMs. I really enjoyed Lisa Becker's talk "Beyond LLM-Washing: When other ML models are simply better". 


She pointed out the potential huge cost of using LLMs and encouraged us to at least consider other methods, like classification or clustering, along with predictive models or anomaly detection. She pointed out using LLMs and GenAI tends to have prestige, but might not be practical. The talk is here.

I also enjoyed Lianna Potter's talk "Never Neutral: AI Development, Past, Present and Future in Anthropological Research". She describes herself as a digital anthropologist. 


 
She talked through Diana E. Forsythe's book, Studying those who Study Us. The bias that creeps in when people focus on the wrong things never stops! I've not come across this book before, but it's now on a long list of books to read. Her talk is here.

Ian Miell's talk about LLMs in the humanities was interesting. He set himself the challenge to get AI to write an essay for him that he had to write at university. He also talked through some AI history, including machines to play chess. The details of his personal project to generate an essay were relatively high level, but easy to follow. His talk is here.


I also went to Jeff Watkin's talk "Four Horsemen of the Information Apocalypse." He started by asking who invented
  • the light bulb
  • the printing press
  • the internet
These are often wrongly answered. This was a great lead in to talking about misinformation, mal-information, disinformation and non-information. He drew an analogy with a virus spreading and encouraged us to lower the r number, to stop the spread, or at least reduce it. His talk is here

I went to several other talks too, but the different afternoon tracks meant I missed many. I look forward to these turning up on the internet. The speakers' brief was to keep things understandable. That's hard if you don't know the audience, but I think the speakers managed. Some technical terms were used, but analogies or simple explanations were offered. 

I'm glad I went. I met new people and had lots of interesting conversations. Having speaker's drinks the night before meant I recognised a few people when I turned up on the first morning, which was lovely. 

You can access the recordings via the YouTube playlist. Again, they all aim to be understandable, even if you don't know anything about how AI works.

Tuesday, 24 September 2024

SoCraTesUK 2024

I attended the International Software Craft and Testing Unconference UK just outside Oxford last week for the first time. I have been aware of this for a while but hadn't had the chance to attend before. I had been to another conference which had a single "unconference" track, so I got the idea.

Before the main conference, we had a day of workshops. I ran a 90 minute session introducing C++. That's not much time to learn a language, but I think everyone managed to get something working. I walked though how to build a game of Rock, Paper, Scissors, avoiding any mention of pointers or iterators. You need to be able to handle input, output and generate random numbers, which I believe is a great way to try to learn any language. 

For the unconference, there's no fixed agenda or schedule beforehand. People chat in groups about potential ideas and pitch these in the morning, to see if anyone is interested. If someone wants to go ahead with the idea, they put the title up on a board in a slot for a specific time and place. 

What ended up happening is on their website. I didn't make all the sessions: I needed some headspace and went for a walk round the grounds or did a short gym session a couple of times. 

The first session I went to was about confidence. Harram proposed this. She hadn't been to this unconference before (nor had I), so she's braver than me. It seems an old manager told her she wasn't confident enough, so we unpacked what that might mean. I personally didn't feel it was useful or helpful feedback. It's all too easy to be confident but wrong. 

After that I went for a short wander and then attended the end of "Workplace conflict, what can ancient warrior arts of the mystic East teach us?" 


I've done some martial arts before, but wasn't familiar with the specific ones mentioned here. However, the idea of stepping to the side rather than pushing back cropped up and makes sense. I missed the beginning, so I only caught some of this. Thinking about what "stepping sideways" might mean in a discussion was useful. 

Next I went to "As freelancers, how do we decide what to spend our time on", run by Clare.  



I have been available for short consultancy this year, but have spent far too much time preparing content for things that got cancelled or getting distracted. To be fair, I have also had a book published and started another one, so I have managed to do some things. Saying "No" once in a while is a good idea. This made me think about how to make better choices next year. 

I then went to "What I wish I had known about retirement before I retired", which ended up being a bit focused on money and cashflows, simply because that's what people were asking. I shall take stock and see how I'm doing. Things seem to be getting harder for people. For example, I don't have a student loan, but many younger people do, and that makes planning more difficult. 

On Saturday I went to Seb's "BDD reboot". I have had a session about BDD accepted for OOP next year, and planned to talk about my experiences. Seb's session was a useful reminder of what BDD is really about - clue the middle D for "driven" is important. It's certainly not about slapping Given-When-Then in your tests. Many of the rooms were named after flowers, and this was, appropriately, in Rose. 



Next, I went to "Challenges when dealing with time-dependent & historical data". I had hoped someone would give me all the answers, but we just chatted through things we have had to deal with and what we tried. My examples involved reference data changing and how to maybe label versions so you get the same outputs for regression testing. Dealing with time dependent data is hard. 

There was a discussion over lunch based around "Unionizing in Tech".  Listening to the ins and outs of trying to be a union member in a large tech company was hard. I mentioned a book I read a while ago: Reorganise: 15 stories of workers fighting back in a digital age, which is about other ways people band together to support each other. 

I couldn't settle my head after that so I flitted between sessions then went for a walk. I then went to "I need 28 thoughtful / gratitude reflection style questions".  We sketched out questions that could be used in an app which checks in with you each day and shares your answers with others, maybe inspiring them too. Why 28?  So the questions could cycle around every four weeks. I'm not sure how useful we were, but things like "What have you learnt recently?" "What would you like to learn next?" etc... ended up on the list. 

The last session I went to that afternoon was Clare with "Recently diagnosed or undiagnosed autistic - ask me anything". Most people who attended were either diagnosed autistic or suspect they are. One or two were there because they have an autistic child. I suspect I might be autistic, and I wondered what difference the diagnosis had made to Clare. I nearly ended up in tears a few times, for reasons. The big thing I realised in this session was how many women were at the conference, especially compared to conferences I usually go to. 

In the evening, there were some Lightning talks, where people volunteer a short talk, for a maximum of five minutes, on the spot. All kinds of things were covered. Clare gave the last talk about how a hot air balloon ride is like an unconference. I didn't make notes, so I no longer remember who else said what. But that's OK. Lightning talks are a great way to allow people to do a little, which is less scary than a whole session.

Finally, Mervi gave an LED hula hoop performance. You had to be there.



Monday, 5 August 2024

Why I wrote Learn C++ by Example

I recently shared some details about my latest book "Learn C++ by Example".


You can buy my book directly here: http://mng.bz/AdAQ - or just go look at the table of contents. You can also buy it from Amazon: https://amzn.to/4dMJ0aG

There are a lot of C++ books, so why did I write another one? Well, many books delve into the details of a specific language version. As you may know, C++ remained relatively stable until C++11. This felt like a new language in many ways. Some things became easier, for example using a range based for loop meant you can show the contents of a container without needing to learn about iterators first:

#include <iostream>
#include <vector>

int main()
{
    std::vector numbers{1, 3, 5};
    for(auto number : numbers)
    {
        std::cout << number << '\n';
    }
}

Since C++11, there has been a new standard every three years. In fact, the code listing above is now old, because we can use std::println instead of std::cout and import modules rather than include headers. My book didn't cover all the newer features, because I wanted to give just enough to help people get back up to speed. 

My previous blog posts did show what I covered. The chapters have the following titles:

1 Hello again, C++!
2 Containers, iterators, and ranges
3 Input of strings and numbers
4 Time points, duration, and literals
5 Creating and using objects and arrays
6 Smart pointers and polymorphism
7 Associative containers and files
8 Unordered maps and coroutines
9 Parameter packs and std::visit

As I said, this doesn't cover everything. However, I think it gives just enough to help you get back up to speed if you used to know at least some C++, but haven't used the language for a while.

I have been using C++ since the 1990s, along with various other languages. I used to work in finance in London. Trying to get a position can be a challenge. Many organisations give you a thorough grilling, with a homework challenge, possibly a multiple choice "quiz"  and one or more face to face interviews. Aside from implementing linked lists on whiteboards, or spotting missing semicolons on paper printouts, you often get asked about dusty corners of the language, so many people practice and learn a huge number of details about C++. 

I did learn some Python and C# too, which meant I had to take time to revise if I wanted a contract using C++ again. Watching the language change and move would a bit overwhelming, but since I edit ACCU's Overload magazine, I was aware of some newer features I should probably catch up with. Before writing the book I found time to practice some modern C++, and started to form a list of things I knew and things I wanted to learn.

Meanwhile, I sometimes review manuscripts for Manning, and have been a technical proofer for some of their books. I noticed I hadn't seen a C++ book from them for a while. I have a copy of Anthony Williams' C++ Concurrency in Action and recently reviewed a couple of C books. I suggested the need for a short C++ book covering significant changes since C++11 and my proposal was accepted. 

People who have read my book have told me how useful it's been. If you used to know C++, and feel sad because you haven't managed to keep up, don't give up. Find one or two small things and learn those. You might never catch up with all the changes, and C++ will keep evolving. However, you can practice a little once in a while to stop yourself from going completely rusty.




Monday, 15 July 2024

C++ On Sea trip report

 

I went to C++ On Sea again this year, attending the main conference. I spoke about Swarm Optimisation algorithms. I wrote a brief blog post about these a while ago, if you want a quick overview. I also hosted the lightning talks.



On the first evening, we had six speakers and a last minute bonus from Jon Kalb:
  1. Jan Wilmans, A Magical chat about C++ with GPT3+
  2. Anders Schau Knatten, C++ Quiz
  3. Cassio Neri, My favourite UB - Part II Russell's Paradox in C++
  4. Sanket Singh, Unlocking the Power of Advanced C++ Compiler Flags: Boost Performance and Debugging Efficiency
  5. Amir Kirsh, delete [ ]
  6. Mark Williamson, Undoom - reviving a zombie with a time travel debugger
  7. Jon Kalb, Wisdom in Keywords
I was speaking directly beforehand, which was a challenge. People sign up and send me slides (unless they are doing a demo on their laptop), so I couldn't poll emails while I was talking. I had prepared a game of "Coding rockstars" beforehand - or at least had some pictures and ideas.  For example, a picture of Taylor Swift. See what I did there?

On Thursday, (almost) immediately before the speakers' dinner, we had another session of lightning talks, with more speakers this time:
  1. Andrew Drakeford, Variadic Reduction 
  2. Sandor Dargo, Do engineering teams really resemble sports teams?
  3. Roth Michaels, Spelling and Pronunciation in C++
  4. Daniel Jump, Replacing legacy string type
  5. Koen Poppe, Implicit conversion, friend or foe 
  6. Kris Jusiak, Static assert is almost all you need! 
  7. Alex Merry, Slide Core Guidelines
  8. Phil Nash, All the Defaults Are Backwards : Let's Fix That
  9. Ambrus Tóth, HyloDoc: Documentation Compiler for Hylo
Dave Abrahams gave the opening keynote about Hylo, one of many languages investigating safety in C++ and potential improvements. The focus was on value semantics, which he described as the "absence of entanglement".  Dave mentioned https://www.bemanproject.org/  My hand scribbled notes don't have any context, but their website says their aim is to "support the efficient design and adoption of the highest quality C++ Standard libraries."

Princess Bride quote: "That word you keep using, ..." in answer to the question "What does a reference mean?"

Next up, for me, was Jason Turner talking about constexpr. He started simple, and gradually added more details. I will need to relisten to this, because I know he covered a few edge cases I hadn't thought of, like lambda captures. I have noted constexpr doesn't change the lifetime of an object. On the face of it, that's obvious, but it's too easy to think it's some value baked in at compile time.

Next I listened to (some of) Björn Fahller's talk on cache friendly data structures. I was busy piecing together lighting talks, so hid up on the balcony to avoid being disruptive. He was talking through a  data structure with good locality of reference and showed efficient filters and deletes, and I did note down his github link. This says "Elements are kept packed towards the beginning of each column, but can be referenced using stable row_id type." This means tracking what has been deleted. One of many cases where a relatively easy to state problem leads to lots of thinking.

I spoke next, giving a high level overview of many nature inspired "swarm" algorithms, and then went into depth on the Cat Swarm algorithm.  You're right, cats don't swarm, but each swarm algo has agents with a position and velocity. The position is a potential numeric solution to a problem, and the velocity gives agents a trajectory, which changes over time, moving towards better places, for some definition of better. In our case, up mean the cat would be let out of a paper bag, so higher coordinates were more likely. 

After the lightning talks, I wanted to collapse in a heap. A small gang of us went to a Turkish restaurant just down the road, which serves a mix of vegetarian friendly and meaty food, in huge portions. Five stars.  

Thursday was less intense, which allowed me to concentrate on Cassio Neri's dragon talk. The full title was A new dragon in the den: fast conversion from floating-point numbers. Another easy to describe problem - print a numeric value. But how many digits, and how quick can you make it? He introduced a new algorithm called Teju Jagua which is a mythological monster: Cassio took great delight in telling us the tale. He's a great story teller. I'll have to go back slowly through the clever maths he did, but meanwhile here's a picture of the seven headed monster:




Next, I went to Jonathan Müller's talk An (In-)Complete Guide to C++ Object Lifetimes. There were so many C++ features I've either never used, like std::launder, or never heard of like std::destroy_at or std::start_lifetime_as. It's always good to discover new language features but my brain was melting by the end of this talk.

I went to see next, talking about Elevating Precision in C++: A journey below the surface of floating-point. Two floating point talks in one day might seem a bit much, but I've not heard him speak before,  and he asked me to sign a copy of my Learn C++ by Example book earlier, so I went to his talk. He talked about Dekker doubles, which led to an obligatory joke about double decker (buses). He asked if anyone knew what a bfloat was, and I made a fool of myself guessing the 'b' stood for binary - clearly not, on reflection. It's a brain float (bfloat16),   It's used for serious numerical computing, including neural networks, hence the name. Wikipedia tells me

It preserves the approximate dynamic range of 32-bit floating-point numbers by retaining 8 exponent bits, but supports only an 8-bit precision rather than the 24-bit significand of the binary32 format.
Daniela Engert then gave her keynote, called Not getting lost in translations. She was talking about Unicode, and how much you can do at compile time. Of course, constexpr got a mention again. I listened, while being mildly distracted by lightning talk emails, but made no notes. I know she showed some really interesting approaches, but I'll have to listen to the recording. It's nice to just listen and let your brain wander once in a while. 

We then had more lightning talks, being less ambitious for the in-between parts. I wasn't sure what to go for after coding rockstars, so I just asked "What's next?" For example,

1, 2, 3, ?

Yep. 4. Start simple. We went downhill from there though. 

I started Friday with Roth Michaels' How and when to write a template. This was part of the C++ fundamentals track labelled as for beginners. Again, we started simple. For example std::string is a template. Roth then considered various types of templates:
  1. class
  2. function
  3. alias
  4. variable
  5. lambda
As you might imagine, things got complicated, and Roth somehow covered EVERYTHING. I knew almost all the ideas he covered, such as std::visit, template template parameters and a question sparked a brief discussion about splitting templates into two header files, including an impl.h, to avoid all the things in one place. I'd forgotten about doing that. 

Next, I went to see Tristan Brindle talking about Practical Tips for Safer C++. This was also in the C++ fundamentals track, this time aimed at beginner or intermediary level. He talked about trapping or wrapping integer overflow, again starting with some simple slides, asking if code was potentially unsafe. Simple things, like sorting numbers can lead to trouble if your container has NaNs. So he suggested using std::is_lt for sorting. He mentioned his Flux library once or twice - it's worth looking at. One point he made, which cropped up several times at the conference, is constexpr can find UB.

I went to Peter Muldoon's talk, Dependency Injection in C++ : A Practical Guide after lunch. He considered various ways of injecting code
  1. link time
  2. virtual functions and inheritance
  3. templates including concepts
  4. type erasure
  5. null objects or stubs
He rejected the first approach quickly. It gets out of hand too easily. He then showed examples of the other approaches, which were all useful. The essence of his talk was approaches to take to make code testable. 

This led on nicely to the next talk by Steve Love, called Testable by Design. Steve built up an example of a thermostat and heating controller. Again, this started simple, and he showed various ways to chain together code, so the heating would go on or off at various times of day, without using the system time directly. If you do that, you are in danger of having a test that only passes at certain times of day. 

Finally, Klaus Iglberger gave the closing keynote, There is no Silver Bullet. He also talked about design choices, contrasting full on inheritance with templates and finally value-based OO, using type erasure and impls. He mentioned Ivan Čukić's Prog C++ talk, which was the closing keynote at MeetingCpp in 2023. He also contrasted the performance of each approach, but made us promise not to take the numbers too seriously. People can get hung up on performance, but extensibility is important too. The value based OO wasn't as quick as template tricks, but did make it easier to extend the internals or externals more simply.



It was a great conference, and I met new people as well as catching up with friends. Thanks to everyone who was brave enough to give a lightning talk, ask a question in a talk, or willing to attempt to answer a question from a speaker, even if they got it wrong. 


Monday, 8 July 2024

Learn C++ by Example: Chapter 9

I have been sharing some details about my latest book "Learn C++ by Example", and gave an overview of chapter 8 last time. There are 9 chapters, so this is the final blog about the book's contents.




You can buy my book directly here: http://mng.bz/AdAQ - or just go look at the table of contents. You can also buy it from Amazon: https://amzn.to/4dMJ0aG

The final chapter explains parameter packs and uses the std::visit pattern. Since we're on the last chapter, we also get opportunities to practice variants, std::format and ranges. We used a std::variant back in chapter 5, to hold either a Card or a Joker. Chapter 5 noted a variant's definition:

template <class... Types>
class variant;

We learnt that the dots are called a parameter pack, allowing us to use zero or more template arguments. We used a variant with two types, a Card or a Joker, back then, but we could have more than two types. We used std::holds_alternative<Joker> to detect if a card was actually a Joker. With more than a couple of types, this can get clumsy, so this final chapter shows another approach.

We explore how to write variadic templates, i.e. templates with at least one parameter pack, looking at fold expressions. Jonathan Müller's blog has some great examples if you want more details. The three dots in the template head indicate a parameter pack,  and we use three further dots to unpack the parameters, for example

template<typename... Ts>
auto add(const Ts&... tail)
{
    return (... + tail);
}

allows us to call add(1, 2) or add(1, 2, 3). You need to watch out for left or right association, for some operators. 

The mini-project in this chapter is building a slot machine. We build up three "reels" (vectors) of numbers, rather than more traditional fruits or similar for slot machines. In fact, we use the triangle numbers. If you can't remember what they are, read my book or find a good online resource.  Just think of arranging snooker balls in a triangle and counting how many you have: 1, 3, 6, 10, 15, 21, ...

If you consider the last digit of each triangle number, a pattern emerges, and repeats. The last digit will be 0, 1, 3, 5, 6 or 8 and nothing else. 8s and 3s are less likely than the others. If we set up three reels with these numbers and compare the final digits we can give a payout, as a slot machine would. Two matches gets a small payout, and all three gets more. In fact, we give a higher payout for 8s and 3s since they are less likely. Trying to calculate a fair payout was a challenge, so I spared the readers and used an approximation. 

The first game just lets the reels spin. How do we spin the reels? We shuffle the vectors first, so we don't know what's going to happen initially, but after that the reels want to move forward by a random amount. And yes, "That's a rotate".  (Ólafur Waage's blog "Everything is a rotate" will explain that meme if you've not heard it before).

Because the reels stay in order, we can display the previous and next numbers above and below the current line, and allow a hold or nudge something like a real slot machine. By adding three structs, 

#include <variant>
struct Hold {};
struct Nudge {};
struct Spin {};
using options = std::variant<Hold, Nudge, Spin>;

we can extend the game relatively easily.  One approach is using a struct with an overloaded method for each type:

struct RollMethod
{
    void operator()(Hold)
    void operator()(Nudge)
    void operator()(Spin)
};

This is far better than checking std::holds_alternative, for each type. The chapter goes on to explain the Overload pattern and how to use std::visit. We need a different function for each type, or double dispatch. Have an experiment, and see if you can code this up.

The chapter also briefly mentions C++17's execution policies, mutable lambdas and std::views::zip, as well as giving extra practice with algorithms and std::format

So, some questions for you
  1. Can you find the repeating pattern of the final digits of the triangle numbers? (Write code to generate them, and have a look).
  2. Can you rotate a vector by a random amount? (It seems a few people can't remember how to use std::rotate, so practice).
  3. Can you use std::visit for the three different options, hold, nudge or spin? 
I've now shared an overview of each chapter. Have a play around with the mini-projects and get in touch if you can think of other good learning examples. 

 


 

 



Monday, 1 July 2024

Learn C++ by Example: Chapter 8

I have been sharing some details about my latest book "Learn C++ by Example", and gave an overview of chapter 7 last time. There are 9 chapters, so this is the penultimate blog about the book contents.




You can buy my book directly here: http://mng.bz/AdAQ - or just go look at the table of contents. You can also buy it from Amazon: https://amzn.to/4dMJ0aG

Chapter 8 is predominantly about unordered maps and coroutines. The previous chapter used std::map, which has been in C++ for a long time but allowed us to learn several new features anyway. This chapter uses an std::unordered_map for contrast. The unordered containers were introduced in C++11. They use hashes to place elements in buckets, so the std::unordered_map is a hash map. There are many overloads of std::hash but you might need to write one to use the hash map, for example for your own class or std::tuple.

The mini-project in this chapter is a game of matching pennies. Two players secretly pick heads or tails on a coin, and simultaneously show their choice. One player is trying to get a match, and the other tries to avoid this. It's not hard to write code where the computer wins on a match, using random numbers for the computer's turn, giving a basic version of the game. 

Now, Claude E. Shannon wrote a short paper in 1953 called “A Mind-Reading (?) Machine” Yes, that Claude Elwood Shannon - the accomplished unicyclist and founder of information theory. The paper has a question mark in the title because the machine isn't really mind-reading. Shannon tracked whether the penultimate outcome was a win or lose, and if the player then changed from heads to tails (or vice versa) or played the same move and thereby won or lost. The three elements can form a lookup table and we can record whether the next choice was a change or not. If we just store the last two values  (change or not) for a given state, we can perform a lookup and if they match, make a prediction. If they don't match, the computer plays at random. The mind-reading machine is surprisingly effective, though you can outsmart it if you track the same state yourself. 

Coding it up gives the opportunity to practice all kinds of C++ features, as well as think about how to form a hash for the three part key. The first part of the chapter creates a MindReader class template, taking a generator and distribution as template parameters, making the code using randomness easy to test. Armed with a mind reader, we then see how to use this in a coroutine. Doing so makes no difference to the matching pennies game, but is an opportunity to learn about this new, much discussed feature of C++.  

You can pause a coroutine, say after yielding a result, and resume later. CppReference says 
This allows for sequential code that executes asynchronously (e.g. to handle non-blocking I/O without explicit callbacks), and also supports algorithms on lazy-computed infinite sequences and other uses.
Coroutines allow cooperative multitasking for example running some code, then suspending while awaiting a result. You need to write a lot of boilerplate to get a coroutine working, but the compiler will help you remember what to add. Again, the compiler will point out anything you need if you forget something. 

If you see a function with one of the following 
  • co_await
  • co_yield
  • co_return
the function is a coroutine. The return type must then fill in the boilerplate, including how to start and stop, and what to do with a co_await, co_yield or co_return

Ivan Cukic gave a keynote at MeetingCpp in 2023. He mentioned coroutines (and lots of other ways to style C++ code for various use cases and neatness). Go look at the slides: From slide 69, he talks about "C++ error handling, let’s abuse the co_await operator." An usual use of coroutines, but interesting.

So, some questions for you:
  1. Why are the C++11 containers called unordered?
  2. How would you write a hash function for a std::tuple, say of just three elements?
  3. Can you list all the parts a coroutine's return type needs?