 So, our first talk is going to be presented by two speakers, Michael Schwerber and Nicole Rauch. Michael is the CEO of Active Group. He's been developing software and teaching programming for over 30 years. And Nicole is an independent software developer focusing on domain-driven design and event streaming, and she's been organizing software craftsmanship conferences. So please give them a big round of applause for this talk. Good morning, everyone. This thing is on. Hey, it works. Excellent. Cool. So, soul-crossing code. I think before we say farewell, we should think about what it actually is. And so I thought I'd maybe get a presentation first. There we go. So, okay. So first, maybe we should talk a little bit about what soul-crossing code is. And so I brought something for you, for your entertainment. And here we go. This is some code I found in an eclipse tutorial. If you know a little bit about eclipse, you can see this by looking at this I thing here. Yeah. And this actually, I mean, I have no idea what this does, you know? You have this adapter factory, which is really, like, okay. And then we get an adapter, and there's lots of stuff going on. But what actually is this doing? So there's to-do, okay. This gives a hunch that this might be this famous to-do example. But then I have no idea what's happening here. But maybe that's just eclipse, right? In eclipse, everything is an adapter for everything to do something else. Okay, maybe. So, okay. I had expected you to say something like this. So I thought I'd bring another example. And this actually is from an open source project. And this actually is a native query interpreter initiator. I also want an interpreter initiator. Who doesn't? And also it's a session factory service initiator. Wow. I'm getting impressed. So, and then it also does lots of stuff. And then, okay, we have initiate service. And then we have another initiate service. And then at the end, wow, we have this get service initiated. Wow. Okay. So, fine. But I mean, that's just a bunch of kids doing open source software, right? Yeah, this is open source software. So these are all hobbyists, right? So, I mean, what would you expect from something like that, right? Okay, fair enough. So I brought a professional example. Oh, I see. Okay. So here's a professional example. So this is from a system that does queries of some sort. I think there's a shape and translation from German to French to English in me or somewhere. So you can see that it does either full text search or it does non-full text search or something like that. And so obviously in the initialization of some C++ class, it checks that flag and instantiates some object either to the full text variant or the non-full text variant, right? And you would think this is object oriented and you would find you just go and call methods through that one instance variable that you have there. If an else is so object oriented. Yeah, well, that's just the constructor, right? This is not the bad part. The bad part is that every single method that actually does something like this one looks like this, right? It checks that flag again and it either calls full text recharges, which is, I guess, also has something to do with full text search. You can see that there's lines commented out and nobody remember to leave a comment as to why it's commented out. And you can see that this code is really fragile, right? If you want to maintain that kind of code, every method looks like this. You always need to remember to check that flag before you do anything to be sure that, oh, I'm here or I'm there, okay? Yeah, so I mean, okay, so the fact that somebody uses an object oriented programming language does not necessarily imply they actually understand what object orientation is all about, right? So maybe they are just crappy programmers, okay? Okay. So they happen to use this and then they mess it up on the way, you know? You mean non-crappy programmers can produce crappy code? And now you're getting me confused. I think you have another example. Yes, I have a much better example here. A real object oriented example. So this is finance, right? So here we have options. In this case, just call options. And so the financial guys want to talk about those options, but there are so many different kinds of options so they cannot talk about each of them individually and so they want to group them together in something they call a basket. So up here you can see this basket and it contains Google and Facebook because they are sort of like the same, you know? So they just group them together in this basket and then they want to talk about properties of this basket of all those options that are contained in it. And for example here, they implement this market data and so this is standard object oriented business like everything is a class, right? And there we have two methods in there because that's also standard object oriented business. We have a class and then we have methods in there. And one of the first method, getSpot, just gives us the spot price. So all of these options have a number in the real world and that's why they number this here and for the fun, they call this Sikovam. I have no idea why this seems to be a French word for I don't know what it means but yeah, just go with this. So this maturity thing, that's the date at which point the option expires? Yeah, so that's for the volatility. So you get the volatility for an option. An option is defined by the underlying asset and by the date it's due and also by the price it's supposed to have then. And that's what is encoded here. So we have the option with this long and then we have the maturity which is a point in time so we can properly use a double for this, I think. And then we have the strike which is a price and probably some of you know that it's not a very good idea to deal with money in terms of doubles but on the other hand it's fairly common in banking. So let's do this here as well, okay? Fine, so yeah, that's it. Yeah, and then what they actually want to do, so they don't only want to look at the world as it is but you know those guys with the suspenders, you know, they want to analyze and see what might happen if something would happen, you know. So they want to play what if games. And for this what if game here they take the spot price and they actually want to shift it. So they want to say what if the spot price were different and what would happen then with my options, right? And here they just, you know, so if you want to modify something in object orientation you write a derived class. And this is the derived class, spot shifted market data and this derived class overrides the getSpot method and it takes the value of the parent class and multiplies it with a factor, okay? Sounds straightforward so far. And then of course they don't only want to multiply this with a factor but they also want to do other modifications and they want to be able to do all these modifications without recompiling so they want to play around with these and they don't want to recompile their code every time they change something. So they want to have a dynamically configurable code base. So to speak, or dynamically configurable market data. And if you look this up in the object oriented literature you come up with the decorator pattern. And so the decorator pattern is something that allows you to dynamically modify your code. So you have a component and then you derive a decorator and the decorator is a delegate to something else you want to plug in basically. And this is how they implemented the delegate. So they wrote the decorator as a derived class and then they have their real object in there and for the getSpot method here they just ask the getSpot method of the underlying object, fair enough. And now going back to the baskets where I started out initially so what they did in this one derived modification here they multiplied with a factor and now in the basket they get a bunch of options say or a bunch of assets and now they want to calculate this for all of them and they go into this recursively and it's very hard to see here what actually happens is they go into this recursively and do this modified operation for all of them and because of late binding it happens that they keep getting through this upper method again and again so adding the factor again and again and of course they did not figure this out by looking at the code because like I said really hard to understand and of course this is all just small snippets of the code just the essence but they found this because the values were incorrect and so what they did is they compensated for this and for example here is the most interesting part I think does the first market data derive from the second one so they check whether they have this chain going on and then they do something differently well I mean this is production code right and this is still in operation and probably this method by now is like hundreds of lines long because they had so many edge cases they need to compensate for well yeah I can imagine that but I mean it's obvious they just shouldn't have done this in C++ or using object-oriented programming right so do you have a better suggestion? absolutely we have slides on this people should have used functional programming right which is great because I'm a functional programming person here on stage so functional programming has all these advantages right you can have immutable data immutable data means you have less coupling you don't have these complicated effects going on that you saw earlier maybe functional programming is very close to mathematics so you can apply formal verification isn't that scary? yeah and you can use all these great mathematical things in there you can have catamorphisms you can have bifuncturs that's my new favorite thing monads, monadic profuncturs is also something that we've been using lately that's great there's all these wonderful things in functional programming and they solve all of these problems yes I could why are you laughing? who's laughing? I should have imagined you saying something like this but have you ever considered that you're tackling the problem from the wrong angle? I mean you and your horrid of IT tech nerd you're sitting in your cave hacking away having your hood over your head and just sitting there and hacking and hacking so that problem solved and I mean really just throwing tech at the problem is not a solution it's actually part of the problem but we're producing software we're producing tech right? have you gone through this thing here? there's tech outside everywhere how do you make that? probably not by sitting in the corner and just writing hacking away okay have you considered that there is more to it? that it's not only just tech that you need to talk to each other? mm-hmm yesterday I saw this robot walking around in a circle and it said I need new code please talk to me this is something like this okay so we need to talk to each other it's not only tech tech is nice and everything so do you have a pattern manual for that? a pattern manual yes of course there are talking patterns actually there are people like you so go ahead so educate me okay so I mean there were many approaches over the years right? some approaches were for example looking at agile software development you know and it says individual and interactions over processes and tools tools tech so let's talk together and let's figure out things okay but it does say working software also right? one of four you know says working software because of course we also want working software right? I mean just talking and no coding is also not the answer so anyway so last year we were at this conference right and you were probably talking to somebody but I actually attended the keynote and it was by somebody who talked about what worked and what were the ongoing problems in software engineering and this was an agile company right? they do everything in an agile manner so supposedly they communicate all the time but still when they look at where they spend all of their time and all of their work and effort they say that they still spend 53% on maintenance and complexity and not on new features or I have no idea what that professionalization thing is actually but it takes up 18% looks nice so let's get back to the technical problem shall we? yeah so I mean we already saw this right in the market data example I think much of this maintenance and complexity problems is caused that we are in a world consisting of objects and so everybody jumps on this object-oriented bandwagon right? and what they actually end up with is something like this okay and this is sort of like not helpful so maybe but I would like to explain this maybe in a different way so modern object-oriented programming well you can all laugh at that slide before but we really need to understand the problem right? the technical problem is this right? so at the heart of modern object-oriented programming something called imperative programming where all these objects that you showed on the previous slides they have what's called encapsulated state there's some state in there and what happens is the world progresses by all these objects sending messages to each other and as a result of a message some code gets executed that modifies that encapsulated state now the thing was object-oriented programming was originally developed to support simulations of the real world but the problem is that the real world just does not work like that the real world is not a bunch of objects sending messages to each other so one simple example that maybe can help explain that is there is an speaking of elephants right? yes so there's an elephant and the elephant comes in from the jungle and walks into some kind of room right? and the object-oriented model for this is well all the entities get models get objects so the elephant has an object the jungle has an object and the room has an object that represents them and you have the sequence of method calls or message sense that tries to reproduce that sequence as well the elephant exits the jungle and the elephant enters the room the problem is that the exiting of the jungle and the entering of the room are one and the same act so the real world has dependencies it's not just a bunch of isolated entities that are sending messages to each other but things hang together in the real world so I think a more useful model for thinking about programs and how programs should model the real world has to do with should really go through the way that we perceive things so if you watch a soccer game these days there's lots of objects that you see right? so you see 22 players maybe you see a ball, you see the referees and you see lots of people in the audience now so they all change their internal state if that's the model that you use now if you want to know what's going on in the football field you need to observe all of these changes but do you know what the object-oriented model is for observing changes? something called the observer pattern which means that you register each of these objects and tell them well if anything changes with you send me a message do your ball, send me a message if you move you do that with all the players all the 20,000 audience members and so and of course when you leave the stadium you all send the messages oh no I'm no longer interested in what you're doing the world doesn't work like that it has another problem is that all these messages will arrive in some sort of sequential order and that also would mean that with all of these objects moving around we would observe inconsistencies all the time the same way that we observed it the elephants going into the room if you remember there was an inconsistent state in the middle here which was that after the first step the elephant is for a brief amount of time is nowhere, it has exited the jungle but it has not entered the room yet and the same is true of course if we have many moving objects but yet we never observe like one person getting up and suddenly appearing in another place appearing in the same place at the same time and that's because our perceptive apparatus creates consistent snapshots of what we observe we look at something and it gets stored in memory and we can think about it for a little amount of time and analyze what's going on and of course we remember things that were in the past which is also something that an object-oriented model cannot do so I think there's fundamental problems with this object-oriented model of programming and that's one of the fundamental things that leads to that soul-crushing code that we've been talking about that actually reminds me of a very interesting thing that lots of people are using and that's in the UI and it's called the MVC pattern or model-view controller and if you have ever worked with this you can see here that this all goes in circles and you can go in any direction and then you end up here again or you go this way around or follow this dashed line and so you can go from anywhere to everywhere and this leads to the obvious problem that if you have changes in the model and changes in the view they need to hopefully be corresponding or maybe not and what do you do about this so what you end up with if you do this enough and if you aren't very very careful you end up with this Certainly my MVC programs have always looked like that Yes, Sao feels really familiar doesn't it? And I think that's also what Alan Kay was talking about back in the day so this is a quote from 1996 but I think the paper just appeared then but the original quote is much older he said OK, OOP had those motivations that we described here but eventually we need to overcome this model and we need to find something better and eliminate it altogether is what he says here But that never happened right? No I don't think so So if these days if you look for examples of how object-oriented programming works it always is about encapsulated state that Alan Kay wanted to get rid of so I think that's the first thing when I searched for object-oriented examples was something with students and you can immediately see that a lot of attributes that you have there go through some method that modifies them My favorite one is that you have the student and you can set the grade point average of the student so if you're not happy with the grades that your kid is getting get a perfect GPA there and let me reiterate Nicole, of course people should have used functional programming which has all these simple languages less complexity, higher productivity, less bugs we have all these powerful type systems we can do property-based testing we can do, well it goes on and on we get more predictable behavior generally testing is easier because we don't set up and tear down methods you get lower couplings you have fewer dependency cycles you can say monad here in this list so you get all these concrete advantages from doing functional programming so that's what people should do to solve those problems Do you remember Fred Brooks? He said, there is no silver bullet What do you say about that? Fred Brooks is an old guy, right? Yes And what about you? Yeah, I guess I am too I'm getting there Yeah, well so Fred Brooks said that but he's an old guy so let me get you one example of why that maybe is not true so in the early 90s actually there was a big study conducted by the US Navy on the effectiveness of different programming languages and they had one set problem that was about determining the regions of influence of warships and they had different teams write solutions for their problem in different languages and what they ended up doing is also they gave that also to people who were using functional programming specifically in the Haskell programming language which was still pretty young back then and you can see, well the solution in Haskell is much shorter than the solution C++ definitely less than 10 times as short than the C++ solution I think Java wasn't as big then but there would also be around between 3 and 10 somewhere also what's maybe interesting is that there are two Haskell solutions one at the top and one at the bottom Probably they just split the code so the numbers look nice Yeah, you would need to add them up, that would be interesting but what they did is they had they had a Haskell expert write a solution and then they also gave the solution to a student I think who learned Haskell for two or three weeks and who also wrote a solution and if you look at development time so somebody took 10 hours and somebody took 8 hours and the 8 hours is the student that's because the Haskell expert tried to put many interesting flourishes and super cool programming techniques into the program but the student was actually doing pretty well so if that's not what a silver bullet looks like, I don't know what would So the Yale study, right? They got a fixed set of instructions and they just had to code those instructions Do I remember that correctly? Okay, so do you ever experience that in the real world getting a fixed set of instructions from your client and then just implementing this and they never changed their mind they never come up with new ideas they never like say oh, I forgot something I actually don't experience this Let me think about it maybe you can So that's what we need to consider as well coming back to the elephant right? talking to each other Everybody has different ideas Now you guys start with that agile stuff again Everybody has different ideas when they look at something and everybody describes things differently and so what we need to do is to figure this out together coding a bit, talking a bit talking a bit, coding a bit and so this needs to go hand in hand and this is sort of agile agile doesn't mean scrum and standing in a circle every day or something, relax So personally I like to communicate with code So that makes me think of an example that we were working on a project that was in a semiconductor factory so this was serious business anyway so when we started this, I don't know you all know this, right? when we started this, I thought, well a semiconductor the way it gets made, there's a big machine you put in a piece of silicone and you go like this and junk and out comes a microprocessor and it doesn't really work that way one of the reasons is just that a modern chip consists of many layers another one is that there's just many different production steps that are necessary for making even a single layer and some of the machines that make a layer are so expensive that you can't just make an assembly line and also a lot of things break all the time in a semiconductor factory so it makes no sense to just have an assembly line and push things through that but things just move around among the different machines in a semiconductor factory right? so that each chip or each wafer undergoes a sequence of steps in the factory and that needs to be managed and those steps, it's typically for big microprocessors that might be like a thousand steps so you need to manage something that's called a route which is just a sequence of operations and now here's a bunch of Haskell code Haskell code is great because the programs are so short that they fit on slides but if there's something unclear about that code then I invite you to interrupt me and ask so first of all you can read that declaration at the beginning says data operation and that's just a simplified data type that describes what an operation would be and it says you can read that vertical bar as or so it says an operation is either track in or process or track out and tracking in just means putting a wafer into a machine and processes you do something inside the machine and you take it out of the machine okay and then the next thing is that a route is just a sequence of operations and these brackets that you see there they mean list off so what it says is a route is a list of operations and down here you have an example for a route for a very simple route that says well one route, route number one might be a list of the following operations you put a wafer into a machine you process it, you process it some more you process it again there so far? everybody nod? everybody who's still awake nod? okay so don't be afraid to ask so one thing that you do is when you have data types as you just saw is you define functions on them that describe some aspect of what happens in a FAB in a semiconductor factory so in a FAB what happens of course is you need to execute the next step of the operation that happens as part of making a semiconductor and for that we're making a function called route head and what you do is you write a type signature and type signatures are very good for communication actually so you put in a route and you get out a single operation and then you write equations that describe what that function would do on different aspects or different classes of input so in this case route was a list of operations and lists there are two different kinds of lists one type of list is the empty list and the other kind of list is a list that has what's called a head or a first element and a rest and because there's two kinds of lists you write two equations and so that's why you see two things where it says route had something equals to something else and the first equation is for the empty list this is why you have these two empty brackets and the second one that says well it's a non-empty list and the first thing in that list is some operation op so this is something called pattern matching you match this onto the actual list that you see and op then gets bound to that first operation and we don't really care about what comes after that first operation and so the second equation is pretty clear if you want the head of a route that is not empty you just take the first element of that list okay so far and the other equation says well what do we do with an empty list right an empty list does not have an operation so you're saying you're into the second slide of your beautiful Haskell code and you already don't know what to write there well so we're communicating right okay okay so you're talking you're talking to some of the expert and you say well you have got an empty route what's the first operation of an empty route and he says well empty routes they don't really have a first operation maybe have an operation and sometimes they don't so for that we can create a data type that says that something might sometimes be there and sometimes it's not and we'll just call it option are there any Haskell programmers in this room oh okay so this is built in of course as the maybe type but I'm just making a separate type called the option type and that says well the a says it can be anything right anything an option a means it can either be there or not and for that it has two constructors or two different classes of maybe objects and one are called the some objects and the other one are called the none objects maybe we'll start with none so anything can be a none it just says that anything is not there right so anything can be of type option of a and it means it's that something is not there and that is the type of that particular constructor the other constructor says well that thing actually is there and so the constructor has to accept something of type a and then give us something of type option of a okay so you're saying it wraps this object yeah it wraps the object okay and so if you're not a Haskell programmer but maybe maybe an F sharp programmer or an ML programmer then that is what it looks like there and I believe it's even built into Java these days something called optional yeah so and now that means we can change our Roudhead function a little bit because it doesn't work out and instead of saying route arrow operation we write route arrow option operation may seem trivial to you but it already communicates a tiny little bit of something so and then we can write Roudhead of the empty list as none so there's no there's no head of the empty route or if we have an operation coming out we just write some in front and so if we use that example route that you saw earlier where R1 was process process track out what we get is sum track in okay so that type communicates a little bit of what we do because always it's already calling the shots very good the next thing that we might want to do is we don't want to always know only the first operation we also want to know what happens after that so we can use that option and we already know that of course an empty route will not have something coming after that first operation so we could write another function called route advanced and it takes a route as input that's to the left of the arrow and it gives us both an operation and a route that's why there's these two things in parentheses with a comma in between so that's a tuple so it gives us an operation in a route but only sometimes when that actually exists which is why there's an option wrapped around that so what we want to do is if we take our route number one we want to split it into that first operation in a list of the rest so it should split out the track in and then give us a list of the remaining or a route of the remaining operations that are in there okay so far so it gets technical don't be does anybody have a question okay so don't hesitate to ask I'm looking at the clock ah so and then this is actually pretty easy to write now again we need to make two equations because a route is a list and lists always need two equations so we can say route advanced at the empty list none and route advanced of up and the rest is we just return a sum of up and the rest because the list already splits exactly along the line that we wanted to between the first and the remaining elements right so this is just very simple code or at least a short code that communicates what routes are right I see and so if I remember correctly I mean you said you put the wafer into the machine and then it processes it if I remember correctly some of these processing steps can be chemical reactions or something and so it might be the case that they must happen in a certain amount of time or something is that true okay so what we could actually do is we could model something like this yeah I sneaked at your part of the slide so I chucked this in so what we actually could do is we could model something like those three steps here need to happen together in a set period of time so the chemical reactions mean that your wafer might go bad if you start the sequence of steps and you don't finish on time then your wafer goes bad like etching and washing for example if you etch too much then that's always a problem in existing systems oh is it okay so cool so maybe I can try and see how I can model this into your existing code okay cool so let's have a look so what we first need is we have this route element here with this operation right and now we need another representation for a route element and let's call this route QT zone for Q time zone and there of course we have the duration that means the amount of time this step needs to be finished in or this sequence of steps needs to be finished in and then we have this list of operations here we saw this before right the list of the operations and then what this gives us is of course again a route element so we can combine like ordinary steps like putting the wafer into the machine doesn't matter how long it takes maybe it blocks the machine but other than that no issues come from that but if we do the etching and the washing for example we would need to have a Q time zone because we need to restrict the time that this takes in conjunction right is that correct so far yeah good and then if we look at our example this is the previous example we had here we could create another example where is my there and here we have a route Q time zone say it may only take five whatever seconds say and then we have two processes here that need to be finished within five seconds and then we do the track out again okay so far so clear good and then if we look at this and we discover that here we have this route element list and here we have this operation list this is actually sort of similar isn't it so maybe we can make something out of this and maybe we can actually turn this down here into route elements as well oh so that's what you were doing before right before there it's set up there it also set list of operation up there yeah up there when it said type route when you started my code my code had route equals list of operation right and now you did the same thing oh yes yeah right so now it's now it's the same okay again right so it's both route route elements yeah good point and now if we look at this again so maybe this actually means that this year is not just a list of route elements but maybe this is actually a list of routes it's actually a route down there so actually derive some some information here from the code so we discover that our route queue time zone actually contains a route so what are right so if we look at this here what we then can do here with this route element so here we could plug in any route element right for example we could plug in a route queue time zone which is also a route element so coming from this example here where we have just a flat list that just contains some route operations and a route queue time zone and then a route operation we could also stack them into each other so a route queue time zone could again contain a route that contains a route queue time zone that's pretty cool do you think that would happen in this pre-reality now we can nest queue time zones and that's something that occurs in reality and so your model has suggested that but it's something that our old IT systems based on object oriented programming couldn't model that's pretty neat now I understand why you're aiming at functional programming and saying that you can model things better with it and this is pretty cool so we discovered this in the code and then we were able to get back to the business people and check back with them whether they would actually see this in practice and whether it's a valuable addition here and we discovered that just from looking at the type information and then we can continue this and because now we have this list of route elements down there we could actually say oh yeah a list of route elements we know what that is this is actually a route and now we like go one level up so whenever we learn more about routes or whenever we change this here this route thing it will automatically be reflected in here because we abstracted it and that's what functional programming is all about abstracting things and figuring out what the common parts are right? I noticed you're agreeing with me very good excellent so and now we can also of course check how our functions will be modified because now we need to go to all of our functions and see whether they still work and here we have this route head and also route element head and now we need to extend this because the route element head works on the route element and now we have a new route element which is the route queue time zone and of course if we want the route element head of the queue time zone this is of course the head of the containing route and we have this neat function up here already route head which gives us the head of the route and so we can just reuse this here so even this has become simpler for us to implement because we have discovered that there is a route in there instead of just a list so no special handling we can just revert to the function we already have and if we look at the route advance so if we want to proceed our route to the next operation and you know proceed to the next step then of course we also need to add this here the queue time zone and now the question is what happens if we advance into a queue time zone process because somehow we need to keep track of when does it need to be finished so initially we said it may only take X time or D time and now we need to keep track of whether this time is already taken up or not and so in this case what we actually do is we need to add another route element and that's a route queue time limit which defines when a started operation needs to be finished so it has an actual time which is the point in time like now duration or something just the finishing point in time and then it's just the same as the queue time zone so this limits this end point of time and now we can implement our route advance because whenever we have a queue time zone that's where we didn't know what to write before so whenever we advance this route then we know that we need to come up with a route queue time limit here and whenever we have this queue time limit and we advance over that one we know that we just need to basically behave like before we need to split this up and also keep our time limit of course and then just proceed into this limited while keeping the time limit and here if we start this out then we need to determine the end point so we take the current time which we now need to pass in here at the top we take the current time add the duration and then we know when we need to be finished with this process and then in here yeah we just work on every step while keeping the time limit so your code suggested that there was a gap in your understanding of what needs to be represented right yeah so I didn't know what to implement for the route advance and now I know that so watching this I'm thinking that there's still a little if I look at it with the eye of a domain person I think there's still a little problem in there which is yeah if you look at this remember a route element is something that can occur anywhere in the middle of the beginning at the end of a route so it has these three things obviously we can have queue time zones anywhere we can have operations anywhere but the thing is we can only enter a queue time zone at the beginning right oh I see so you mean here we could have a random list in a random order yeah that's a good point actually so this suggests that the queue time zone has been entered because there's a route queue time limit but there's still an operation there in front of it okay yeah that doesn't make sense yeah that makes no sense so if we could go back from the domain knowledge to the code now a little bit we could refine that type further and we could pull out the queue time limit from that type down there because these are all the things that occur in the middle of a route and pull it up to a top level type and introduce an intermediate type that distinguishes between what's in the middle and what's at the beginning oh I see that's neat so what we now have is we have this back and forth between the code which yields insights about the domain and the domain and from the domain back to the code and we can play that game that's what I intended that's what I intended did you understand this yeah so that code no longer crushes my soul excellent yeah same here cool okay so that's what the point we wanted to make so if you take functional programming and if you add communication and discussions and this going back and forth and learning from both sides switching both sides with the information coming from the other part then you actually end up at a silver bullet everybody's looking confused that's a bullet train a silver bullet train okay we're done yes thank you thank you for a very entertaining talk we have some time for questions Q&A so if you have any questions please line up next to the microphones we have four microphones across the room and we'll start from a question from the internet so here is the question from the internet as an FP beginner with a weak background in math would it be preferable to learn functional programming in pure functional language over languages they are multi paradigm so I think the point is there's many different functional programming languages and haskell happens to be what's called a pure one but there are also languages that are hybrid between object oriented and functional programming scala I think is the prime example right now and scala is a fine language the problem is if you want to combine these two paradigms you typically get something that's pretty complicated so scala is a complicated language that takes more time to master also because you have both paradigms available to you at both times at all times you often get confused about what paradigm you should use in a given situation so I think both of us we haven't really seen the great advantages you get from that hybrid model also the problem is if you're a learner in FP and you try to tackle this with something scala you will inevitably fall back to what you know if you run into problems and so maybe just jump into the deep end and try to swim and see where you get that and get help on the internet yeah number two it was a good presentation thank you every time I see some functional programming it's refreshing and it's interesting but the presentation was talking about using functional programming in IoT so there was nothing specific to IoT in this presentation there was no interaction with the hardware no interrupt handling no nothing how do you handle that for example yeah good point I think we had a bunch of slides on that that we ended up dropping because of time but so my argument would be that IoT the software is the same software as any other software what's special about IoT is the risk that emanates from IoT obviously so if you do things like so if you want to do things like interrupt handling I think my response to that would be to convert it into functional data structures and this gives you a deterministic model for handling that kind of stuff so we talked about that I think we talked a little bit about the observer pattern which is analogous to what usually happens with interrupt handling which is what you were talking about and the way to do that really is to have of course you have a tiny bit of imperative code that hooks your functional code to the hardware or whatever it is but to convert your interrupts into a list and you can ask actually it's pretty good at that and that gives you all the advantages of functional programming, the testability the funky abstractions and you can use that on the interrupts and it turns into software just like any other functional software Microphone number one Hi, thank you for your talk I have to write code for microprocessors and most of the time I only have a C compiler and if I'm lucky I get a C++ compiler where can I get a silver bullet The old Haskell compiler used to compile to C and nowadays it doesn't do that anymore by default but probably you can make it do that I'm sure you can still do that but there's a number of functional languages that compile to C so it's kind of difficult to give a one shot answer we've also done a project for example where we get a lot of the advantages from functional programming by writing code in Haskell that generates the C code it's difficult to give you one answer without knowing more details about what it is that you're doing but there's certainly a spectrum of options available in that context So functional programming is pretty concise and pretty compact so no one really wants to use large variable names and I saw in your examples like a D and a T, T, L or T and I don't think that they're so much better than the long versions you showed earlier what is your take on that? I'm also struggling a little bit with this one thing is that this was fairly concrete code but often you go into the abstractions and in the abstraction it's arbitrary what you have so you can use short names because you're not talking about concrete things anyway so that's why it's easier to use abstract variable names but what I actually do is I also use longer names so I would not always use D and R, T and something like that to get a better grip on this but one important thing you must not forget is that this you have a function of three lines and so if you start out and you understand D and R, T for example from the signature and reading three lines of code with a D and R, T in it it's not that bad and in object oriented or Java or whatever you sometimes have hundreds of lines and then you have a D and R, T and you read this for half an hour and then of course you forget what it means so I would use longer names as well probably but sometimes also shorter because just the code is so short one detail is I find myself using longer names in dynamically type languages they're dynamically type functional languages and there you don't have the type that spells out what that thing is and then you need to put it in the variable name in one of the slides you made the claim that a functional programming lends itself to proving how would you actually do this? Good question That's another talk right? So there's various ways of doing that so first of all as you saw Haskell program is a bunch of equations so you can use algebra as a mathematical technique to reason about functional programs so first of all going to the abstract aspect of that question which is something well you can sort of do it with your Java program but it is much harder to establish an algebraic way of talking about Java programs there's also plenty of tooling available to write to prove aspects of your programs in functional languages starting with a classic tool called ACL2 we can talk on something called Idris so there's a newer breed of functional languages where you can put more proofs into the types of your languages so it just turns out it tends to be just a magnitude an order of magnitude easier to prove properties of functional programming because you can use algebra and equation reasoning as you would about Java programs does that answer your question a little bit? A bit but I think Idris uses like dependent types and doesn't isn't it possible to use it in imperative programming as well maybe I don't know So is that specific to functional programming dependent types could it be used in even the way that Idris talks about imperative programming is functional using monads by the way so there is that and there's this whole spiel about reasoning about effects but the thing is side effects you have an imperative programming they don't make it impossible to reason about programs but they make it much much harder so in a functional program in a proper functional program you tend to have large parts that are purely functional and that allow functional that allow equation reasoning and you have smaller parts that maybe that might be a little bit more difficult that are about the interaction with the imperative environment Also the thing that we did with a type system you remember first we had the list and we had the the Q time limit in the middle and that was an illegal state and so we changed the type system to disallow this and so actually already the compiler tells us hey this is forbidden code and it's not syntactically wrong but it's semantically wrong and that's what is also like a weak kind of validation or verification in my opinion So we could talk about this all day sorry Another question from microphone number 2 I noticed that you didn't present any mechanism to hide your implementation or to make things private that things that you can do in C++ and I don't miss those mechanism but I would like to know your take on why I think you don't miss them so why do you don't miss them either No they exist in functional languages as well right and so the mechanisms that you're familiar with private things modules functional languages tend to not use objects and classes for modularization I think that's the primary difference but functional languages tend to always have mechanisms for doing that they just differ between languages so it's difficult to talk about this in a talk we could have told you how to do this in Askel and write a module and hide things but would have put more codes on the slides And the other aspect is that you don't really have to hide things because everything is pure so if you call this function I don't care you can't destroy anything whereas in object oriented programming you have this change my object to really bad something and you don't want anybody else to call this because it will really break things and in functional programming check in some variables get something out do this as much as you want I don't care That last one is the take I love I endorse fully Microphone number 3 You had some slides on the importance of communication I have a hard time to see myself communicating with business people using Haskell code how would you what would you do about this code how would you do the communication with like normal people I mean we we clean it up someone but this actually happened it's sometimes it's sometimes a little bit of a process to get there and sometimes what you notice maybe in the code with the routes was that playing with the Haskell code yielded domain insights that you could have also explained to somebody in a meeting right without showing the code so the communication goes through the Haskell code by the Haskell code but all I can tell you is that that actually happens we sometimes communicate with clients showing them code and talking to them about is this really what you're doing is this what your domain is like that happens it depends on your clients they need to have a bit of resilience so they can they can accept that they wouldn't understand everything but if you talk them through and say here's this and this goes in and that comes out and what do you think about this and then so you just not throw the code at them but you have informed communication this can also be contractually enforced and I remember one instance where we did that and a big round of applause for this talk