Types and other techniques as an accessibility tool for the ADHD brain - Michael Newton

Discovering ADHD in my 40s transformed my approach to programming and life.

The next speaker is Michael Newton. Michael, would you mind introducing yourself?

Hello, I'm Michael. As you can hear, I originally hail from the British Isles, but I am currently living in Italy, working remotely as a software developer. I think that's the most important bit in terms of what you need to know for this talk.

Out of curiosity, why Italy? I know plenty of Italian developers who move to England.

Let's go with two reasons. First, Brexit—I'll leave that one there because let's not have that discussion. The other reason, which is possibly more universal, is that my wife is Italian, and my parents-in-law live in a small town just north of Verona. Given that I was working for a company in America anyway, it made sense.

Do you ever get weird cravings, like Beef Wellington or stuff you can find around here?

No, not really. Cheddar cheese—that's kind of it.

Really? Are you not happy to leave that behind?

You also stayed here in the north, right?

No, I'm in Lazio.

Oh, Lazio, right. So, Pecorino?

Yes, Pecorino. It's good cheese, but I still want cheddar.

Holy [ __ ]!

Okay, so please give it up for Michael.

[Applause]

Thank you. This is a very odd talk for me because I have been doing conference talks for quite a long time now. I have had a relatively successful career in software, and most of my talks have been about fairly esoteric technical things that I got interested in and then gave talks about. For example, the first talk I gave was about type providers for FP, which are effectively compiler plugins, and so on. However, this talk is something totally different and seems much more appropriate for this particular conference.

I will be talking about the features I found in programming languages that, over the years, I've realized are actually my accessibility tools for programming with my ADHD. I have spent most of my adult life very, very tired and have talked to various doctors about it. They did blood tests and checked for all the things that cause fatigue, but never really found anything. Life just seemed quite hard. In the meantime, I got married, had a son, and my job was going reasonably well, but I was fatigued a lot of the time.

Eventually, a few years ago, well into my 40s, I came across a podcast with a guy called Matt Tersson, who some of you might recognize as the head language designer for the C programming language. He talked about his diagnosis with ADHD and mentioned that he got the diagnosis because of chronic fatigue.

In this talk, I will spend some time discussing ADHD and what it is. I will also talk about the features I found in programming languages that help me and why. Additionally, I will discuss the fact that as programmers, we like to think of ourselves as very logical and believe things can be better or worse or provable or not provable. I will make the case that this isn't really how we make a lot of technical decisions. Instead, we pick the things that work for us and then overgeneralize because that's what humans do about everything.

So, let's go with it. What is ADHD? The quick answer is it's not really anything in the sense that, as with many medical conditions—sorry, I hope you can read my handwriting; I decided it would be appropriate if the slides were quite messy because my brain is quite messy. ADHD, like many medical conditions, doesn't really exist in the sense that they know there is a thing that causes these effects. It's the reverse: there is a group of symptoms that are grouped together often enough that medics have decided it's useful to give them a name. But that doesn't necessarily mean that because you have those symptoms, you have it for the same reason as someone else with the same symptoms.

I'm not an expert, and don't take any of this as medical advice. I'm mainly going to be talking about my own experiences.

=> 00:05:17

ADHD isn't just about hyperactivity in kids; it's a lifelong struggle with executive function that varies greatly from person to person.

I hope you can read my handwriting. I decided it would be appropriate if the slides were quite messy because my brain is quite messy. I was struggling to find that bridge between handmade and legible, so hopefully, it's legible.

ADHD, like many medical conditions, doesn't really exist in the sense that there is a thing that causes these effects. It's the reverse: there is a group of symptoms that are grouped together often enough that medics have decided it's useful to give them a name. But that doesn't necessarily mean because you have those group of symptoms, you have it for the same reason as somebody else who has the same group of symptoms. I'm not an expert, so don't take any of this as medical advice. I'm mainly going to be talking about my own experience. On one hand, I want to share things that you may spot in yourself or in others that may be useful, sort of going, "Oh, maybe I should think about that." On the other hand, I don't want to give the impression that everybody who has ADHD has the same life experience I do because that won't be true either.

