Code that fits your brain
This is a modal window.
The media could not be loaded, either because the server or network failed or because the format is not supported.
Formal Metadata
Title |
| |
Title of Series | ||
Number of Parts | 170 | |
Author | ||
License | CC Attribution - NonCommercial - ShareAlike 3.0 Unported: You are free to use, adapt and copy, distribute and transmit the work or content in adapted or unchanged form for any legal and non-commercial purpose as long as the work is attributed to the author in the manner specified by the author or licensor and the work or content is shared also in adapted form only under the conditions of this | |
Identifiers | 10.5446/50575 (DOI) | |
Publisher | ||
Release Date | ||
Language |
Content Metadata
Subject Area | ||
Genre | ||
Abstract |
|
00:00
Programming languageHausdorff dimensionMachine codeComputerSemiconductor memoryNegative numberSingle-precision floating-point formatDifferent (Kate Ryan album)Position operatorSign (mathematics)Stress (mechanics)Computer programmingMoment (mathematics)Video gameLogicObject (grammar)Order (biology)Perspective (visual)SoftwareMultiplication signGame theoryFunctional (mathematics)Disk read-and-write headInstance (computer science)Task (computing)Virtual machineDigital photographyBitSocial classCompass (drafting)Physical systemMetreProgrammer (hardware)Observational studySoftware bugCondition numberGoodness of fitAverageStructural loadConsistencyIdentity managementFreewareContext awarenessProjective planePresentation of a groupTerm (mathematics)Software testingState of matterProgrammschleifeGraph coloringWordProxy serverVariable (mathematics)Computer chessExistenceDirection (geometry)WhiteboardNeuroinformatikMereologyComputer animation
06:46
Right angleClient (computing)Level (video gaming)OvalFrequencyLie groupSerial portErlang distributionComputer programmingRead-only memorySelf-organizationSemiconductor memoryServer (computing)Functional (mathematics)Erlanger ProgrammOpen sourceNumberMechanism designReal numberTask (computing)MereologyBitSerial portWordProgramming languageMultiplication signCross-correlationMachine codeDifferent (Kate Ryan album)Observational studyGroup actionEvent horizonComputer chessSoftware testingPattern languageVideo gameTrailClient (computing)Graph coloringComputer programmingRight angleElement (mathematics)Programmer (hardware)Associative propertyThread (computing)Disk read-and-write headParadoxCASE <Informatik>InformationMixed realityMoment (mathematics)Electronic mailing listRegular graphFlow separation2 (number)Category of beingInsertion lossBit rateCycle (graph theory)Perfect groupComputer animation
13:32
Self-organizationRead-only memoryProgramming languageFrequencyVector potentialOvalChemical equationControl flowDifferent (Kate Ryan album)Physical systemGame controllerObject (grammar)Greatest elementData conversionMathematicsDataflowLevel (video gaming)Client (computing)Computer programmingHypermediaWebsiteMultiplication signFunctional (mathematics)Arithmetic progressionBitProcess (computing)Representation (politics)Server (computing)Semiconductor memoryNetwork operating systemNumberPattern languageData structureWordTerm (mathematics)Machine codeThermal conductivityGroup actionCartesian coordinate systemLimit (category theory)Loop (music)Distribution (mathematics)Programming languageCASE <Informatik>ScalabilityLogicConcurrency (computer science)Expected valueWorkstation <Musikinstrument>Service (economics)InformationVideo gameParallel portModule (mathematics)Electronic program guideNatural languageRight angleFinite-state machineRoboticsBookmark (World Wide Web)Scaling (geometry)Erlanger ProgrammErlang distributionVisual systemGoodness of fit1 (number)CubeCategory of beingStrategy gameCode refactoringFrequencyTask (computing)Computer animation
20:18
Theory of relativityType theoryReading (process)Context awarenessWordObservational studyProgramming languageGraph coloringTheory of relativityPosition operatorComputer animation
20:59
Programming languageLimit (category theory)Computer programmingOperator (mathematics)Digital electronicsCategory of beingObject (grammar)Link (knot theory)Computer fileDirectory serviceNP-hardElement (mathematics)Computer programmingNumberDifferent (Kate Ryan album)String (computer science)CASE <Informatik>AreaDependent and independent variablesProgramming languageComputer programWordProgrammschleifeTerm (mathematics)Control flowStudent's t-testMoment (mathematics)Theory of relativityCondition numberBitTask (computing)Line (geometry)Order (biology)MathematicsSystem callFunctional (mathematics)Service (economics)Multiplication signInsertion lossAdditionMachine codeRadical (chemistry)Variable (mathematics)Game controllerWeightStatement (computer science)Algebraic closureOperator (mathematics)Arithmetic progressionResultantType theoryReading (process)Process (computing)Virtual machineLimit (category theory)Direction (geometry)LogicSheaf (mathematics)Semiconductor memoryProgrammer (hardware)Exception handlingTable (information)ExpressionGoodness of fitSymbol tableRight angleData conversionObject (grammar)Software testingCategory of beingComputer configurationRevision controlNeuroinformatikMonad (category theory)Array data structurePattern languageValidity (statistics)Group actionChainMetreBookmark (World Wide Web)Serial portPairwise comparisonIdentity managementComplete metric spaceSeries (mathematics)Natural numberJava appletPointer (computer programming)Roundness (object)Computer animation
30:33
Identity managementComputer fileWorld Wide Web ConsortiumDirectory serviceInstance (computer science)String (computer science)Operations researchProgramming languageExpressionFluid staticsPhysical systemTelecommunicationPhysical systemImage resolutionComputer programmingCASE <Informatik>PermianInteractive televisionSoftware maintenanceNumberDifferent (Kate Ryan album)Functional (mathematics)Bookmark (World Wide Web)Client (computing)String (computer science)Object (grammar)Link (knot theory)Electronic mailing listOperator (mathematics)Programmer (hardware)DataflowElement (mathematics)outputParameter (computer programming)Endliche ModelltheorieLine (geometry)SpacetimeGreatest elementSoftware testingGroup actionProgramming languageContext awarenessInsertion lossFeedbackBitBit rateView (database)Order (biology)Level (video gaming)Disk read-and-write headMultiplication signExtension (kinesiology)Machine codeSoftware developerAsynchronous Transfer ModeWebsiteEvolutePoint (geometry)Integrated development environmentType theoryPattern languageMoment (mathematics)Identity managementImplementationIterationRandom matrixDigital electronicsLimit (category theory)Gastropod shellState of matterWordRepresentation (politics)MereologyData structureFocus (optics)Flow separationArithmetic meanLibrary (computing)NeuroinformatikMonad (category theory)Default (computer science)Exception handlingIntrusion detection systemProblemorientierte ProgrammierspracheResolvent formalismPointer (computer programming)Computer configurationTask (computing)Keyboard shortcutReal numberComputer animation
40:06
World Wide Web ConsortiumVector spaceComputer fileLengthVelocityAbelian categoryConfiguration spaceTrailCartesian productMathematicsPhysical systemSturm's theoremExpressionProblemorientierte ProgrammierspracheVirtual machineProgramming languageMachine codeGame theoryLocal GroupDecision theoryImage resolutionDataflowCommunications protocolCodierung <Programmierung>Right angleSphereProgramming languageSurfaceField (computer science)Constructor (object-oriented programming)Video gameRule of inferenceGame controllerBitCore dumpLatent heatBookmark (World Wide Web)File formatImplementationProjective planeFunctional (mathematics)Different (Kate Ryan album)Problemorientierte ProgrammierspracheConnected spaceCASE <Informatik>Game theoryMereologyMonad (category theory)Vector spaceVirtual machineMachine codePhysical systemSymbol tableObservational studyFreewareRepresentation (politics)Data structureForm (programming)Matching (graph theory)Electronic mailing listComputer programmingEndliche ModelltheorieMessage passingSource codeSoftwareFunction (mathematics)outputFitness functionProcedural programmingInheritance (object-oriented programming)Distribution (mathematics)Group actionPresentation of a groupSpectrum (functional analysis)Level (video gaming)Fiber (mathematics)Cellular automatonLengthMoment (mathematics)Algebraic closureNP-hardCategory of beingComputer chessLimit (category theory)Workstation <Musikinstrument>Heegaard splittingService-oriented architectureWater vaporInformationReal numberOnline helpStress (mechanics)Semiconductor memoryPoint (geometry)Dressing (medical)Programmer (hardware)OvalRational numberComplex (psychology)AreaCoordinate systemPoisson-KlammerOrder (biology)2 (number)Physical lawElement (mathematics)Computer animation
49:39
Computer animation
Transcript: English(auto-generated)
00:00
Let's go. Thanks for showing up. It's great to see you here. I've really been looking forward to this presentation, because it's been almost ten years in the making. It all started out back in 2004. I embarked on a new project, the project had begun on for a couple of years, and they had developed some new subsystems, and now the only thing
00:23
left was to integrate it. And that's where I joined, and we tried to get system up and running, and the first thing that happened was that it crashed, and it crashed brutally. So the bug was fixed, we made another try, and it crashed again, and again, and again.
00:40
And it went on like that for six months before we finally had to pull the plug and redesign large parts of software to make it work again. So I learned a lot from that project. Most important takeaway for me was that software is somehow different. Software is so complex that we can't just reason about it, it's a really hard thing to do.
01:03
And that led me to leave and start to study psychology. So not as a direct consequence, but anyway. And what I'm trying to do today is to take some of those things that I learned and bring them back into programming. We're going to look at programming from a psychological perspective, because the thing is, we have a lot of bottlenecks in our
01:28
world. The idea is if we know where those bottlenecks are, we can work around them instead of against them. So this is the agenda for today, and let's get started with beauty,
01:43
because beauty surprised me. The thing with beauty is if you take attractive people, we consider attractive people to be not only more social and friendly, but also more intelligent and competent based on appearance alone. It's a scary thought. We're not even consciously
02:04
aware of that. The word isn't fair. But at least it's good news for us here. So the same thing holds true for machines. If you take physical objects, take two machines, identical functionality, one of them looks a little bit nicer. We will automatically
02:22
consider that machine to be more user-friendly, to be better to operate just based on appearance alone. So beauty goes deep. But what is this beauty thing anyway? Let's find out by doing a small experiment. Now, you see some photos here. Your task is to select the face you
02:44
find the most beautiful. If you're like 96% of the population, you have picked a woman in the upper left corner. Here are the bad news if you hope you will ever meet her. She doesn't exist. She's a composite of all the other pictures. And this is a surprising
03:07
thing the researchers found out as they started to, aided by computers, start to morph pictures together. The more pictures they morphed, the more attractive any result became. And that's because as you combine pictures, individual differences disappear.
03:22
That means beauty is nothing more than average. It also means that beauty is a negative concept. Because beauty is not so much defined by what's there. Beauty is defined by what's absent. Beauty is the absence of ugliness. And that's a definition we can use as we program.
03:47
Let's have a look at that. But first, how come that beauty means so much to us? The cost is evolutionary. From an evolutionary perspective, our main objective in life was to find a partner with good genes. Back in the stone age, making a DNA test was tricky.
04:07
Today, it's possible, but it may not be the best idea. Don't try to ask for that on a first date. Promise you, it won't go well. So what we have come to do instead is that we have come to develop beauty as a proxy for good genes. The idea is that if you grew up
04:24
and you could have a face that's symmetrical and average in this mathematical sense, then you probably had a good immune system, you were protected against diseases, things like that that signal good genes. That's why beauty is so important. Computer programs. What's beauty
04:41
in a computer program? It's exactly the same thing. It's the absence of ugliness. And ugliness in a computer program, I would say that's everything that puts an unnecessary load on our brain. Things like explicit conditional logic, explicit loops, inconsistencies, and we get several opportunities to look into that. And we start by our next topic,
05:06
working memory. We humans, we have a lot of different memory systems. Working memory is just one of them, but it's a bit special because it's a short-term memory, and working memory is more like your mental workbench of the brain.
05:22
It's working memory that we use to integrate, manipulate, and reason about things in our head. So working memory, you use it as you solve a Sudoku or do crosswords or even try to understand a C-sharp method. That's working memory. And working memory is vital to us as programmers.
05:42
The problem is it's a strictly limited cognitive resource. There's just so many things I can hold in my head at once. And traditionally, in psychology, it has been said we can only hold several things at a time in our head. The modern research paints an even darker picture. It may be as little as three things at a time, depending on context. Three things in our head?
06:06
Think about the last class you wrote. How many instance variables did you use? It's not a wonder that things go wrong sometimes. Luckily, there are some workarounds we can use and one of them we can learn it by studying chess masters. Chess masters are amazing.
06:26
They can basically stand with their eyes closed and play chess simultaneously with 20 different people and they win the games. And at every single moment, they know the precise position on every single chess board. I can't do that. But try this. Go to one of the chess boards
06:42
and rearrange the pieces. Put them in an order that can never occur naturally during a game. For example, both bishops on the same color. Suddenly, the chess master, they won't perform better than you or me. That means their memory isn't necessarily better. It just works differently. Because what they do, they don't remember individual pieces. They see patterns.
07:07
They remember groups of pieces. And this is a technique called chunking. And I can demonstrate having you do a small test. Now, what will happen is I will present a number of characters to you
07:22
and your task is to remember as many characters as possible, right? Ready? Let's have a go at this. One, two, three. All right. A little bit too fast now. Let's have another try. Ready? One, two,
07:41
three. All right. I guess it was a little bit easier the second time around. And as you probably noticed, it was exactly the same characters that I showed. I just choose to group them differently. I grouped individual characters into words. Words are chunks of characters.
08:02
And each word carries more information. We can still just hold seven things at a time in our head, but now each thing means more. So this is a way to stretch that bottleneck. And this is something we should be aware of when we program. So how can we apply chunking to programming? I would say the most fundamental mechanism that we have, the easiest way,
08:24
is the function. Let's have a look at that. Here's some open source code. And there's no particular reason for using this code. I just wanted a realistic example. I'm not after perfection today. I just want something that we can come around in our everyday work.
08:42
This code here, pretty typical server functionality. It's a Minecraft server, and it rates over a number of clients, and let each client perform a periodic task. And, to me, that's one single concept. That's one chunk. Let's chunk that out.
09:03
Next part of the code, I had to analyse it a bit to actually understand it, but it turned out we're basically just keeping track of the overall play time. And finally, we're keeping track of another time as well. The total refresh time, the time when it's time to refresh all our connected clients, so let's chunk that out too. The details here aren't
09:23
really important. I just want to focus on the overall pattern. And, as I did that, I noticed this little thing here, thread sleep 10. Looks like we didn't get everything right here, but let's leave that for a moment. Perhaps we will come back. Now, I just want to show you what happens if we introduce these chunks. We move from this
09:45
to this. This is code that fits my head. This is so much easier to understand, to reason about, and to improve. So, if you just take away one thing today, this is the most important and
10:00
most simple thing I'm going to tell you. Put name on your things. Name your concept. Your brain is going to thank you. Which quite naturally leads us to our next topic of serial killers. Now, quick, what do serial killers and Erlang programming have in common?
10:23
As far as I know, absolutely nothing. But false serial killers, they are relevant. And this is a guy that's pretty infamous in both Sweden, my native country, and Norway. Thomas Quick. During the 90s, what happened was that he received psychotherapy and during that
10:42
therapy, he started to confess to a lot of brutal killings and murders. And Thomas Quick was convicted for several of those murders, and many years later, it turned out he was innocent. There was no way he could actually have done those brutal things. So, what happened was,
11:01
if you study this case, remember, I'm a psychologist, right, so we like things like that. And what happened was that during that therapy, Thomas Quick, he lied a lot. He loved attention. But there were times where he actually believed his own stories. He had developed what psychologists call a false memory. A false memory, that may sound like a paradox, but it's
11:26
quite common. A false memory is a memory of some event that has never happened, or at least not happened in that way that you remember. That's a false memory. And within psychology, false memories are my specialty. That's what I find most interesting, and that's where I've
11:43
done my research. And if you research false memories, it's tricky to use the same methods as they used in the psychotherapy. Of course, first you have the ethical aspect. If you participate in a study, I don't want you to live and think you're a serial killer. And second, it's time consuming and it's expensive. But what we do instead is this.
12:04
If you participate in a study on false memory, you're likely to be presented with a list of words. It will be words like this, like tired, awake, dead. And after you've seen those words, you will be asked to write down as many as you can remember. Here something interesting happens.
12:21
A lot of people suddenly write down a word that has never been presented. In this case, the word sleep. We have developed a false memory for a word that has never been presented. And this sounds trivial, and that's really the beauty of it, because it's such a simple way to study a complex phenom. It turns out there's a high correlation between
12:41
your performance on this task and your tendency towards false memories in real life. Now, you're probably wondering, how is he going to tie this back to programming? I'm a bit curious too, so let's have a go at that. This is important to programmers because it tells us something about how our memory is organized.
13:04
Our memory is hierarchical. This illusion here, it works due to semantic associations between semantically closed words. Our memory is hierarchical, our memory loves categories, our memory loves to put labels on things. That means if our programs should be easy to remember
13:23
and reason about, we need to categorise our design elements. I've thought about that for a long time because it didn't occur naturally to me. We have functions, classes, some languages have modules. Yes, those may serve as categories but they don't really do the trick to me.
13:45
Then five years ago, I started to learn Erlang. I want to show you that as inspiration. There's been several really good Erlang talks on this conference and I hope there will be some other ones coming up. The thing with Erlang is when you talk about Erlang, you always talk about
14:01
those amazing technical features like concurrency, scalability, fault tolerance, distribution, all those things, but what attracted me to Erlang was the structure of the programs. It turns out that all Erlang programs are structured according to a number of pre-defined patterns. This makes wonder for our ability to reason about Erlang programs. For example,
14:27
here, if you have a look at this, first of all, you notice that Erlang programs are hierarchical, naturally, due to these patterns. At the bottom, you have something called a worker process. Everything virtually is processes in Erlang. A worker process contains application
14:42
logic. Again, if we take our principle of beauty and apply it to a worker process, what is absent? Special cases. A worker process most of the time is a happy-day scenario. If things go wrong, the worker just terminates and leaves the control to a supervisor.
15:01
Now, the supervisor knows one thing. It knows the error-handling strategy. So it decides upon that, okay, what action should I take? Should I restart the worker or should I stop the worker? This makes it much easier to reason about the programs because now, if I want to know where is my error-handling strategy, I immediately have to go to the
15:21
supervisor. Also, these labels, they kind of guide my expectations in the programs and know what to expect as soon as I see a worker or supervisor or state machines or whatever patterns we have in Erlang. So, your brain really loves Erlang.
15:40
When we talk about working memory, we need to mention attention too. Because working memory, it's a conscious mental process, and that means to be consciously aware of something, we need to direct our attention towards it, and attention too is a limited resource.
16:03
In fact, we can only be consciously aware of one thing at a time. And I can show that pretty easily with this object. This kind of cube is something that you will rarely find in the real world. Because this object lacks texture. There's no light, no shadows, and, as a consequence,
16:24
your visual system doesn't get any hints, and we're able to fool the brain. And if you look at that, you're able to see it in two different ways. With some practice, you can learn to switch between those two representations. But no matter how long you practice, you will never be able to see both at the same time.
16:43
It's a fundamental limitation of our brain. We can just be consciously aware of one thing at a time. Or perhaps not. Let's talk about the different kind of attention. Let's talk about cocktail parties.
17:01
Try this out tonight at the party here at the NDC. You meet someone you know, and you strike up a conversation. At the same time, at this party, there may be literally hundreds of different parallel conversations going on, but you manage to shut all of those out because you're focusing on your conversation. That in itself is quite amazing.
17:24
If I now interrupt you and ask you the conversations around you, what have they been about? You probably don't know. You haven't picked up a single word because you're focusing on your conversation. But now, say you stand there, you're chatting, and suddenly someone mentions your name,
17:40
like Adam. Oh, yes. Wow. What just happened there? As soon as somebody mentions your name, your attention is immediately drawn there. And this is true for all information of personal relevance. And the reason for that is, and this is actually one of the few things that Sigmund Freud got
18:00
right. Most of our mental activity is unconscious or automatic as it is called today. That means we constantly have this helpful mental process that scan the surroundings, to scan the environment, and as soon as they detect anything of personal relevance, our attention is immediately drawn there.
18:23
So how can we use that as we program? One thing I've been doing is this. We're back in our server-side code. This is after our refactoring. And I would say it looks quite pretty. Perhaps a little bit too pretty.
18:41
Because if you look into it, we will see that we actually have this. We have a loop there, basically, that's letting each client perform a periodic IO task. But before we get to the loop, we acquire a lock. Now, lock-based concurrency is always a problem. Locks on this level is definitely a problem.
19:03
If for no other reason for scalability and performance, but as I work around with the code, I want to kind of make a mental note to myself. Please revisit this and do something about it soon, but I want to leave it for now. I want to put a mental post-it on it. One way to do it is to deliberately introduce ugliness in our programs.
19:24
Just as we create beauty, we dislike ugliness. Ugliness makes us feel a little bit sick. Let's use that. We take this function and change it to this. We break the flow. We break the expectations. We introduce a small surprise,
19:40
something that draws our attention to where it is needed right now. That was attention. Let's move on to talk about, let's move a bit deeper and talk about language. Language is my favourite topic because language, our natural languages, the languages that we
20:03
speak, they are not just a way for us to express ourselves. The language we speak actually influences how we perceive the word. We can show that by doing a small thought experiment. Please have a look at this deep red beautiful rose. A red rose evokes a lot of positive
20:26
emotions in us. We tie it to things like love, friendship, all these positive thoughts. Picture this. Say that our language would lack a word for the concept of the colour red.
20:42
Without red, would we still consider that rose that beautiful? Would we still couple it with the love and friendship? Perhaps not. That's the principle of linguistic relativity, that the language we speak influences how we perceive the word. The best study I'm aware of that is this one. It's done on aboriginals in Australia.
21:06
In their language, it has this particular way of dealing with directions. All their directions are given as geographic directions. So, if you have a conversation with them, they may say things
21:21
like, hey, Adam, watch out, you have a mosquito on your south-east shoulder. Oh, thanks. It's really practical. But as a consequence of that, they get to practice this and they grow extremely good with orienting themselves. They never get lost like I do. But ask them to perform a task that requires relative directions. For example, setting a round
21:47
table with forks to the left and knives to the right. Suddenly, we perform better. That's a good thing to know that our language is also good for something. This is not really a new idea. This is Mr Ludwig Wittgenstein. He was into this thing too.
22:08
He said that language means the limits of my word, quite dramatic and not true, according to recent research. This is simply a too strong statement. Language may influence our thoughts but they don't in some way control them. Wittgenstein wasn't a particularly good
22:26
computer programmer. I would still claim that this is spot on for many programming languages because I believe that they are a bit different. We have more diversity there. The pioneer in that area was Ken Iverson. Back in the 60s, he designed the programming language
22:46
APL. Just out of curiosity, how many people know APL? Wow! That's cool. Five, six people. APL for Iverson, it was not just a way to instruct a machine. APL to him was a thinking
23:05
tool. To serve efficient, that's a hard word, to be good as a thinking tool, the language needed a compact syntax. That's relevant as we learned about working memory, right?
23:22
How compact is APL? Well, you have a complete APL program here if you look at Donald Duck. And what this program does, it draws a series of lottery numbers, one to 40, no duplicates, and it delivers them sorted in ascending order. It's quite compact, right? How many lines of C
23:46
sharp or Java would you need for that? I really like that. The reason it's that compact is, again, take a principle of beauty and apply it. What's absent? You don't see any control
24:00
structures. You don't see any if-else. You don't have any explicit loops even though it's an iterative process. The reason for that is that APL has arrays as a fundamental data type, so functions are applied to collections of element. By doing that, you erase a vast array of
24:24
something, the code will look the same. This is a powerful idea that we are going to come back to, but first we are making a short distraction into something much more unpleasant. What could probably be worse than serial killers? Well, null. The reason I dislike null is because
24:47
it always means a special case. If you have a look at this string here, the string can reference some text, can reference an empty string. We can have a lot of different strings. But a string can also be something completely different. A string can be null. As soon as
25:04
that string is null, I can forget everything I know about strings. I can forget everything in the whole API. I've introduced a special case. This has been a problem for a long time, and that's one of the reasons that this safe navigation operator has been one of the
25:22
suggested feature additions to C sharp. A friend told me it is going to be included in the next version. It works like this. You can chain property calls together like that, and if all of them are valid, you will get the value of violating the meter.
25:40
That can never be a good thing, but it will work. If some of them is null, the whole thing will simply short circuit, and the tricky variable there becomes null. To me, this is a very elegant solution to the wrong problem. Let's have a look at an alternative solution. Let's look at our server-side code again.
26:07
We have a few cases there where we are deliberately using a null as a valid return value. That means, again, the details aren't that important. I just want to focus on the overall pattern. What we do here is we have a base directory, it might be null, so we have to check
26:22
for that. We have a fine line that might be null. We have to check for that. If everything is okay, we can create a region object and return that. To me, that's a little bit too complex. What I would like to write is this. I just strip out the conditional logic, and, suddenly, this is pretty much easier to reason about. It fits my head better.
26:46
There's one slight disadvantage with this, and that's that it won't work. Because, as soon as something there returns null, the whole thing blows up with a null reference exception. I could, of course, try to catch that exception, but that only makes
27:02
things worse because now, suddenly, I'm introducing an implicit invisible control flow in my program. We have a terribly hard time to reason about that, and it's exactly the same reason that multi-threading is hard. So, what do we want to do instead? Well, let's
27:21
just step back and look at what we have, and where we want to go. We have this code. On the left, we have some symbols, or variables, perhaps they're called. Those variables are bound to the result of computations on the right, and the control flows from top to
27:40
bottom. Now, I would say this. What if, just what if, we had a way to instruct the program how to combine the results from the different lines, how the result from one line should flow into the next one? If we could somehow run code in between each line, then that code could
28:01
check for invalid cases. It could check for null references and take some action. We have a way of doing that, and it's called a monad. Monads are pretty well known in functional programming, most prominently in the Haskell world where monads are used for virtually every interesting task. If you Google monads, you will find we have a whole
28:25
industry writing monad tutorials. We have everything from the formal mathematical definition to comparisons and metaphors like assembly lines and my favourite, burritos. Those are really good and instructive, but I choose to rely on a much simpler definition. This is
28:46
actually my real favourite. This is a monad. A monad has been called a programmable semicolon. Of course, that refers to the common line terminator. You know, if we could somehow
29:01
programme our semicolons, we can tell how the result from this computation should flow into the next one, and, in between, we could do all kinds of crazy stuff. I want to show you how this looks. To do that, I need to switch language. I have to switch to Clojure, but I'm coming back to C-Sharp soon, and you won't ... does anyone know
29:22
Clojure here? Oh, great. For the rest of you, it will be really, really basic Clojure, and I don't really think you need to know anything about the language to follow along. I try to keep it really simple. This is the C-Sharp code, and if we translate that directly into Clojure, it looks like this. Yes, we have a different naming convention,
29:45
but it's basically exactly the same code. We have the only surprising thing here perhaps is this keyword let. Let is just a keyword that allows me to introduce symbols. We have symbols here on the left, and these are bound to computations on the right. Just as in C-Sharp,
30:04
the control flows from top to bottom, and just as in C-Sharp, as soon as something returns null, the whole thing blows up, in this case with a null pointer exception. Now, in Clojure, we have the option of using monads. It's quite a natural solution actually. All we have to do is we take our code here with the let,
30:25
and we replace the let expression with do monad identity M. Do monad is just some syntactic sugar that knows how to apply that monad. The monad itself is this, identity, and identity is
30:49
you give it as an input argument, you get back as a return value. Identity works like that. If you send it a valid value, it will pass that on to the next computation. If you send it null,
31:02
it will pass null on as well, and the whole thing blows up again with the null pointer exception. We moved a step forward. We actually found a way now to run computations between each line here. We find a way to glue them together. So what we can do now is we can change to a different monad. We can change to maybe. And maybe signals an operation that can
31:28
fail. As a consequence, maybe checks its input arguments. If maybe gets something valid, it will pass that on down the pipeline. If it receives null, it will short-circuit the rest of the
31:42
evaluation, and the whole thing returns null. So this actually solves our original problem. But I think the reason I'm showing you this is because if you have a look at these different solutions, you see that all of them have the same structure. All of them look the same.
32:03
And to change the behaviour, to vary that, all we need to do is change one single keyword. Just apply a different monad. And the reason for that is because we have separated the knowledge of computations from the knowledge of how to glue them together, how to bind them together.
32:22
This, my friends, is separations of concerns for real. I think it's very powerful. And if we return to C sharp, you have monads in C sharp too. Link is partly based on them, and you have a lot of really bright people that have been writing monad libraries. I tend to not use them myself because I think it's not quite a natural solution there.
32:44
So what I try to do is I try to take the concept of optional type or maybe type and apply that C sharp but base it on the implementation IDs of APL. So let's have a look at that. Maybe signal something that can fail. In that case, we get nothing. If it succeeds, we get just
33:06
one of some kind of object. And the difference between these two is expressed using a list. That list will contain either zero elements in case of nothing or just one. And we glue everything
33:22
together in order to use it with link. This means that we can take our original code here and change it like this. Instead of returning a string, we're indicating that this operation may fail. We're returning a maybe string. We may get nothing out of that. That allows us to
33:41
rewrite our original code like this. We just chain it together with link, and the nice thing here is as soon as something fails, it returns nothing, which is, remember, on an empty list. And that basically short-circuits the rest of the computations. And as we get to the end there, see at the bottom, we have this first of default,
34:04
and first of default on an empty list will return null. So even though we solved our own problem, we keep pushing nulls upon our client. That's not a nice thing to do. We want to feel a bit better about ourselves. So, of course, what we can do instead is to
34:20
signal that we can fail too. In that case, we return a maybe region. And we can resolve that and adapt that empty list back to a monad by a simple extension method. It's pretty straightforward. We just check if we have something. In that case, we return just one, otherwise, nothing. So let's step back and recap where did this take us? We start out here
34:49
in the midst of special cases, and we transition to this. This is a lot more complex than what I would like it to be. So if I go on that solution or not, it always depends on context.
35:05
If it simplifies the code, I go with that, otherwise not. But no matter what, I would still say it's a little bit better than where we started off, because this code will look the same no matter if something fails or succeeds here. We always have the same flow.
35:22
We have erased the special cases, so it takes a step forward. I just want to show you one way, one case where our exclusive use maybe is to signal operations that can fail. I think we really need that optional type there. This is kind of typical pattern in C sharp.
35:42
You have these try methods when you return true only in that case is our out reference bound to a valid value. I think that's better expressed using a maybe, because now we are raising differences. We get rid of a special case, and we express our intent. If it fails, we get
36:01
nothing. All right. Let's move on to the last part here. Let's leave the monads now, and let's focus on representation and see what I mean by that. I think that, to a large extent,
36:23
programming is problem-solving. How do we humans solve problems? This is one model, and this is my favourite model. It's from educational psychology, and the reason I like it is because I think that we, as programmers, face much the same
36:42
challenges as educators do. We need to communicate knowledge through time and space to the poor maintenance programmer coming after us. This model is based upon two mental models that you have in your head and continuously execute. The first one is called a situation
37:02
model. A situation is everything you know about the problem. You take that knowledge you have, and you express that in a system model. The system model is your solution, your code. The interesting thing with this model is that those two mental views, they co-evolve.
37:23
They grow together. As we start out with an incomplete understanding of the problem, as we try to express it, we get feedback on how well our understanding worked, and we can improve our situation model, which makes us improve our system model. That means programming is always a learning activity. It also means that programming
37:43
is inherently iterative. I'm pretty convinced that we should take this knowledge and adapt it to our environments, to our development environments. How could that look? Well, we have most of those tools already. For example, to grow those models, we need to interact with
38:07
our programmes. Many technologies, like this is Python, and you have the same thing in F Sharp or Closure, you have an interactive prompt where you can interact with your programme and grow it, and let those two models evolve incrementally. In languages like that,
38:25
I've been using tests for a long time, and, of course, this is old news. You can use the tests to incrementally interrogate with your programme. You can grow your two models by tests. And, on a personal note, for a long time, I used to rely on test-driven development,
38:43
but, over the last years, I shifted away from that towards end-to-end tests, because they tend to give me a better overview of the task I'm doing. I think it's more important to focus on what I'm doing from a situation point of view than from a system point of view. But that's just me. Remember Ludwig? Wittgenstein talked about how the language means the limit
39:08
of a word. That comes back now when we talk about problem-solving. Because these two models, as we iterate between them, that iteration gets easier the better aligned those models are.
39:23
The closer they are together, the easier it is to transition between them, and to reason about them. And that means that the challenge for us as programmers is to take our general-purpose low-level programming languages and grow them to the level of the problem.
39:44
How do we do that? And this is where the difference in language plays out, and I'm going to show you that by taking two extremes. Let's start with the bad one. Let's start where you don't want to be. Let's start with brainfuck. Brainfuck, as you know,
40:06
it's a programming language designed to be hard, to be deliberately hard. It's an interesting design goal. And the reason that brainfuck is hard, it's not the cryptic syntax. I mean, every one of you, if you read a bit about brainfuck, you will pick that up in ten minutes.
40:21
It's quite minimalistic, actually. The reason brainfuck is hard is because there's no way to name the concepts. There's no way to introduce chunks. This is all you have and all you get. Of course, that hasn't stopped people from doing really interesting things in brainfuck. This is my favourite. This is a complete implementation of the game of life in brainfuck.
40:49
And even though it's self-documenting to a certain extent, I would still say it's not exactly a perfect match between situation and system model, because
41:02
everything I know about the game of life, I can't see that there. I can't see the rules. So, what can we do instead? Let's transition to the other end of the spectrum. Let's move over back to Clojure and domain-specific languages.
41:21
To follow along now, you actually need to know a little bit about Clojure, so I will give you a 20-second introduction to that. That's virtually all you need to read about domain-specific languages in Clojure. Here we go. We have some simple data structures. We have a list delimited by parenthesis. Within that list, we have three elements.
41:43
We also have a vector. A vector is delimited by the square brackets, and this vector has two symbols in it. Those symbols in turn may reference other data structures. It's not really that important, but what is important is if we step back to the code we used before when we talked about monads, we had this. If we take a close look at that
42:06
with our new Clojure knowledge, we notice that it's wrapped in parenthesis. Within those parenthesis, we have a vector. Clojure is expressed using its own data structures. Clojure is meta-circular. This is a very powerful idea when building DSLs
42:26
because it means I can write programs that take source code as input and modify that just like you would work with any kind of data structure and output something differently that compiles. So, in Clojure, it's quite a natural solution to just grow your language using
42:47
these constructs to the level of the problem, and I would like to leave you with a small case study on that. This is something I worked on a couple of years ago. It's a protocol called Asterix. It's a protocol used in air traffic control. If you want to communicate
43:05
with the radar station, try Asterix. It was quite tricky. It's a binary protocol, very low-level, tricky encoding, and you see two examples here. What we had to do, we needed to write a small diagnostic tool that interpreted those binary dumps
43:26
and delivered something human-readable like this or that. You see it's quite tricky. You have a lot of strange coordinate formats you have to be aware of and fly to points. So we decided in this project to approach it with a DSL, and this is what we did. We
43:44
took the specification, this is our understanding of the problem, the situation model, and you see this is typical Asterix. You have a category, you have different fields with information, each field has a length, and this column here specifies the encoding.
44:04
So we took this specification and we basically put parent pieces around it and made it compile like this. So this is actually the solution. This is how it looks in Clojure, and you see here, the only thing that reveals that it's Clojure is perhaps just the parent pieces and the
44:23
vectors we're using here for each single field. So as Clojure compiles this program, what happens is that it generates a lot of code for us. It generates code for receiving Asterix messages over the network to interpret them, to parse them, and to present them in human-readable form. And this allowed us to grow the support for different languages
44:45
quite fast, because we can take everything we knew about the domain and apply it immediately to our system model. I would say it's not a perfect, but it's a pretty good fit between those two models. Of course, it's an investment to write that, but using the right technologies,
45:01
it's definitely doable. The reward for us is that we can do just as Iverson intended, to move on from instructing a machine to actually expressing a domain. It fits our way of thinking much better. The human brain isn't precise.
45:22
We're almost through now. Just a short recap here. We started with beauty, we learned that beauty is average, and we learned how important it is to us, and we discussed working memory, we learned about chunking, we learned about categories, and attention, we learned we can
45:41
use that as a tool to direct our attention where it's needed, talk about languages, how they influence our thoughts, how they may limit our word, and we learned a little bit about monads and now representation. But before I leave you, I want to tell you a little story about the anatomy of the brain. As you may well know, our brain is actually made
46:08
up of two different parts, two hemispheres. And our mental functions are a bit unevenly distributed. For example, language, it tends to be located in the left side of the brain.
46:21
And those two hemispheres, they communicate by a thick fibre of nerves called the corpus callosum. Now, what do you think would happen if we decide to cut that connection between the brains? We would basically get a person with two small brains within the same head.
46:45
And this is not some kind of crazy Frankenstein idea. It's actually a historical medical procedure that's been performed historically to help epileptics to stop the spread of the disease. And it's also not quite as drastic as it sounds. If you meet some of those patients,
47:07
they're called split brain patients. If you meet a split brain patient, you probably won't notice. But the scientists, they love split brain patients because now they have a way to test the
47:23
differences between the left and right side of the brain. And one typical thing they do is ask the split brain patient to please sit down. They sit down. Then the instructor, right side of the brain, the part without a language centre to please stand up, split brain
47:41
patient rises. Then you ask them, why did you stand up? And now the left side of the brain with the language takes over and answers something like, oh, I got thirsty, so I decided to get a well, you know, my brains, they don't really have a connection between them, so I don't know.
48:06
And what that means to us is that our sense of self, our sense of free will is an illusion. It's the ultimate illusion. Our sense of free will is an after the fact rationalisation.
48:21
And you know where it's located now in the left side of your brain. So, what I want to tell you with that is that as human beings, we have all the right to be sceptical about who we really are. But as programmers, we can really question who writes your code.
48:40
And, of course, the thing I want to take away from that is that this is a vast complex area, and I really just stretched the surface here. There are so many things that are constantly influencing ourselves without us having any idea about it. And in this presentation, I left a lot of things out. For example, I left the whole social psychology stuff out,
49:02
how we communicate, how we solve problems in groups, all those things that really matter on a project. I also ignored all those personal differences and educational aspects for now, but I hope to be talking about that too in a presentation in the future. Until then, thanks a lot for listening to me.