The symptoms that go into it can be read in paragraphs of description, but fundamentally, they boil down to a continuous struggle with executive function which has lasted for your whole life. It's not that you struggle with it now or because you're tired; it's something ongoing. This initially comes across as quite strange to many people, especially in the Anglo-Saxon world, such as the US and the UK. When you talk about ADHD, it normally comes up in the context of school kids who are excessively hyperactive in classrooms and disruptive. You might wonder how that translates to a lack of executive function, which is knowing what you want to do and then doing it. Executive function is that ability to join up your desires with actually making them happen. That can be very short-term, like being told to sit still for an hour and actually doing it, or very long-term, like planning a holiday in Greece, booking tickets, and making all the necessary arrangements.

To get a diagnosis of ADHD, you have to have ongoing experiences from childhood where there are continuous examples of you knowing what you want to do, knowing that you can do it, and not doing it. The final part, which is where it gets really weird and where I don't understand psychologists at all, is that the threshold for whether or not you get a diagnosis is not how much you struggle with this but how much distress it causes you in your daily life. You can have someone who neurologically has much worse symptoms than me, but because they do a job where they do not need to exercise executive function on a day-to-day basis, they wouldn't necessarily get a diagnosis because it's not causing them issues in their life.

Looking back, the first really strong sign I had that I had ADHD was during secondary school in the UK. There was very little coursework, at least when I was going through secondary school. You turned up, got given a piece of homework, and it generally needed to be handed in within a week. You built up to a final exam, needed to know the information for the final exam, did the exam, and then you could forget about it. It was very structured: your teachers told you what to learn and when to learn it. I did really well at school, and no one suspected I had problems with attention. Then I got to university, where the environment was more like, "Hey, you've got three months to study this topic yourself, arrange your own study plan, make sure you learn this thing, and then next term we're going to build on all the stuff that you taught yourself last term," obviously with the help of lectures and things.

=> 00:09:06

I thrived in school with structure, but crashed in university's self-study environment, revealing my ADHD.

In school, the structure was clear: within a week, you built up to a final exam, you needed to know the information for the final exam, and then you could do the exam and be done with it. It was very structured; teachers told you what to learn and when to learn it. I did really well at school, and no one suspected I had problems with attention or anything. However, when I got to university, the environment changed drastically. It was more like, "Hey, you've got three months to study this topic yourself, arrange your own study plan, and make sure you learn it." The next term would build on everything you taught yourself last term, with the help of lectures and other resources. I just crashed and burned. I barely passed my first year and never went back to university because I lost my funding due to my performance. In the meantime, I got a job over the summer, and that was the first hint of my struggles.

What does it feel like? This is where things get weird because I didn't realize for a long time that my experience of life was different from anyone else's. As humans, we associate vocabulary with what we assume it means to others based on what it means to us. Many things you hear about ADHD, you'll think, "Doesn't everybody do that?" because the mechanisms are such that if you get tired, stressed, or have had many changes in your life recently requiring big decisions, you will suffer executive function failure. Humans generally do not have an infinite capacity to carry on regardless of circumstances.

Two comments struck me hardest at different times. One was shortly after I met my wife, probably on our first or second anniversary. I missed the date, and my wife commented, "If you really care about things, you'll remember them." I was just like, "What?" She said, "If a day is really important to you, don't you wake up and know that today is important?" I was like, "No, where does that come from?" It never occurred to me that this is not how most people think. It turns out one common experience of ADHD is sometimes referred to as temporal blindness. We tend to have a much looser connection between how recent a memory feels and how recently it actually happened. We also don't tend to remember to do things at a particular time of day. My wife can remember to do something at 3:00 PM, but I need a reminder, or it’s not happening.

The other significant comment came from the psychiatrist who assessed me a few years ago. He adjusted the dosage of my medication, noting that not everyone with ADHD can be helped with medication. He explained, "You decide to do something, then you need to start doing something, and then you need to do something." I agreed, and he pointed out that most people don't have that middle step. They decide to do something and then do it without an effort to transition between those states, assuming it’s something they want to do. He said, "We'll know we've got the dosage right when, during the period where the meds are working at full strength, you don't have that division. You decide to do something, and you start without a preparation period."

The reason it often manifests as fatigue when diagnosed is because of these transitions and the effort required to manage them.

=> 00:13:20

Realizing I had ADHD explained why I was constantly exhausted despite appearing successful.

I was like, yeah, and he was like, most people don't have that bit in the middle. They decide to do something, and then they're doing it, but there isn't an effort to transition between those two states, assuming that it is actually something that they want to do themselves. I was like, oh, okay, that's weird. I had realized that one. He was like, "We'll know that we've got the dosage of the meds right when, during the period where the meds are working at full strength, you don't have that division. You know you want to do something, you decide you're going to do it, and you start, and there isn't a gap in between; there isn't a sort of preparation period."

So, the reason that it often manifests then as fatigue when it's diagnosed in an adult is something that probably is excessively prevalent in the programming community. It turns out that if you have good verbal reasoning skills and ADHD, what will often happen in the way modern society works is that you can compensate for the ADHD by firefighting all of the chaos that you cause for yourself and by sounding intelligent. This sort of creates a good impression, and people assume you're competent even if you're actually not necessarily. You can sort of bridge the gap fast enough to keep up with life, but that's actually very tiring, especially when each thing that you do takes another sort of hit out of your very limited executive function.

There was a moment where I had been listening to this podcast with Mad Till, and I sort of realized, oh, that sounds a bit familiar. But is there actually even there, is there not? The reason that sort of triggered my realization that I needed to do something about this was that there was one day where I knew that I needed to do the washing up, and it just reduced me to tears. I literally broke down in the kitchen and cried because I couldn't make myself do the washing up. I was just like, that's not normal. That's not a life experience that most people have.

The question then becomes, I'm having this struggle with life, I'm constantly fatigued, but at the same time, I'm doing conference talks. I was working as a consultant for a while, working as a senior developer in a remote team, mentoring other developers. How is this working? How am I getting work to work even while the rest of life is obviously got something fundamentally wrong with it? This coincided with a change of work environment where I had gone through a period over several years of interacting a lot with people in the Ruby Community for different reasons, primarily teaching them functional programming, which is more my background. Talking to more and more people who have that different background, I realized that some of my assumptions about why I didn't like dynamic programming and why I thought functional programming worked better and static types were great were actually not as certain as I assumed they were.

I got the ADHD diagnosis, and I was looking at my situation, trying to explain how I was doing this. I began to realize that we talk a lot about better and worse ways of doing programming. In fact, we even talk about best practices quite a lot. I still have lots of opinions on programming and lots of preferences. If you'd asked me like 10 years ago, I would have said that I knew some things about programming—things that were better or worse. I'm more and more coming to the opinion that there are some things I still think are definitely worse, but there are actually a lot of things which are not as certain as I assumed they were.

I like type systems, and I'm going to get into why in a moment. It turns out that there is a really nice literature review by a guy called Dan L, who wanted to look into the literature around whether strongly typed programming languages actually lead to codebases that have fewer defects and are more maintainable over the long term. He basically came to the conclusion that there is absolutely no empirical proof at all that this is true—not that it isn't true or that it is—but just that fundamentally, we do not have the evidence to support that assertion.

=> 00:17:23

Sometimes what feels like the best way to do things is just a way to compensate for our own weaknesses.

I still believe there are some things that are definitely worse, but there are actually a lot of things which are not as certain as I assumed they were. I like type systems, and I'm going to get into why in a moment. It turns out there is a really nice literature review by a guy called Dan L, who wanted to look into the literature around whether strongly typed programming languages actually lead to code bases that have fewer defects and are more maintainable over the long term. He basically came to the conclusion that there is absolutely no empirical proof at all that this is true—not that it isn't true or that it is—but just that fundamentally, we do not have the evidence to support that as a statement.

Another example is that I really like property-based testing. For me, it fits a really nice niche, being able to cover a lot of ground very quickly. You can think about how you're going to solve the problem rather than writing lots and lots of little repetitive things to solve the problem. This is great and fantastic, except that there are some really nice counterpoints from Brian Marrick, who does a lot of testing within the agile community. He mentions that while he likes some of the ideas of property-based testing, there are past papers that looked at partition-based testing. I'll get into what this is a little bit more in a moment. Partition-based testing makes the case fairly clearly and on a solid logical basis that there is actually quite a small category of problems where you will get improved reliability by using partition-based testing. I found this to be another interesting point to consider.

A final example, for which I don't have papers, involves a long discussion with someone at my previous workplace about domain-driven design. Domain-driven design has this idea of bringing the language from your product into your code. For those working on embedded systems, this might be a different world, but for business products with users and customers, domain-driven design promotes the idea of ubiquitous language—the language which applies everywhere for everybody. The big idea from domain-driven design is to use the language that your users use to describe the problem in your code. This way, you can run through the logic of your code with the actual experts in what it's supposed to be doing, and you're both using the same language to describe what's happening. However, I had a long discussion with someone who felt this was bringing unnecessary cognitive load onto the developers. They argued that developers now need to know not just Ruby but also all of this technical language from the domain space as well. I kind of see their point, but I'm less convinced by it.

These discussions made me think about why, when I started programming, I latched onto these techniques which are not particularly common in the industry. They are not well-known techniques and are not the normal way of doing things. I realized that I wasn't doing this because it's better; I was doing this because these techniques compensate for my weaknesses. I had slides for this, talking about ADHD. Last night, I had run out of medication, and dinner got delayed because the restaurant we tried to go to was closed. I got to the hotel later than I meant to, and I had one slide left to do on my slide deck. Instead of finishing it, I spent two hours wondering if I could screencast slides to doodle on them while talking. Then it was 1:00 AM.

=> 00:21:21

ADHD makes it hard to focus and remember details, so I use structured techniques to compensate and stay productive.

The discussion delves into ADHD, exploring what it is, how it works, and its impact on individuals. The speaker shares a personal realization that certain techniques are used not because they are inherently better, but because they compensate for personal weaknesses. For instance, the speaker recounts an experience from the previous night involving medication that kicks in within a 5-hour window. Due to a delayed dinner and a closed restaurant, they arrived at the hotel later than planned and had one slide left to complete. Instead of finishing the slide, they spent two hours experimenting with a new tablet and stylus, leading to a late night without completing the intended task. This highlights how ADHD can lead to procrastination and inefficiency, contributing to long-term fatigue.

The speaker then transitions to discussing the importance of types in programming. While many argue for types to ensure reliability and correctness of code, the speaker appreciates types for a different reason: they often forget to type things. For example, forgetting return statements in Python can lead to confusing null values. Additionally, ADHD often correlates with poor spelling, leading to frequent mistakes in dynamic languages that are only discovered when running the code. Immediate feedback in the editor about typing errors significantly improves the programming experience for the speaker.

Despite a respect for dynamic languages and an interest in metaprogramming with Lisp, the speaker finds the lack of immediate feedback too detrimental. They acknowledge that while types may not be the superior method for everyone, they are crucial for their own effectiveness. The speaker explains that adding types to programs involves writing theorems about the program's constraints, a non-trivial skill not widely taught. For the speaker, splitting programming into designing constraints and writing code that follows those constraints is easier than holding all constraints in mind while coding. This approach compensates for the weaker working memory associated with ADHD. However, they recognize that this method may not be necessary for everyone, as some individuals have sufficient working memory to manage programming tasks without such division.

The speaker concludes by referencing Rich Hickey's hammock-driven development, where Hickey spent weeks thinking about the design of Clojure before implementing it, illustrating a different approach to programming that contrasts with the speaker's need for immediate feedback and structured constraints.

=> 00:25:30

Programming languages reflect their creators' personalities.

One of the challenging aspects of programming is designing the constraints on a system and then managing to write code that adheres to those constraints. It is difficult to hold in one's head all the constraints while writing the code. It took me a very long time to realize that this challenge doesn't apply to everybody. For many people, their working memory covers just fine the task they need to achieve with their programming language. A classic example is Rich Hickey's hammock-driven development, where he spent weeks thinking about how to design Clojure while lying in a hammock. He eventually came up with the design, whereas I would have ended up with three new pizza recipes and a role-playing game, but not a programming language. This makes more sense when considering that Hickey wrote a dynamic language with meta-programming.

This observation ties back to how communities influence programming languages, but I've been fascinated by how the personality of the original author influences programming languages. I gave a talk at Lambda Days a few years ago, discussing Elm and FP, which superficially look very similar. Having worked with and met both original authors, I can see their personalities reflected in the codebases, even years later with many contributors involved.

Teaching my son to program was another enlightening experience. He is now 17 and quite competent, but when he was about 8, he needed to see his code run immediately. He didn't want to wait for it to be perfect; he just wanted it to do something. I understand this urge, especially when interacting with a new system or API. Regardless of how good the documentation is, it won't always give you what you expect, so you want to reach the point of seeing the output as quickly as possible. Types can make this harder, presenting a trade-off.

An interesting conversation on LinkedIn, surprisingly useful, involved someone with ADHD who loved test-driven development (TDD) for the same reason I like types. He could think about the design of his code, write it down as a series of tests, and then implement those tests. I understand this in theory, but this is where the downside of ADHD comes in. There is a difference between the ideal TDD described in books and the TDD encountered in practice. The idea is to write about the properties of your code, implement those, and then refactor. However, in my experience, people often end up writing many tests that are essentially debugging checks, verifying if the code does what they think it should.

What tends to happen is that you end up with about 5,000 tests, and if you swap the order of three lines of code, all the tests break. Fixing all these tests can be a truly painful experience, especially for someone with ADHD.

=> 00:29:24

Overloading on tiny tests can make debugging a nightmare, especially for those with ADHD. Opt for meaningful tests and avoid pointless code coverage metrics.

In a situation where developers write a multitude of tests, these tests often serve as a form of debugging, checking whether the code behaves as expected. You might encounter tests that specify, "Oh, I'm going to give this Mock and it should get called first and it should give this result, then that should cause this other mock to get called, which should do this, which should give this result." However, what happens is you end up with about 5,000 tests, and if you swap the order of three lines of code, all of the tests break. Consequently, you have to go back through and either fix all of the tests, which for someone with ADHD is a truly painful experience. This involves going through numerous tiny tests that check completely pointless implementation details that no one should care about. Even worse, if you delete them, you then have to explain to someone why the code coverage count has decreased on the CI server. It's because the code coverage count wasn't telling you anything useful. We'll come back to that when we talk about property testing later. Don't do code coverage metrics, please. I'll stop ranting about mocks now.

Moving on, all of the languages I've been interested in are very small. I really enjoyed working with Elm, which is a very small language. I've also enjoyed working with F#, which is surprisingly small. It has the caveat that it needs to be able to interoperate with C, so it has a bit of cruft around the edges for allowing some of that interop. The common point around these languages is that they've chosen a small number of powerful ideas that let them do what they need to do. For example, in pseudo code, this wouldn't actually work quite like this in either language, but this is roughly a comparison of FP and TypeScript. Don Syme, who wrote F#, didn't include higher-kinded types in the language partly because that would have made interoperability with C a disaster and partly because he thought they probably didn't need it. Instead, he has this idea of computational expressions where you can encapsulate repetitive code for handling the same type of wrapper.

I don't want to use the monad word because they are not quite equivalent, but you can effectively use them for most of the same things. For instance, you can declare a certain block that knows how to handle async operations. You can write let! user = the result of this async function and in the rest of this code block, user will just be a user. The fact that you got it asynchronously doesn't matter because all the code for handling that is in this async wrapper. If the data might not exist, you can have a wrapper for that as well. If the data might be async and might not exist, that's fine too; you can deal with that using the same abstraction. In contrast, JavaScript adds each feature separately, such as await for async operations, yield for iterators, and a null coalescing operator for optional values. When you want to combine these features, it becomes increasingly complex.

This brings us back to the working memory issue and the discrepancy between reasoning ability and working memory. I'm not necessarily claiming to have the most amazing non-verbal reasoning skills, but for me, it's definitely much stronger than my working memory skills. Yes, this is an abstraction, and I did need to learn how it works. I had to write some of my own before I truly understood what it meant and what it was turning the code into when I ran it. Once I knew, I had one thing to remember. If you've looked into psychology, there's this concept of chunking, where you can take lots of pieces of information and find a common logical framework for them. At some point, you actually chunk it into a single block, which consumes less of your working memory when you're thinking about things. This is one thing, and there are other languages I've used and enjoyed for similar reasons.

=> 00:33:30

Union types in programming are a game-changer for clear, self-documenting code and error handling.

Yes, I did need to learn how abstractions work, and I had to write some of my own before I really got into my head what they mean and what the code turns into when I run it. Once I understood, I had one thing to remember. If you've looked up some of the psychology of how people learn, there's this concept of chunking. Chunking is where you take lots of pieces of information and find a common logical framework for them. At some point, you chunk it into a single block, which consumes less of your working memory when thinking about things.

There are other languages I've used and enjoyed for different reasons. I really like the idea of Lisps because of the metaprogramming power and easy access to macros. However, I found it really hard to write larger pieces of code in Lisps. I enjoy playing with Haskell because you can do really insane things with it, but I struggled with the fact that every Haskell codebase is different due to different compiler options and styles. I often come back to languages like F# and Elm, or if using a more flexible language, I prefer having a discussion at the beginning of the project about the house style.

Regarding .NET, I don't actually mind .NET Core and have quite a lot of time for it, but that's a separate discussion. Coming back to types, I like types. Talking about small but powerful features of programming languages, I tend to write business code most of the time and think a lot about modeling a business process or a real-world thing. For example, I find Union types really helpful because they allow breaking down a big problem into smaller problems in a way that's easy to explain to someone else. If I add a third contact info method, the function stops compiling, which is a killer feature for me because I don't want to remember all the places I need to change things.

Union types are probably the clearest form of documentation of code I have found so far, and it's also compiler-enforced, which is lovely. One thing that happens a lot in business code is we tend to have at least two classes of error. Union types allow you to clearly demarcate not just whether the code worked or not, but also handle errors like a temporary bounce-back message from an email. Union types become a very clear way of documenting the different logical semantic meanings of different return types from functions, something that older versions of Java struggled with.

I find Union types really helpful because they are super explicit. If you change something, it breaks everywhere until you fix it everywhere. If you add something, you have to handle it everywhere, and I love that. I love the self-documenting features of them, but there are trade-offs.

=> 00:37:51

Union types make code explicit and self-documenting, but can limit flexibility.

I encountered an issue where a payment from a credit card was not processed, and Stripe didn't respond. I tried to send an email but received a temporary bounce-back message. This situation highlights the importance of Union types in documenting different logical semantic meanings of return types from functions, something that the Java of 1995 struggled with. Union types are very explicit; if you change something, it breaks everywhere until you fix it. If you add something, you have to handle it everywhere. I love the self-documenting features of Union types, but there are trade-offs, such as a lack of flexibility. For example, they are great for representing a syntax tree until you need to allow plugins to add new syntax, which complicates things.

I also find domain-driven design (DDD) incredibly helpful. It addresses the challenge of working in the mid-space where code is about code, which can be difficult for someone with ADHD. When given a task, I can get lost in the technical details and forget the main objective. DDD helps by using the words of the task in the code, making it easier to stay focused on the problem at hand. For instance, while working in local councils, we dealt with vulnerable adults and kids. The term "user" was too generic, as it could mean staff, teachers, kids, or parents. Using specific terms like "guardian" helped align the code with the terminology used by social workers, making it easier to understand the context and the actual problem we were solving.

The counterargument to DDD is that it adds complexity by requiring developers to understand all the terminology and the user's problem. However, I see this as an advantage. There's an excellent blog post listed in the links at the end that discusses how reality has a surprising amount of detail, which is another reason I favor domain-driven design.

=> 00:41:45

Understanding the user's real-world context and terminology leads to better software design.

In my brain, I need to understand the context of what I am actually trying to do. I believe the counterargument I was given for DDD (Domain-Driven Design) is actually one of its advantages. The counterargument was that it loads all of this complexity onto the developers, requiring them to understand all the terminology and the problem that the user is trying to solve. My response to this was, "Yeah, I'm not seeing the problem here." There is an excellent blog post, which is included in the list of links at the end, discussing how reality has a surprising amount of detail. This is another reason I like the domain-driven design idea of using the terminology that the user is using. If you start talking about a user, you tend to form a very simplistic mental model of what a user is. However, if you start talking about a guardian, the social worker will tell you, "Oh, well, we need to know this and we need to know that, and the relationship to this other thing is that," and you immediately get that surprising amount of detail. I actually think that's a good thing, although some people will disagree.

The idea that you don't care about the humans who are using your software is problematic. If you think that way, you're probably at the wrong conference. I have had someone actually say that to me, and I was gobsmacked.

Moving on to property-based testing, for those who don't know, it involves stating a property of your code, such as it doesn't throw exceptions or it reverses strings. Then, you generate inputs, run it 100 times, and see if it breaks. For example, handling phone numbers on international websites can be a pain because nobody actually types in their country code. You get the input from the user and the country they say they're from, and then you try to guess what they actually meant by their phone number. Here, we generate country codes and phone number inputs and write a property like, "Once we've normalized the phone number, it should always start with a plus."

On one hand, I love this because there are often a whole load of really simple tests where you just write simple inputs, know the results, and can generate them easily. However, there is a downside. It can become tempting to write excessively complex generators to cover things that are very hard to property test, and you might end up writing a duplicate of your business logic in reverse in your generator, which is not good. I have made that mistake. Another issue is that measuring coverage as an indication of how good your tests are can be misleading. For instance, if we ran the test mentioned earlier, we would get 100% coverage of that method because it would try all the different options. However, the test only checks one specific thing: whether the normalized phone number starts with a plus. It doesn't check if it got the phone number right, if it normalized the number correctly, or if it identified unnormalizable numbers correctly. So, it would give you 100% test coverage of the code parts but only cover one property of the function, which can be misleading.

Lastly, we are entering Dreamland now, discussing features I wish programming languages would have. I would love a production-worthy, well-tested ecosystem language that includes dependent types and linear types. There is a lot of academic research on these topics, but that's not primarily why I want them. Dependent types are fascinating, but linear types are particularly interesting. For those unfamiliar, linear types allow you to tell the compiler that a function needs to be called exactly once from the moment it is declared before the program continues.

=> 00:45:39

Dreaming of a programming language with dependent and linear types, seamless tooling, and strong community standards!

The discussion begins by addressing the complexity of programming languages and their features. The speaker notes that dependent types and linear types are often seen as academic concepts, but they have practical applications. For instance, linear types allow a programmer to declare a function that must be called exactly once before the program terminates. A classic example is a database connection that returns a disconnect function, which must be called once before the program ends. If the function is not handled correctly, the program will not compile, ensuring that resources are managed properly.

The speaker expresses a desire for a production-worthy language with these features, emphasizing that they are not just academic but have real-world utility. They also mention the utility of dependent types for tasks like converting a list of names and values into a structured format at compile time.

The conversation then shifts to the broader ecosystem of programming languages, highlighting the importance of tooling and automatic formatters. These tools are essential for maintaining code quality, especially in team environments. The speaker shares a personal anecdote about attempting to push incomplete work to the production branch, only to be stopped by the build server, which underscores the importance of a robust build process.

The speaker also touches on the social aspect of programming, noting the value of consistent formatting within a community. They mention the cognitive load of adhering to a style and the frustration of being asked to run a series of automatic tools before every commit. This experience led them to introduce continuous integration to multiple workplaces, realizing its necessity for professional work.

In conclusion, the speaker provides a link to their blog for further reading and opens the floor for questions. They acknowledge that their preferences may not work for everyone but have found them beneficial in their experience. The talk wraps up with a round of applause and an invitation for questions from the audience.

=> 00:49:40

Realizing I can't work without certain tools was a game-changer for me.

Once I realized that I could never actually professionally work without it again, I understood the importance of certain tools and practices in my workflow. That was sort of a whistletop store tour of why I like some of the things I like, why they work for me, and why I've learned over the years that they don't necessarily work for everybody else. There is a link to my blog in my speaker profile on the website, which is probably the easiest way to access it. I realized after I posted the convenience link that it has the date in it, so it's not actually very convenient, but there you go. And that's about what I've got.

[Applause]

Thank you very much. So, are there any questions? We're going to do just a couple because we're running a little bit late. Not sorry, it's fine.

Audience Member: I have a question actually.

Speaker: Oh, you have a question? Yes, and you're going first also.

Audience Member: Oh, it's F. No, no, go for it, go for it. Okay, so I heard you were having trouble with, like, for example, for Union types, right? For getting errors when you change a union type, for example, right? You add a new type to a new field or whatever. How do you feel about editor tooling like find all references? Does that help you with that maybe?

Speaker: So, editor tooling can help, but I have a small mental stack. One of the reasons I love types is that I'll often find that I will write the types of an API, and I'll get halfway through writing the code, then go and get a coffee, and come back thinking I was done, but obviously, I'm not. People talk about things like Ruby and Rails; I know a lot of people really love it and find it a productive environment. I absolutely hated it because it's entirely convention-driven. People say it's so easy, they always know where to look for things, but I don't remember to go and look. That's the whole problem. Good editor tooling is really useful, especially in debugging scenarios, but in terms of this side of things, it's all about having the reminders and being able to set up the reminders in advance.

Audience Member: Thank you so much, that makes a lot of sense. Let me pick someone else. Let's see who Alo speaks.

Alo: Hey, firstly, thanks for discussing neurodiversity. It's much appreciated. I'm sure I'm not the only one here who feels represented, so thanks a lot. About 10% of the programming community is neurodiverse, as far as I can make out, and that's before you get into the overlap between the autistic spectrum and ADHD because they often come together. I saw a study recently which pointed out that if you make accommodations for neurodiverse people in the workplace, then it helps everyone. I just wondered if you've got any thoughts on that or if you've got any experience or advice on that.

Speaker: I think generally that's true. The caveat is that sometimes it pays to play to your strengths. For example, at the moment, I'm working in a very small team—there's like four of us. The whole company is four of us; it's a somewhat stealth-stage startup. We all have a functional programming background and 15 years plus of programming experience. There are things that I'm doing there that I would not do in other environments just because I already know that the people dealing with that code would have that stuff pre-chunked and are ready for it.

There is a balancing act. In general, I agree, especially when working in larger teams. I've argued quite hard that it would make sense to accommodate as much as we can. The place where it starts feeling wrong for me is when some people assume that means you shouldn't use any of what they consider advanced techniques. What people consider advanced depends entirely on their background, not actually how difficult that thing is to understand.

So, I hate to give a sort of waffly answer, but I think it depends on what you mean by accommodation. For some people, that means familiar and easy, and for others, it means addressing specific issues they have.

=> 00:53:34

Understanding ADHD means recognizing that traditional methods don't always work for everyone; find what works for you and embrace it.

There is kind of a balancing act when working in larger teams. I have argued quite hard that it would make sense to accommodate as much as we can. The place where it starts feeling wrong for me is that some people assume that means you shouldn't use any of what they consider advanced techniques. What people consider advanced depends entirely on their background, not actually on how difficult that thing is to understand.

I hate to give a sort of waffly answer, but I think it depends on what you mean by accommodation. For some people, that means familiar and easy, and for others, it means addressing a specific issue they have and finding a specific solution to help them deal with that issue. It can be a very difficult conversation to have because a lot of people don't know enough about the thing they're struggling with to be able to express that to you.

Regarding ADHD and working memory, one of the links on my blog is to a literature review of the link between working memory weakness and ADHD in adults. It's a symptomatic diagnosis, which means not everyone with an ADHD diagnosis will have a weak working memory, but there is an established correlation scientifically. Personally, I struggle with this as well.

In the first half of my talk, I described the issues, and in the second half, I explained how I cope with them in programming. But how do I cope in normal life? This is all quite new for me, as I was diagnosed only a couple of years ago. One realization for me was that I should change how I use calendars. Most people use calendars to remember boring stuff they have to remember, but I realized that the things that mattered most to me were the things everyone else didn't bother to put in the calendar because they would remember them anyway, whereas I wouldn't. So, I started putting the interesting stuff in the calendar to give it priority.

I also found a software service called SkedPal, where you can set tasks with estimated durations and priorities, and it will organize them in your calendar. If you don't do a task at the scheduled time, you can hit the button again, and it will recalibrate everything based on what you've actually done. This has been really helpful for me because one of the things with ADHD is decision fatigue. You reach a point where you just stop making decisions because you can't cope with making the choice. SkedPal helps by suggesting what to do next, reducing the burden of decision-making.

Helping others understand how your brain works can be challenging. I've been married for 20 years, so I've had many conversations with my wife about things that have happened in the past. One thing I recommend is a podcast by Mads, where he talks about being successful at work but feeling like he's letting his family down because he has a PA at work organizing everything, but at home, he's lost. He talks about letting go of the guilt and realizing that the things he was told should work didn't, and that's not his fault. However, he still keeps the responsibility and tries to find solutions that work for him.

There isn't a right answer because the causes are subtly different for each person with the diagnosis. There's a website called How to ADHD with a bunch of suggestions. It's important to try different things and not give up if something doesn't work. The same solutions don't work for everyone.

Thank you, and please give it up for the next talk. We'll come back in 10 minutes.