Domain Driven Design with the F# type System
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
Wlaschin, Scott
Statically typed functional programming languages like F# encourage a very different way of thinking about types. The type system is your friend, not an annoyance, and can be used in many ways that might not be familiar to OO programmers. Types can be used to represent the domain in a fine-grained, self documenting way. And in many cases, types can even be used to encode business rules so that you literally cannot create incorrect code. You can then use the static type checking almost as an instant unit test — making sure that your code is correct at compile time. In this talk, we'll look at some of the ways you can use types as part of a domain driven design process, with some simple real world examples in F#. No jargon, no maths, and no prior F# experience necessary.
 Okay. Can everyone hear me okay? Up all the way at the back. Can you hear me? Yeah. Yeah. Okay. Good. Right. So this talk is domain driven design or domain modeling with the F-sharp type system. It's not really, I'm not going to go through a lot of domain driven design. It's more about how can you construct a domain model with the F-sharp type system. So I'm going to be explaining about algebraic types and how you can use that for designing. So a little bit of domain design, but mostly about the F-sharp type system and algebraic types. So hopefully that's what you're interested in. So I'm going to start with a challenge here. How many things are wrong with this design that you see on the screen? So you probably have seen this kind of code, millions of times. It's a very simple contact or a person. There's a first name, middle initial, last name, an email address, and a flag to say whether the email address has been verified by sending the contact to an email to verify. So you might think, well, I'm not going to say it's about syntax. I'm actually talking about from a design point of view, how many things are wrong with this code? And I think you'll find there's quite a number of things wrong. Hopefully I'll surprise you with some of the things that I'll say. So before we start on that, though, let me just talk about the software development process. And just like any process, there's an input, and there's the process, and then there's the output. And one of the things that we do in conferences like this is we normally talk about the process, which is the coding and the testing and the tooling and continuous integration and continuous deployment and all these things. I think one of the problems with that is there's this well-known truism, which is if you have garbage in, you get garbage out. So we tend to focus on the process, but really what we should do is focus on having less garbage coming into the process in the first place. So what I'd like to do in this talk is really focus on reducing the amount of garbage that comes in and then hopefully that reduces the amount of garbage that comes out. So reducing the amount of garbage that goes in is really the design process. So if you have a good design process, you can actually guarantee good output. If you have a bad design process, all the best tools in the world will not necessarily guarantee a good output, or at least there's a lot of extra effort to guarantee that extra good output. So that's what this talk is about. How can we have good design and how can the language that you use help you with that design? And I think that F-sharp is actually an excellent language for design purposes, not for coding, for design. So here is our contact again, and I propose to you that this is actually a very garbage-riddled design. If you use this design, you might have lots of errors in your code that would be completely preventable if you use the different design. So the first question of this design, one of the reasons why this is not a good design, is it's not very clear which values are optional. So the middle initial probably is going to be an optional property or an optional field. The first name might be required, the last name might be required, the email address might be required. It's not clear from this design. So when it comes time to coding, you won't actually know. So there's going to be a communication gap straight away between coding and the design. Now you might code it so it's optional, but that's going to be buried in your code. And when someone else comes along, they're going to have to look at your code to find out whether it's optional or not. So in this case, the middle initial is optional. It'd be nice if we could somehow put that optionality into the design itself. What about the constraints? So if we take the first name, it says it's a string. So does that mean you can put two billion characters into the first name? Can you have line feeds in the first name? There are constraints on the first name, which a string does not represent. Now again, you probably have some validation logic in your code, but that's in the code. Can we actually represent that in the design? So in this case, the string is not allowed to be more than, say, 50 characters. What about which fields are linked together? So what I mean by that is in terms of concurrency, I can, if one person updates the first name and another person updates the last name at the same time, that's going to be a concurrency error. But if one person updates the first name and someone else updates the email, that might not be a concurrency error. Is there a way of communicating that through this design? In this case, it's pretty obvious that the name part is separate from the email part. And finally, what's the domain logic? So we have this isEmailVerify flag. That means I sent you an email and you clicked on it, so I know that you actually are the owner of that email. But where is that logic in this design? I mean, that's just a boolean. Anybody could set it to true or false. I mean, I've called it something, but the logic is not encoded in the design. So in this case, the logic is that if the email is changed, I have to reset it to false. If you change your email, I have to re-verify you. So here's all the questions again. Which value is optional? What are the constraints? Which fields are linked? And what's the domain logic? And I think that F-sharp can actually help with all of these questions. So domain modeling in the F-sharp type system. My name's Scott Voloshin. My Twitter handle is Scott Voloshin, very cleverly. I have a website called fsharpforfunandprofit.com. And I have a consulting company called FP Bridge. And if you want these slides, if you go to fsharpforfunandprofit.com, the slides will be there and some other links will be there too. And I'll post the video there too when it's ready. Right, so domain-driven design. Hopefully, how many people have read domain-driven design? Most of you? Yeah. So the main quote really from domain design is you focus on the domain and the domain logic rather than on the technology. So you're trying to capture something in a way that anybody can understand. It's any business person can understand it. It's not about writing it in code. It's not about using clever technologies. It's about communication really. So domain modeling and DDD is a quite big topic. Functional programming is another quite big topic. This talk is really going to be on the overlap of those two things. It's not a particularly common area, but I think it's actually a quite profound thing to talk about. So first of all, I'm going to spend a little bit time demystifying functional programming because I think a lot of people are kind of scared. So I just want to take away some of that fear. I want to talk about functional programming is actually a useful thing for real world applications. It's not just some academic theoretical thing. I'm going to compare F sharp and C sharp. How many people use C sharp here? Everybody, right. And I'm going to then talk about the F sharp type system. And then I'm finally going to talk about how you use the F sharp type system to design real things, really practical things. So let's start with demystifying functional programming. Why is it so hard? I think a lot of people are put off by it because it's very scary. You have all these words like functor and catamorphism, currying and monad. These are very scary sounding words. And I think the reason is, yeah, there's Homer, he's quite scared. The reason is because the mathematicians got there first and they named these words. Now, if we renamed the words differently, they wouldn't be so scary. So for example, I think these words are just unfamiliar. Not scary. So if we named things like functor, if we called it mappable instead of functor, and if we called it collapsible instead of catamorphism, we said aggregatable or chainable. So those are still words you might not understand what they mean, but they don't sound so scary. So here's Homer. I mean, he doesn't understand them, but he's not frightened by them anymore. It just means it's something you have to learn, just like you have to learn entity framework, or you have to learn the link, or you have to learn WCF, if anyone knows how to do that. So I tell you what, it's really scary, it's object-oriented programming. You just don't think it's scary because you already know it. But if you're a new person coming to programming and you're faced with object-oriented programming, this is what you have to deal with. You have to deal with all these scary words, like polymorphism and inheritance and interface and generics and covariance and countervariance and solid. And solid itself is five different things, SRP, OCP. No, there's a lot of things you have to remember. Each one of those abbreviations, and you've got IOC and DI and ABC and MVC and AOP and thousands of little things you have to know. So that's really scary. So functional programming is actually a lot less complicated than object-oriented programming. It's just that you're more familiar with object-oriented programming. The other thing about all these words is you're not going to need it for this talk, so I'm not even going to talk about any of them. All right, so don't worry that I'm going to be mentioning them. So let's talk about functional programming for real-world applications. So you've probably heard that function programming is good for mathematical stuff and it's good for complicated algorithms and it's really good for parallel processing, but you need a PhD in computer science to understand it. So the first three things are actually true. It is good for all of those things. It's so not true that you need a PhD. I'll tell you what, I think functional programming is really good for. It's really good for boring line of business applications, blobbers, I call them. So I think how many people make their living writing blobbers? Yeah, pretty much everyone writes boring line of business applications. So that's e-commerce websites and accounting packages and ETL data warehouses and I don't know, all sorts of stuff, back-end infrastructure, whatever. So that's basically what we do every day. But I think functional programming is actually really good for that. So let me tell you why. If you're going to be doing Blobber developments, first of all, you need to express requirements very clearly because you're working with customers and sometimes they don't quite know what they're talking about. You need to have really good communication. Secondly, you need to have a rapid development cycle because you want to get the code out there before the customers change their mind, which they probably will next month or next week. So if you can have a rapid development cycle, then you can actually get the code to live them and then they're happy. And finally, you need high quality because there's nothing worse than trying to fix a bug for something you did six months ago. You want to be working on new stuff. You don't want to be fixing old stuff. And then you look stupid if you have bugs as well. So what's interesting is that all these requirements are actually is where the agile movement came out of, XP came out of Chrysler. The whole thing of expressing requirements clearly, that's behavior-driven design and customer-on-site customer and all this kind of stuff, rapid iterations. F-sharp is good for that because it's concise and it's really easy to communicate. So it's actually better than C-sharp for that. The rapid development cycle, again, that's where you have your continuous integration and your continuous deployment. F-sharp is good for that. It has a REPL where you can actually code interactively. And it has many, many convenience to avoid boilerplate in your code. So you can actually churn out a lot of code much faster in F-sharp. And finally, the high quality deliverables, of course, you have your unit tests and so on. And in F-sharp, you can do unit tests as well, just because it's a.NET language. You can use N unit. But the type system can actually be used to ensure correctness at the design time. And that sounds, you can actually encode business logic into the types. That sounds like a very strange thing to be able to do, but you can actually do it. There's one other thing which is really important. If you're doing boring business applications, you need to have a bit of fun, OK? Because the applications might be boring, but hopefully at least your coding is fun. Now, the nice thing about F-sharp is F-sharp is actually a fun language to code in. I don't think anyone thinks that C-sharp or Java are fun languages. They're useful, but they're not exactly fun. I think Python is more fun. Ruby is a bit more fun. F-sharp is fun. And in fact, fun is even a keyword in F-sharp. So they know what they're talking about. So F-sharp is really good for Blobber development. So let me just show you some F-sharp and C-sharp codes. And you tell me which one you think is better for domain-driven design, OK? So in domain-driven design, we'll start with a simple immutable object. In domain-driven design, that's called a value object. So how would you implement a value object in C-sharp? Well, first of all, what is a value object? So a value object is basically an immutable object which is based on comparing all the properties. So if you have a personal name, two personal names, if the first names are equal and the last names are equal, they're basically the same thing. They might be different objects, different pointers, but from a logical point of view, they're the same object, which means they have to be immutable because they can't be changing underneath you. So here is a C-sharp version. We have a constructor with the first name, last name. We have two properties. I'm using private setters for immutability. Not really immutable. I could be using read-only if I was going to be super strict. But that's probably good enough. Something I've left off, though, is that personal name is a reference type, like all classes in C-sharp, which means if I have two personal names and I compare them, they're going to compare differently. So what I have to do is I have to override equality. So I have to override it, get hash code, and I have to override equals, and I have to add equals again, and I have to implement i, equitable, whatever it is. So there's a lot of code you have to write to do equality. And this is actually quite bug-ridden code. I don't know if any people have ever put objects in a dictionary or a set with a mutable ID and the hash code's changed and all of a sudden things break. It's very easy to get this kind of stuff wrong. So let's compare this with f-sharp. So in f-sharp, this is your personal name. You've got a first name and a last name, exactly the same thing, two properties. The whole thing fits on one under code. But of course, I need to do equality as well. So let me show you the code for equality. So yeah, there is actually no code for equality because in f-sharp, classes or types are equal by default. You don't have to override equality. So it's the other way around. If you want them to not be equal, you have to do it to work. And the best code is no code of all. If you don't write equality methods, you can't mess them up. So it's less work for everybody. Now, in domain driven design, you also have this concept of an entity object. An entity object is normally based on some sort of ID. And here's an example of a person. And the person ID, if they have the same ID, they're the same thing. But the contents of the thing can change. So this person has changed their name from Alice Adams to Bill Wobaggins. And generally, the content is mutable. That doesn't have to be mutable. So let's look at the C-sharp code, very same kind of thing, except I've removed the private setter to make it a mutable name. And I have to override equality again. And now I have to change, subtly change the way I compare things. Buried in the code is the important part. Let's look at the f-sharp code. Now, in f-sharp, if you want to change the way that equality works, you have to say custom equality. You have to override equality. And then you have to get hash code and equals just like the C-sharp code. The nice thing about f-sharp, though, is the person cannot be null. So you don't have to do any null checking ever, unless you're dealing with code that's coming from C-sharp, where you don't necessarily trust it. So. But in this case, we're comparing by ID. But in many situations, you might not want to compare by ID. Sometimes you might compare by person, by the name. Sometimes you might compare by ID. And it may be that you want to use different comparisons into different situations. So rather than always having a default comparison, you can pass in i-comparables or whatever it is. What I like to do in f-sharp is actually say no equality. And what that allows you to do is say that you cannot compare people directly. You can't say this person is equal to this person. You can say their IDs are equal. You can say their names are equal. But you can't actually, if you actually try and compare them directly, you actually get a compiler error, OK? Which is, I think, a very cool thing. I think most entities should have that by default. So the other thing in f-sharp is that the person class is immutable, unlike the C-sharp class. And let me tell you some of the advantages of immutability. So if it's immutable, the only way you can change it is make a new one. You can't just change the property. You have to create a whole new person every single time. And there are some syntax things in f-sharp that make that not so hard. But if you do have to create a new person every single time, the advantage of that is you can validate the data on construction. So in the constructor, you can say it's the name blank or whatever. And if it's a valid thing, you can return a new person. And if it's not a valid thing, you can not return a new person. And that's the only way you can create a person is through that constructor. And that means that any change has to go through that checkpoint, which means that there's only one place you have to enforce invariance. So I don't know if you've ever had code on the setter of a property. You've had to check that it's not blank or check that it's not null. And then if it is null, what do you do? You're going to throw an exception, or you're going to have an object which is in an invalid state. You don't really have very many good solutions to that problem. If you don't allow an invalid object to be created in the first place, you eliminate a whole class of problems right there. So let's have a look at the C-sharp code that we've got so far. There we go, the personal name and the person. So let me ask you a couple of questions. Do you think this is a reasonable amount of code to write for these two simple objects? All right, I think the answer is no. I think that's way too much code. And secondly, do you think a non-programmer could understand this? If I was showing it to an in-house customer and I say, have I got the definition of a name right? Is this what you mean by a personal name? I think they would say, well, I can't understand all this weird stuff. The other thing is you can't really tell which ones are values and which ones are entities. You can use market interfaces. But the important stuff is sort of buried right in the middle of the code. It's not at all obvious how they compare the ones of value type, and it compares on properties. And the other one is an entity, and it compares on its ID. OK, let's look at the F-sharp code. So there's the personal name, and there's the person. So let me ask you the same two questions. Do you think this is a reasonable amount of code to write for a simple object? And I think, yes, I think there's pretty much a small amount of code you shouldn't get away with writing. Secondly, do you think that a non-programmer could understand this? If I went to somebody and said, have I got the right definition for a personal name, like a business analyst or something, and would they say, yeah, I can understand that? I don't understand F-sharp, but I can look at this code and say, yeah, actually you're missing a middle initial, or you're missing an email address or something. It's pretty obvious just by looking at it. You don't have to be an expert in the language to understand this code. So comparing C-sharp and F-sharp. So this is just now, I'm not saying that C-sharp is a bad language, but I'm saying from the design point of view, if you're just designing types, I think that F-sharp wins out over C-sharp. Value objects are really easy. Entity objects are really easy. Value objects by default. Immutable objects by default. You can tell them apart, and it's easy to understand by non-programmer. So if you do nothing else, you might consider just using F-sharp for doing your types or your classes. And it's just an assembly. You can link it in with your main C-sharp code. So if you want an easy way to create immutable classes, have an F-sharp assembly and just do that. Don't have to write any other F-sharp code whatsoever. Just do that bit and then use those classes in C-sharp. So this last thing, whether it's understandable by a non-programmer, I think that's a really important point. Again, it's all about communication. So let's look at F-sharp for domain-driven design. And like I said, domain-driven design is about communicating a domain model within the team. So communication is a hard problem. If we take this word UNIO-NIZE, what does that word mean? Well, if you're an activist, that might mean unionize. If you're chemists, it might mean un-ionize. So the same word can mean two different things to do two different people. So in domain-driven design, there's this concept of a bounded context, a framework within which the words mean something. So if you're talking about social activism, unionize means one thing. If you're talking about chemistry, un-ionize means something different. So different domains, different bounded contexts, same word. So it's very important to define the context that you're using that word in. So let me give you another example. SPAM. So if you run a supermarket, spam means one thing. And if you're an email admin, spam means another thing. These are kind of cheap shots. These are pretty easy. Everyone knows these ones. What about products, though? What does a product mean? So this is something you might run into. Like if you're in the sales team, a product is something you can sell. But if you manage a warehouse, a product might be a physical thing that you can put in a box. And sometimes the things you can sell are not necessarily the same things that you can put in a box. And you start getting this miscommunication between the teams. So one of the goals of Domain with Design is to define these contexts and make sure the words are used appropriately in each context. Here's another one. Customer. You probably run into this one, too. From a marketing point of view, a customer, if anyone has an email that you can send them spam to. If you're in finance, a customer is someone who's given you money. It's a different definition. And it affects your design, because a customer who's given you money, you might have an account ID, and you might have a current balance and stuff. And from a marketing point of view, a customer is just an email address, and maybe not even a name. So this brings us to the topic of ubiquitous language. So if you're working in a domain like chemistry, say, chemists have these words, like iron, and atom, and molecule, and polymer, and so on. Now as developers, if you're working on an application in the domain of chemistry, it's very important that we use the same words that chemists use. We shouldn't talk about molecules as an aggregate of atoms, and we shouldn't talk about polymers as a linked list of atom aggregates or something. Those are techy words. We should use the same words that the customers use. So again, part of the process of domain-driven design is to come up with a set of words that the developers can use and the domain experts can use, and that we all agree on them. And then when we talk about a polymer, we have a class called polymer. We don't have a class called list of atom aggregates or something. So again, the ubiquitous language can look similar in different domains. So in the sales domain, you might have something called a customer and something called a product. In the warehouse domain, again, you might have something called a product, but it's a different kind of thing. So but defining the ubiquitous language in a domain is a very important part of domain-driven design. So here is an example of some F-sharp code for a domain. So this is a domain of a card game. How can we tell it's about a card game? Because there's a word at the top that says this is a card game. If this was in a different domain, if I was in the domain of a clothes shop, then suits would mean something completely different. And if I was in the domain of the navy or something, then deck would mean something completely different. But in the domain of a card game, in the bounded context of a card game, these are the things that matter. And so this is the ubiquitous language right here. So let me just go through this F-sharp code. The vertical bar means a choice. So a club or a diamond or a spade or a heart. The star means a pair in this case. So a card is a pick one from a suit, pick one from rank. That's your card. The list is actually a keyword in F-sharp. That's very nice. And this one with an arrow is a function. So this means to deal something. You start with a deck. The one on the left side of the arrow is the input. On the right hand side of the arrow is the output. So you start. The input is a deck. The output is a different deck with a missing card plus a card on the table. So that's the output. So that's the entire domain on one page. So let me ask you the same questions. Is this the reasonable amount of code to write for this domain? I've got nine classes on one page. So I think that's pretty good. In C-sharp, if I was doing this, there would be nine files in a folder, probably. Do you think a non-programmer could understand this? If I had left off something like the king, do you think I could show this to a non-programmer and say, have I left all the cards right? And they would say, yeah, no, you left off king. It's like, oh, thanks. It wouldn't be buried in some enum somewhere. Another important point about this code is there's nothing about databases here. There's nothing about user interface. This is persistent Ignoment. Persistence Ignoment. There's nothing about how it gets stored. I don't care whether you store this in a SQL database, whether you store it in a file system. If you want to be web scale, you can store it in Mongo. It doesn't really matter. It's not part of the domain how it's stored. And the other thing about this code is this is code, and it's a design as well. It's a design and code at the same time. And that is one of the agile philosophies, really, is that the most accurate thing to represent your design is the code. Comments go out of date. Documentation goes out of date. The only thing that is the truth about your application is the code itself. So it's nice if your code can actually represent your design in a nice way. And this is actually not pseudocode. This is compilable code. I could take this code, stick it in Visual Studio, and run it, and get some stuff out. So this is not pseudocode. So I think that's really quite a powerful thing. If you do this kind of approach, you don't need to have your mail diagrams. OK. No new mail, no documentation, just the code itself. The code acts as documentation. If you change that code, at least you add a new type to a new kind of card, for example, your code will fail to compile because it's compilable code. Right, so that's the sort of introduction to domain driven design. And let's talk about the F-sharp type system. So the F-sharp type system is very different from what you're used to in C-sharp. So in C-sharp, you have classes. In F-sharp, you have types. Types are not the same thing as classes. And the F-sharp type system is called an algebraic type system, which is the same type system that's used in Haskell, and the same thing that's used in OCaml, a couple of other languages, very common in functional languages. So algebraic is another one of those mathematical words. So I'm going to use the word composable instead. So it's a composable type system. So unlike objects or classes, you can actually compose the types together to make new types. So what do I mean by composable? It's like LEGO, right? If you take two LEGO bricks and you stick them together, you've got another thing that you can then stick other things to it. You can build up complex things by gluing smaller things together. So that's what composable means. So if you do have two smaller things, how do you glue them together to make a bigger thing? Well, in algebraic types or composable type system, there are basically two ways you can glue them together. You can either multiply them together. So a new type is an old type times another old type. Or you can add them together. So a new type is a type plus another type. Now at this point, you might be thinking, well, that's just crazy. How can you add two types together? How can you multiply two types? What does that even mean? That just sounds silly. But I think if you just hold on another five minutes, I think all will become clear. So let's start off with the times. So here's a very simple function. So a function is basically a black box. It's got input and it's got an output. That's all the function is. So I'm going to take the function add1, for example. So on the input, I have a list of numbers, integers. On the output, I have a list of integers. And the way you write that in F sharp is int arrow int. So int is the input function output is an int. So that's pretty straightforward. Now what happens if we want to add a pair of numbers together? So if we add one to it, the input is a pair and the output is added together. So the output is easy. We can say the output's an int. But what's the input? What kind of type is that input? Now we could define a class called pair, but that's got nothing to do. It's not built from smaller pieces. I want to actually create this type by adding two other types or combining two other types. So let's look at how we can do that. So let's think about what a pair is. So a pair basically means you pick one from the first pile and you pick another one from the second pile, right? So one column and the second column. So let's say there are four numbers. Obviously there are like 64k of four gig numbers, but let's say there are four numbers only. So you can pick four from this pile and you can pick four from the second pile. How many possible pairs are there? There's four times four, 16 possible combinations, yeah? So that's multiplying them, right? Four times four is 16. Here's another example. Let's say you have a pair of booleans. So true false and true true and false false, right? So again, the first column is you pick one from two possibilities and the second column is you pick one from two possibilities and the total number of combinations is two times two. So the way you get the pair is by multiplying the first column by the second column. So that's the total number of possibilities. So in fact, that's exactly how you do it in F-sharp. You say a pair of ints is written as int star int, int times int. And a pair of booleans is written as bool star bool. So literally multiplication, OK? So you can see where that's coming from. It looks a little bit weird at first, but it's actually quite sensible if you think about it. All right, well, that seems kind of academic. Maybe say, OK, well, it's kind of theoretical. Let's look at a real example of how you might see it in a real business application. So let's say you have a bunch of birthdays. So Alice was born on January 12th and Bob was born on February 2nd and so on. How can I represent these birthdays using the type system? Well, we have a set of people. The first column is a set of people, all the people in the world. The second column is a set of all the dates in the world. And every possible combination of a person and a date is multiplication. So that's how I get the birthday type is the every possible combination of the people type and the date type. So in code, in F sharp code, you would write it like this. Type birthday equals person times date. And that's how you create a new birthday type. Right, so that's one kind. So that's what they call a product type or a multiplication type. What about the other one where you're adding things together? So let's look at how you might represent a choice. So here's a function that says whether you have a fever or not. You're passing some sort of temperature. And if your temperature is more than 37 and 1⁄2 or 38, where it says, OK, you've got a fever. And if it's in Fahrenheit, there's 100s, say, and you get a fever. So how can I document what the input is? Well, the output's tabooly, so that's easy enough. But the input is a choice. I can either pass in a Fahrenheit temperature or I can pass in a Celsius temperature. How do I represent that? So if you think about it, this is the same kind of thing. I've got a list of possible temperatures in Fahrenheit. And I've got a list of possible temperatures in Celsius or centigrade. But this is slightly different because I pick one from the first pile or I pick one from the second pile. So let's say there are four in the first pile and four in the second pile. How many possible combinations are there? There's actually only eight. I pick one of these four or I pick one of these four. So there's eight possible combinations. So that's addition. It's what they call a sum type. And how do you represent it in F-sharp? They're both, say, integers. So you have to have some way of differentiating the integers, so you tag them with a little symbol. So I'm going to tag the Fahrenheit ones with the letter F. And I'm going to tag the Celsius ones with the letter C. And then you write that in F-sharp as the temperature type is a choice between an integer, which is tagged with F, and a, say, a float that's tagged with C. So that's how you'd write this choice type in F-sharp. It could be one or the other, but not both at the same time. All right. So again, that's maybe a bit strange. But let's have a look at a real example. So here's a payment method. So as an e-commerce business or maybe as a shop, I can take cash, I can take checks, I can take credit cards, say. And you'd represent that as three different choices. I can take cash, I can take checks, and I can take credit cards. Three different choices right there in front of you. One of the nice things about these choice types is you can have extra data attached to different pieces. You can think of them as different constructors. You might have a cash constructor and a check constructor. And the cash, you don't need any extra information. For a check, you might need the check number. And for a credit card, you'd need the card type and the card number, so a pair. And when you actually use these things, you want to look inside and see which particular choice was actually used. So when, let's say, you want to print the payment method on a receipt or something. What you do is use a match statement, which is the F-sharp equivalent of a switch, basically, or case statement. And if it's cash, you say print cash. If it's a check, you say pay by check. And one of the nice things about the matching is it extracts the information inside at the same time. So you match and you suck out the data. And finally, if I pay by card, I can get the card type and the card number at the same time. So that's how choice types work in F-sharp. And it's very cool that you do this match and assignment in one step. So these are not just enums, like in C-sharp, because enums are just integers behind the scenes. This has, these are more like subclasses, and each subclass has its own data. So you might say, well, why don't you model it with inheritance? Why don't you use subclasses? Why have this special kind of choice type? So how would you implement this in C-sharp or an OO language? So what you'd probably do is have some sort of interface or abstract-based class that represents all of them, an I payment method. And then you'd have a cash class or subclass with a constructor, you'd have a check class that had its own data, and you'd have a credit card class that had its own data. So the problem with this approach is that the interface has no common behavior really between the two. I mean, you might say, well, yeah, the printing method is a common behavior. But that's really in that context. I don't think it should be part of the core domain class that it can print itself on a receipt. That's really mixing, you know, that's not separating your concerns well enough. You should be able to print it on a receipt is a different thing. There's actually no common methods that belong to the domain. The other nice thing about the F-sharp approach is the exadata is really obvious. If I say, well, what do I need to store a credit card? It's like, well, I need a card type and I need a card number. Is that obvious from the C-sharp codes? It's kind of buried in the constructor. It's buried in the properties. It's not really obvious where it is. It's basically scattered around in many locations. And in C-sharp, that would be four different files, probably. You could have one class per file, four different files. In F-sharp, it's four lines, four lines of code in one place. The other thing about the F-sharp code is it's closed, which means that you can't add a fourth option. That is your limit. If you want to add a fourth option, you can, but all your code will break. And then you have to fix up your code, which I think is a good thing. If you add a new kind of payment method, you want your code to break until you've handled that particular new payment method in all your class, in all your code. In OO, in the OO version, anything that implements the I payment method is valid. So you might get an unpleasant surprise. I might implement an evil payment method. As long as it implements the interface, it's totally valid. Now in some cases, you might want open. You might want to have, oh, anybody can implement this interface and it's fine. I trust them. But in business logic, most of the things are actually quite restricted. You have a restricted set of options like payment methods. And adding a new one is actually something you want to know about. It's not something that you should just slip in behind the scenes without telling anybody. So what are types for in functional programming? It's an annotation to a value for type checking. So here we go. It's just like in C-sharp. You say this is an int. It takes an int and it outputs an int. But it's also a domain modeling tool. So in this case, I can tell you that to deal something, you have a deck of cards. And you input this and you output that. So you can actually model the domain using the types. And it's both at once, which means that your domain modeling tool is also compiled into your code. So your code can never match the domain. So I think of a static type system like this is almost like having compile time unit tests. If I have a unit test that says, oh, a payment card must always have a card number or something, I don't need to have a unit test for that. It will not compile if the code doesn't match the domain. So it's a compile time unit test. So type all the things. It's one of the mottos of the static type people, especially the functional programmers. All right, so what can we do with this type system? Let's actually put it to use, do something useful with it. I'm going to start with optional values. This is a really common case. So here we have our personal name. And the middle initial is optional. And the first and last name are not optional. And I can't tell. So can I use the type system to indicate that? So let's go back to our strings. So let's say we have a function that's the length of a string, really, really simple function. And the input is a string, and the output is an int. That's a very simple function. The only problem is that we have null in this list of strings. And null is evil because it's pretending to be a string. You cannot use null as a string. If I say setPhase as to null, that doesn't make any sense. It's illogical. So null is not really a string. It's in the pile of strings. If I say to null, are you a string? I say, yeah, yeah, I'm a string. And then you say, well, give me your length. And you say, ha, you know, I'm going to crash your application now. And it's like, well, you told me you're a string. It's like, well, yeah, I'm pretending to be a string, but I'm not really. So I think of null as like Saruman. OK, it's going to betray you behind your back. It pretends to be one thing, but it's something evil. So in F sharp, null is not allowed. Null is not a valid string. Well, actually, in F sharp, unfortunately, it is a valid string because of the way that it has to be compatible. But most of the classes you create, your own classes in F sharp are not allowed to be null. So you never have to deal with nulls in general. So no nulls. So if you don't have nulls, what can you do instead? So we have a list of strings here. And null is not in them. But we want to say, well, maybe the string's missing. So how can we indicate that? Well, we've already seen how we can do that because we have this choice between something and nothing. So the way we represent that in F sharp is exactly that thing. You have a choice between a string, a valid string, which is not null, and nothing at all. And it's a sum type. It's a choice type. And we tag the strings with some string. And we tag the missing with nothing. So you see the some string or it's nothing. And we write that like that. So it's either some string or it's nothing. So that's a type that you would see a lot in F sharp. And you say, oh, that's really cool. You have the optional string. And then, oh, I want optional int as well. Oh, optional Boolean's really important. So you start having all these optional types floating around. And at some point, you say, there must be an easy way to that. So let me define a generic type that takes a type parameter. So in this case, it's an option of any type. And it's either some of that type or it's nothing, none. And that type is actually built in to F sharp. So this option type is built in. And it's used a lot in the F sharp libraries. So with this option type, we can rewrite the middle initial to say it's an option of a string. And in F sharp, you can actually have a nicer syntax where you call it a string option rather than an option of a string. So I think that's actually much nicer if I was showing that to someone I say, look, it's an optional string. I think it's pretty easy to understand. All right, the next kind of type I'm going to talk about is what I call single choice types. And this is an example of a single choice type. It's something and it's choice A of something. But there is no choice B. There's only one choice. Why would you only have one choice? So let's look at some examples. Here's an email which has only got one choice of an email. Customer ID has only got one choice called customer ID. Why would you only have one choice? What possible use is that? So think about this for a second. Is an email address just a string? All right, in your domain, can you add hello to it without breaking code? Can you reverse it without breaking stuff? An email address isn't a string. Once you've validated it, you really shouldn't be messing with it. You shouldn't be adding things and subtracting things. You shouldn't be reversing it. It's like it's a thing. It's an email address. It happens to be represented as a string, but it isn't really a string in your domain. Is a customer ID just an int? Can you add five to your customer ID and still get a valid customer ID? Probably not. I mean, maybe you can. But your customer IDs, they might be represented by ints in your database, but they're not really ints in a domain. So by using single choice types, you can keep these types separate from their underlying representation. So for example, if you have an email address which is represented by a string and a phone number which is represented by a string, by wrapping them in a single choice, you've now made them different types, distinct types, and you can no longer compare an email address with a string, and you can't compare it with a phone number, and you can't compare a phone number with a string. They're just completely different types all together. And you'll get compile errors, compile errors if you try and compare them. Similarly, if you have a customer ID and an order ID, and this is a very common problem, they're both represented by ints, and in your codes, you want to keep them separate in your query strings to your DAO or whatever. They're not the same thing. If you try and compare them, you should actually get a compile time error. So are you familiar with the phrase primitive obsession? So the primitive obsession is when you use ints instead of domain objects like this. You shouldn't be using ints to represent customer IDs. The other nice thing about using a special type for the email is you can wrap it in a constructor that does validation. So an email address is not just a normal string, it has to have an at sign in it, say. So very crude validation is that it has to match some sort of regex. So in this case, it has to have an at sign in it. So in the constructor, you can say, well, if it does match that regex, then you return a new email address, a wrapped email address. But here's the problem. What happens if it doesn't match the regex? What are you going to do? You're going to return null? No, because null is not a valid email address. You're going to throw an exception. Well, that seems a bit harsh. Just because I passed in a invalid email, it's like, can't you just give me something more useful that I can process as a, well, they have to catch exceptions all the time. Well, I think we already seen the answer to this. You use the option type. So if it's a valid email, you say, yes, it's an email, some email, and if it's not a valid email, you turn nothing. It's like not a valid email. But this is a proper type. You're not throwing exceptions. You're not returning null. And you can tell what it does, unlike the null case or the exception case, you can actually tell what it is by looking at the signature for the function. So you might think that the signature is, give me a string and I'll give you back an email address. And that would be true if I was using nulls, and it would be true if I was using exceptions. But I'm not using either of those. I'm using options instead. So the signature says, you give me a string. I might give you back an email address. I might not. You'll have to handle both cases, because depending on what string you give me, I might give you back nothing at all, because it's not valid. And you are forced to handle both cases. When you take this code, at some point in your code, you're going to have to say, well, is it something or is it nothing? But you can pass it around. You don't have to handle it straight away. It's not like an exception or a null. You can pass it around until somebody has to deal with it. So let's look at another example. Here's a string 50. In this case, I want to make sure that the string is constrained to be less than 50 characters long. So again, I have a little in the constructor. I have a little test. Is it less than 50? If it is less than 50, I can return a valid string 50. And if it's not a valid, if it's not, I return nothing. So the constructor, the signature for the constructor looks like this. Pass in a string, and I might get better string 50 or I might not, depending on whether you passed in a string that was too long or not. Here's another example. If I say this is an e-commerce system, and I've actually seen this in a real e-commerce system, what is wrong with that picture is that I have like a million things in my shopping cart. That should not be possible. I shouldn't really be able to add a million things. Or maybe I can, but most shopping sites will not let me do that, but they might let me do that because somebody has only represented it by an int behind the scenes. So what I really should do is create a new type called an orderline quantity. It wraps an integer. It's not a normal integer. It can't be negative. It can't be 2 billion. There's going to be some sort of constraints on it. And so the nice thing about an F-sharp is I can create a new type just for this domain. It's because it's one line of code. It's really easy. In C-sharp, I should probably do the same thing too, but I probably can't be bothered because it's a lot of work. So most people don't actually do this. And this is the kind of thing where you get bugs in your code because you represent it as an int. And then you have to have special code to handle negatives, special code to handle more than 1,000 or something. Don't have that code. Just don't allow it to be created in the first place if it's not the right number. So in this case, it has to be greater than zero. So even zero is not a valid number for a shopping cart quantity. So if I do something with it, I'm going to have to handle the case where I guarantee by having this type is between 1 and 99. I literally cannot have a zero quantity item in my basket. Yes? AUDIENCE member 1, question. The question is, where would that constructor be implemented? The answer is it would be implemented normally near the type itself. So in Fsharp, you have a module which is basically a namespace or a kind of grouping of codes. And what you can do is you can actually make sure that the constructor is the only way. You can hide the built-in constructor, and you can make sure that people are forced to go through that constructor. And that would be the only way. It's like having a private constructor and then having a public factoring method. And you'd put them together in the same file. Does that make sense? So again, here we return something or we return nothing. So every time I add something to my order line quantity, I have to take into account that I might get something back which isn't an order line quantity. So if I subtract 1, I might get nothing. And in my code, I'll have to say, well, what happens if I get nothing back? Well, OK, maybe I have to move that line from the basket. I'm forced to deal with that code. It reduces bugs just by doing this. So let's have a look at our code quickly, the challenge. So our challenge was how do we do optionals? And we're going to rewrite this now to use constrainString, string50 rather than just a plain old string. So that's a lot easier to see what's going on. And then the other thing, one of the questions is how do I make it very clear which sets of properties have to be grouped together for currency purposes? And it's really easy in F sharp just to create two new little small types. And then the big type just contains the small types. And because it's really easy to do, I mean, this is eight lines of codes. And you can all be in one file. You don't have to create three separate classes and three separate files. So in F sharp, you tend to get a lot more small types than in C sharp just because it's so easy to do. There's one thing we have not talked about, which is this email verified. So this is this Boolean. It's only allowed to be set to true if the email has been verified. So let's have a look at that for a second. So we have some business rules around this. The first business rule is if the email is changed, you have to set it back to false because it's not verified. And the only way you can set it to true is if it's been verified by some sort of verification service. You know, they click on an email and there's a hash in the email and you check that the hash matches. And if it's OK, then it's all good. So those are business rules. Now, again, normally in C sharp, those business rules would be sort of embedded in the code. My question is, can we embed those business rules in the type system? So it's compile time error to get it wrong. So the compiler will not let you set that to true by mistake. Is that even possible? So let's see. So this is not very good. This is terrible because anybody could set it to true and say, oh yeah, this is a verified email address, even though it isn't. So how would you do this in F sharp? Well, the first thing you'd do is you would wrap the email address in a new type called a verified email address. And this is one of the things you tend to get in functional programming, which is any time you have a problem, you solve it by wrapping it in another type. There's no problem that can't be solved by wrapping it in another type, basically. So you tend to have these types within types within types. But because it's a one-liner, it's really easy to do. And it's equally easy to unpack it as well. So now I have a difference now between a normal email address and a verified email address. They're now different types, and they can't get mixed up. That's good. And how do I get one of these verified emails? I have an email service, a verification service, and it takes in an email address as input, and it takes in some sort of hash, which you pass in, and it checks the hash. And if it matches the email, it says, yeah, this is a verified email. Or it might say, actually, it's not. So that's why it's an option. I can tell straight away from this service that it might not work. So email input, an optional verified email is the output. And then what I do is I define my email information as a choice. I say either it's an unverified email or it's a verified email. If it's an unverified email, it's just a normal email address. If it's a verified email, it has to be one of these special verified email addresses. And the only people who can create this is this verification service. I can't create one of these things. Only the verification service can. So when I'm coming along and I want to change the email address, I can change it to unverified, but I can't change it to verified. So this is a way of guaranteeing in the type system that I can't have an accidentally verified email address. So I've got rid of the Boolean and replaced it with two choices. And that's a very common thing you'll see in functional code is every time you have these Boolean flags, like has it been shipped, has the order been paid, all that kind of stuff, those are replaced by a set of states, a set of choices, and each choice might have different types associated with it. So let's go back to our original challenge. Here is our email address. We've broken up into we had one type originally, and now we've got five, six types plus the verification service. The questions were, again, which values are optional, what are the constraints, which fields are linked, and what is the domain logic. So which values are optional? Is this now clear from the code? I could show this to somebody and say, which one's optional? And you say, yeah, the middle initial is optional. The other ones are not optional because they're not allowed to be null, remember? So they're required. The first name is, by definition, required. If I don't say it's optional, it has to be required. The constraints now, I've replaced it with these special types called string 50 or string 1. And the email address, again, is a constrained type. So if I have a first name, I know it's going to be less than 50 characters. I can't, when it comes time to put it into the database, I know that I'm never going to have some database bounds exception that I have to handle because I know it's going to be within the right length. Which fields are linked? Well, that's easy. I just created two little smaller types. That was trivial. And finally, it's the domain logic clear. And it is, I think, because it's now very clear that I have unverified and verified ones. And it's also very clear that the verified email is a different kind of thing than a normal email. What's interesting about this is not only that I've now encoded all those rules in the design, but the ubiquitous language has evolved, too. So in my design, I now have something called an email contact info. I have something called a verified email address. So these are things that I didn't have in the original design. But in fact, these actually do represent concepts in the domain. If I was talking to a business and say, yeah, we have verified emails and we have non-verified emails. So I've actually documented that now, which the original design didn't have. And it's, of course, it's compilable code. This is not pseudo code. This is not a URL diagram. This is real code that compiles. And it would be basically the first file in your F-sharp project. So if you don't mind hanging around for another couple of minutes, I just want to do one more thing, which is this concept called making illegal states unrepresentable. So let's say that some time passes and we now have an address as well as an email. This is the requirements are changing now. And we have a new business rule that the contact must have an email or a postal address. So I need to be able to contact you somehow. That's a fair enough requirement. So does this type actually meet that requirement? And the answer is no, it doesn't. Because the way it stands right now is both the email and the address are required. They're both required fields, right? They can't be null. So they're both required. So this doesn't allow for the fact where I have one but not the other. All right, well, I'll make them both optional. So yeah, does that solve it? No, that doesn't solve it either, because now they could both be missing. So the business requirement is you have to have one of them. You can't have them both missing. So how can I encode that business requirement? Again, in C-Shark, we'd probably have some code varied in a way, well, if they're both null, then throw an exception or return an error or something. It'd be nice if we could actually encode that in the type in such a way that you didn't even have to deal with that case. You could not literally represent that. So that is this concept called make illegal states unrepresentable. If you can't do something, don't even allow it to be in the type system. In this design, I could make them both optional or both null. It's like, don't allow that to happen. So how can I prevent that from happening in the type system? Well, if you think about it, that business rule says that you either have an email address or you have a post address or you have both. That's what the business rule says. There's only three choices, not four choices, not two choices. Well, how would you represent that? Well, as I say, you always wrap everything in a type. You create a new type with three choices, where it's email-only or address-only or an email and postal address. So I now have a type that represents that business rule. And I literally cannot have both of them missing, because it's not one of the choices in the type. But so by defying a type like this, I can actually hard code my business rule into my design in such a way that I literally cannot mess it up. You cannot have a bug from having them both missing, because there is no way to represent them both missing. And then I just replaced my email address as just one new type now. So what I've done is I started with them as separate things, and I've merged them into a single thing, which now has a set of choices. So static types are really awesome, almost as awesome as that. One final thing, let's say that that's a rather restrictive thing, an email address or a postal address. What they probably mean is the business probably didn't really mean that. What they probably meant is there's some way that you have to have at least one way of being contacted, because you're a contact. I should be able to contact you in at least one way. So rather than doing that, what I might do is say, well, this is different ways of contacting you. I can contact you with an email, or I can contact you by sending you a letter. And then in the contact type or structure, I have a primary contact information and a secondary contact information. And the primary contact information is required, and the secondary contact is optional. So again, the type system has created, again, it might be something that when you talk about this, the business zone. So yeah, of course, we have a primary contact and a secondary contact. It's a new part of the domain language now. You've got a part of the ubiquitous language to have a concept of a primary contact. And again, the primary contact is not allowed to be null, so it's by definition required. It's very clear from this code what the business rule is. So I talked about the challenge. I talked about ubiquitous language, self-documenting designs, algebraic types, designing with types, using options, single case unions, and making illegal states unrepresentable. So hopefully this all makes sense now. I haven't talked about states and transitions. That's a really important thing. Services, CQOS, how you do the functional approach to doing use cases, and domain events, and error handling. So if you're worried about using F-sharp, I actually think you should just try it out. Like I said, even if you just use the type system and don't write any code, the support of Microsoft, if you want to go mobile, it's built into Xamarin Studio. That gets you F-sharp on millions of platforms. So it's a very safe choice. If you need to persuade your manager, I have some examples at FP Bridge. And there is the link to my site, F-sharp on Twitter if you've got any questions. Contact me on Twitter. And if you need any help with F-sharp, contact me at my consulting business. Thanks very much. If you have any questions, please come and see me afterwards, and please remember to put the review things, yes. And there are some more F-sharp things tomorrow morning, by the way. Two F-sharp talks tomorrow morning if you're interested in F-sharp. Please go to those.
 Okay. Can everyone hear me okay?  Up all the way at the back. Can you hear me?  Yeah.  Yeah. Okay. Good.  Right. So this talk is domain driven design or  domain modeling with the F-sharp type system.  It's not really,  I'm not going to go through a lot of domain driven design.  It's more about how can you construct  a domain model with the F-sharp type system.  So I'm going to be explaining about algebraic types  and how you can use that for designing.  So a little bit of domain design,  but mostly about the F-sharp type system and algebraic types.  So hopefully that's what you're interested in.  So I'm going to start with a challenge here.  How many things are wrong with this design that you see on the screen?  So you probably have seen this kind of code,  millions of times.  It's a very simple contact or a person.  There's a first name, middle initial, last name,  an email address, and a flag to say whether  the email address has been verified by  sending the contact to an email to verify.  So you might think, well,  I'm not going to say it's about syntax.  I'm actually talking about from a design point of view,  how many things are wrong with this code?  And I think you'll find there's quite a number of things wrong.  Hopefully I'll surprise you with some of the things that I'll say.  So before we start on that, though,  let me just talk about the software development process.  And just like any process, there's an input,  and there's the process, and then there's the output.  And one of the things that we do in conferences like this  is we normally talk about the process,  which is the coding and the testing and the tooling  and continuous integration and continuous deployment  and all these things.  I think one of the problems with that is  there's this well-known truism,  which is if you have garbage in, you get garbage out.  So we tend to focus on the process,  but really what we should do is focus on having less garbage  coming into the process in the first place.  So what I'd like to do in this talk is really focus on  reducing the amount of garbage that comes in  and then hopefully that reduces the amount of garbage  that comes out.  So reducing the amount of garbage that goes in  is really the design process.  So if you have a good design process,  you can actually guarantee good output.  If you have a bad design process,  all the best tools in the world  will not necessarily guarantee a good output,  or at least there's a lot of extra effort  to guarantee that extra good output.  So that's what this talk is about.  How can we have good design  and how can the language that you use  help you with that design?  And I think that F-sharp is actually an excellent language  for design purposes, not for coding, for design.  So here is our contact again,  and I propose to you that this is actually  a very garbage-riddled design.  If you use this design, you might have lots of errors  in your code that would be completely preventable  if you use the different design.  So the first question of this design,  one of the reasons why this is not a good design,  is it's not very clear which values are optional.  So the middle initial probably is going to be  an optional property or an optional field.  The first name might be required,  the last name might be required,  the email address might be required.  It's not clear from this design.  So when it comes time to coding, you won't actually know.  So there's going to be a communication gap  straight away between coding and the design.  Now you might code it so it's optional,  but that's going to be buried in your code.  And when someone else comes along,  they're going to have to look at your code  to find out whether it's optional or not.  So in this case, the middle initial is optional.  It'd be nice if we could somehow put that optionality  into the design itself.  What about the constraints?  So if we take the first name, it says it's a string.  So does that mean you can put two billion characters  into the first name?  Can you have line feeds in the first name?  There are constraints on the first name,  which a string does not represent.  Now again, you probably have some validation logic  in your code, but that's in the code.  Can we actually represent that in the design?  So in this case, the string is not  allowed to be more than, say, 50 characters.  What about which fields are linked together?  So what I mean by that is in terms of concurrency,  I can, if one person updates the first name  and another person updates the last name at the same time,  that's going to be a concurrency error.  But if one person updates the first name  and someone else updates the email,  that might not be a concurrency error.  Is there a way of communicating that through this design?  In this case, it's pretty obvious that the name part  is separate from the email part.  And finally, what's the domain logic?  So we have this isEmailVerify flag.  That means I sent you an email and you clicked on it,  so I know that you actually are the owner of that email.  But where is that logic in this design?  I mean, that's just a boolean.  Anybody could set it to true or false.  I mean, I've called it something,  but the logic is not encoded in the design.  So in this case, the logic is that if the email is changed,  I have to reset it to false.  If you change your email, I have to re-verify you.  So here's all the questions again.  Which value is optional?  What are the constraints?  Which fields are linked?  And what's the domain logic?  And I think that F-sharp can actually  help with all of these questions.  So domain modeling in the F-sharp type system.  My name's Scott Voloshin.  My Twitter handle is Scott Voloshin, very cleverly.  I have a website called fsharpforfunandprofit.com.  And I have a consulting company called FP Bridge.  And if you want these slides, if you  go to fsharpforfunandprofit.com, the slides  will be there and some other links will be there too.  And I'll post the video there too when it's ready.  Right, so domain-driven design.  Hopefully, how many people have read domain-driven design?  Most of you?  Yeah.  So the main quote really from domain design  is you focus on the domain and the domain logic  rather than on the technology.  So you're trying to capture something in a way  that anybody can understand.  It's any business person can understand it.  It's not about writing it in code.  It's not about using clever technologies.  It's about communication really.  So domain modeling and DDD is a quite big topic.  Functional programming is another quite big topic.  This talk is really going to be on the overlap  of those two things.  It's not a particularly common area,  but I think it's actually a quite profound thing  to talk about.  So first of all, I'm going to spend a little bit time  demystifying functional programming  because I think a lot of people are kind of scared.  So I just want to take away some of that fear.  I want to talk about functional programming  is actually a useful thing for real world applications.  It's not just some academic theoretical thing.  I'm going to compare F sharp and C sharp.  How many people use C sharp here?  Everybody, right.  And I'm going to then talk about the F sharp type system.  And then I'm finally going to talk about how you use the F sharp  type system to design real things, really practical things.  So let's start with demystifying functional programming.  Why is it so hard?  I think a lot of people are put off by it  because it's very scary.  You have all these words like functor and catamorphism,  currying and monad.  These are very scary sounding words.  And I think the reason is, yeah, there's Homer,  he's quite scared.  The reason is because the mathematicians got there first  and they named these words.  Now, if we renamed the words differently,  they wouldn't be so scary.  So for example, I think these words are just unfamiliar.  Not scary.  So if we named things like functor,  if we called it mappable instead of functor,  and if we called it collapsible instead of catamorphism,  we said aggregatable or chainable.  So those are still words you might not understand  what they mean, but they don't sound so scary.  So here's Homer.  I mean, he doesn't understand them,  but he's not frightened by them anymore.  It just means it's something you have to learn,  just like you have to learn entity framework,  or you have to learn the link, or you have to learn WCF,  if anyone knows how to do that.  So I tell you what, it's really scary,  it's object-oriented programming.  You just don't think it's scary because you already know it.  But if you're a new person coming to programming  and you're faced with object-oriented programming,  this is what you have to deal with.  You have to deal with all these scary words,  like polymorphism and inheritance and interface  and generics and covariance and countervariance and solid.  And solid itself is five different things, SRP, OCP.  No, there's a lot of things you have to remember.  Each one of those abbreviations,  and you've got IOC and DI and ABC and MVC and AOP  and thousands of little things you have to know.  So that's really scary.  So functional programming is actually a lot less complicated  than object-oriented programming.  It's just that you're more familiar  with object-oriented programming.  The other thing about all these words is  you're not going to need it for this talk,  so I'm not even going to talk about any of them.  All right, so don't worry that I'm going to be mentioning them.  So let's talk about functional programming  for real-world applications.  So you've probably heard that function programming  is good for mathematical stuff  and it's good for complicated algorithms  and it's really good for parallel processing,  but you need a PhD in computer science to understand it.  So the first three things are actually true.  It is good for all of those things.  It's so not true that you need a PhD.  I'll tell you what, I think functional programming  is really good for.  It's really good for boring line of business applications,  blobbers, I call them.  So I think how many people make their living writing blobbers?  Yeah, pretty much everyone writes boring line of business  applications.  So that's e-commerce websites and accounting packages  and ETL data warehouses and I don't know, all sorts of stuff,  back-end infrastructure, whatever.  So that's basically what we do every day.  But I think functional programming  is actually really good for that.  So let me tell you why.  If you're going to be doing Blobber developments,  first of all, you need to express requirements very clearly  because you're working with customers  and sometimes they don't quite know what they're talking about.  You need to have really good communication.  Secondly, you need to have a rapid development cycle  because you want to get the code out there before the customers  change their mind, which they probably  will next month or next week.  So if you can have a rapid development cycle,  then you can actually get the code to live them  and then they're happy.  And finally, you need high quality  because there's nothing worse than trying  to fix a bug for something you did six months ago.  You want to be working on new stuff.  You don't want to be fixing old stuff.  And then you look stupid if you have bugs as well.  So what's interesting is that all these requirements are actually  is where the agile movement came out of, XP came out of Chrysler.  The whole thing of expressing requirements clearly,  that's behavior-driven design and customer-on-site customer  and all this kind of stuff, rapid iterations.  F-sharp is good for that because it's concise  and it's really easy to communicate.  So it's actually better than C-sharp for that.  The rapid development cycle, again,  that's where you have your continuous integration  and your continuous deployment.  F-sharp is good for that.  It has a REPL where you can actually code interactively.  And it has many, many convenience  to avoid boilerplate in your code.  So you can actually churn out a lot of code much faster  in F-sharp.  And finally, the high quality deliverables, of course,  you have your unit tests and so on.  And in F-sharp, you can do unit tests as well,  just because it's a.NET language.  You can use N unit.  But the type system can actually be used to ensure  correctness at the design time.  And that sounds, you can actually encode business logic  into the types.  That sounds like a very strange thing to be able to do,  but you can actually do it.  There's one other thing which is really important.  If you're doing boring business applications,  you need to have a bit of fun, OK?  Because the applications might be boring,  but hopefully at least your coding is fun.  Now, the nice thing about F-sharp is F-sharp is actually  a fun language to code in.  I don't think anyone thinks that C-sharp or Java are fun  languages.  They're useful, but they're not exactly fun.  I think Python is more fun.  Ruby is a bit more fun.  F-sharp is fun.  And in fact, fun is even a keyword in F-sharp.  So they know what they're talking about.  So F-sharp is really good for Blobber development.  So let me just show you some F-sharp and C-sharp codes.  And you tell me which one you think  is better for domain-driven design, OK?  So in domain-driven design, we'll  start with a simple immutable object.  In domain-driven design, that's called a value object.  So how would you implement a value object in C-sharp?  Well, first of all, what is a value object?  So a value object is basically an immutable object  which is based on comparing all the properties.  So if you have a personal name, two personal names,  if the first names are equal and the last names are equal,  they're basically the same thing.  They might be different objects, different pointers,  but from a logical point of view, they're the same object,  which means they have to be immutable  because they can't be changing underneath you.  So here is a C-sharp version.  We have a constructor with the first name, last name.  We have two properties.  I'm using private setters for immutability.  Not really immutable.  I could be using read-only if I was going to be super strict.  But that's probably good enough.  Something I've left off, though, is that personal name  is a reference type, like all classes in C-sharp,  which means if I have two personal names  and I compare them, they're going to compare differently.  So what I have to do is I have to override equality.  So I have to override it, get hash code,  and I have to override equals, and I have to add equals again,  and I have to implement i, equitable, whatever it is.  So there's a lot of code you have to write to do equality.  And this is actually quite bug-ridden code.  I don't know if any people have ever put objects  in a dictionary or a set with a mutable ID  and the hash code's changed and all of a sudden things break.  It's very easy to get this kind of stuff wrong.  So let's compare this with f-sharp.  So in f-sharp, this is your personal name.  You've got a first name and a last name, exactly the same thing,  two properties.  The whole thing fits on one under code.  But of course, I need to do equality as well.  So let me show you the code for equality.  So yeah, there is actually no code for equality  because in f-sharp, classes or types are equal by default.  You don't have to override equality.  So it's the other way around.  If you want them to not be equal, you have to do it to work.  And the best code is no code of all.  If you don't write equality methods, you can't mess them up.  So it's less work for everybody.  Now, in domain driven design, you also  have this concept of an entity object.  An entity object is normally based on some sort of ID.  And here's an example of a person.  And the person ID, if they have the same ID,  they're the same thing.  But the contents of the thing can change.  So this person has changed their name from Alice Adams  to Bill Wobaggins.  And generally, the content is mutable.  That doesn't have to be mutable.  So let's look at the C-sharp code, very same kind of thing,  except I've removed the private setter  to make it a mutable name.  And I have to override equality again.  And now I have to change, subtly change the way I compare things.  Buried in the code is the important part.  Let's look at the f-sharp code.  Now, in f-sharp, if you want to change the way  that equality works, you have to say custom equality.  You have to override equality.  And then you have to get hash code and equals  just like the C-sharp code.  The nice thing about f-sharp, though,  is the person cannot be null.  So you don't have to do any null checking ever,  unless you're dealing with code that's coming from C-sharp,  where you don't necessarily trust it.  So.  But in this case, we're comparing by ID.  But in many situations, you might not want to compare by ID.  Sometimes you might compare by person, by the name.  Sometimes you might compare by ID.  And it may be that you want to use different comparisons  into different situations.  So rather than always having a default comparison,  you can pass in i-comparables or whatever it is.  What I like to do in f-sharp is actually say no equality.  And what that allows you to do is say that you cannot compare  people directly.  You can't say this person is equal to this person.  You can say their IDs are equal.  You can say their names are equal.  But you can't actually, if you actually try and compare them  directly, you actually get a compiler error, OK?  Which is, I think, a very cool thing.  I think most entities should have that by default.  So the other thing in f-sharp is that the person class is  immutable, unlike the C-sharp class.  And let me tell you some of the advantages of immutability.  So if it's immutable, the only way you can change it is make  a new one.  You can't just change the property.  You have to create a whole new person every single time.  And there are some syntax things in f-sharp that make  that not so hard.  But if you do have to create a new person every single time,  the advantage of that is you can validate the data on  construction.  So in the constructor, you can say it's the name blank or  whatever.  And if it's a valid thing, you can return a new person.  And if it's not a valid thing, you can not  return a new person.  And that's the only way you can create a person is through  that constructor.  And that means that any change has to go through that  checkpoint, which means that there's only one place you  have to enforce invariance.  So I don't know if you've ever had code on the setter of a  property.  You've had to check that it's not blank or check that it's  not null.  And then if it is null, what do you do?  You're going to throw an exception, or you're going to  have an object which is in an invalid state.  You don't really have very many good  solutions to that problem.  If you don't allow an invalid object to be created in the  first place, you eliminate a whole class of problems  right there.  So let's have a look at the C-sharp code that we've got  so far.  There we go, the personal name and the person.  So let me ask you a couple of questions.  Do you think this is a reasonable amount of code to  write for these two simple objects?  All right, I think the answer is no.  I think that's way too much code.  And secondly, do you think a non-programmer could  understand this?  If I was showing it to an in-house customer and I say,  have I got the definition of a name right?  Is this what you mean by a personal name?  I think they would say, well, I can't understand all this  weird stuff.  The other thing is you can't really tell which ones are  values and which ones are entities.  You can use market interfaces.  But the important stuff is sort of buried right in the  middle of the code.  It's not at all obvious how they compare the ones of  value type, and it compares on properties.  And the other one is an entity, and it compares on its ID.  OK, let's look at the F-sharp code.  So there's the personal name, and there's the person.  So let me ask you the same two questions.  Do you think this is a reasonable amount of code to  write for a simple object?  And I think, yes, I think there's pretty much a small  amount of code you shouldn't get away with writing.  Secondly, do you think that a non-programmer could  understand this?  If I went to somebody and said, have I got the right  definition for a personal name, like a business analyst or  something, and would they say, yeah, I can understand that?  I don't understand F-sharp, but I can look at this code and  say, yeah, actually you're missing a middle initial, or  you're missing an email address or something.  It's pretty obvious just by looking at it.  You don't have to be an expert in the language to  understand this code.  So comparing C-sharp and F-sharp.  So this is just now, I'm not saying that C-sharp is a bad  language, but I'm saying from the design point of view, if  you're just designing types, I think that F-sharp wins out  over C-sharp.  Value objects are really easy.  Entity objects are really easy.  Value objects by default.  Immutable objects by default.  You can tell them apart, and it's easy to understand by  non-programmer.  So if you do nothing else, you might consider just using F-sharp  for doing your types or your classes.  And it's just an assembly.  You can link it in with your main C-sharp code.  So if you want an easy way to create immutable classes, have  an F-sharp assembly and just do that.  Don't have to write any other F-sharp code whatsoever.  Just do that bit and then use those classes in C-sharp.  So this last thing, whether it's understandable by a  non-programmer, I think that's a really important point.  Again, it's all about communication.  So let's look at F-sharp for domain-driven design.  And like I said, domain-driven design is about  communicating a domain model within the team.  So communication is a hard problem.  If we take this word UNIO-NIZE, what does that word mean?  Well, if you're an activist, that might mean unionize.  If you're chemists, it might mean un-ionize.  So the same word can mean two different things to do two  different people.  So in domain-driven design, there's this concept of a  bounded context, a framework within which the words  mean something.  So if you're talking about social activism, unionize  means one thing.  If you're talking about chemistry, un-ionize  means something different.  So different domains, different bounded contexts, same word.  So it's very important to define the context that you're  using that word in.  So let me give you another example.  SPAM.  So if you run a supermarket, spam means one thing.  And if you're an email admin, spam means another thing.  These are kind of cheap shots.  These are pretty easy.  Everyone knows these ones.  What about products, though?  What does a product mean?  So this is something you might run into.  Like if you're in the sales team, a product is something  you can sell.  But if you manage a warehouse, a product might be a physical  thing that you can put in a box.  And sometimes the things you can sell are not necessarily  the same things that you can put in a box.  And you start getting this miscommunication  between the teams.  So one of the goals of Domain with Design is to define  these contexts and make sure the words are used  appropriately in each context.  Here's another one.  Customer.  You probably run into this one, too.  From a marketing point of view, a customer, if anyone has an  email that you can send them spam to.  If you're in finance, a customer is someone who's  given you money.  It's a different definition.  And it affects your design, because a customer who's  given you money, you might have an account ID, and you might  have a current balance and stuff.  And from a marketing point of view, a customer is just an  email address, and maybe not even a name.  So this brings us to the topic of ubiquitous language.  So if you're working in a domain like chemistry, say,  chemists have these words, like iron, and atom, and molecule,  and polymer, and so on.  Now as developers, if you're working on an application in  the domain of chemistry, it's very important that we use the  same words that chemists use.  We shouldn't talk about molecules as an aggregate of  atoms, and we shouldn't talk about polymers as a linked  list of atom aggregates or something.  Those are techy words.  We should use the same words that the customers use.  So again, part of the process of domain-driven design is to  come up with a set of words that the developers can use and  the domain experts can use, and that we all agree on them.  And then when we talk about a polymer, we have a class called  polymer.  We don't have a class called list of atom aggregates or  something.  So again, the ubiquitous language can look similar in  different domains.  So in the sales domain, you might have something called a  customer and something called a product.  In the warehouse domain, again, you might have something  called a product, but it's a different kind of thing.  So but defining the ubiquitous language in a domain is a  very important part of domain-driven design.  So here is an example of some F-sharp code for a domain.  So this is a domain of a card game.  How can we tell it's about a card game?  Because there's a word at the top that says this is a card  game.  If this was in a different domain, if I was in the domain  of a clothes shop, then suits would mean something  completely different.  And if I was in the domain of the navy or something, then  deck would mean something completely different.  But in the domain of a card game, in the bounded context of  a card game, these are the things that matter.  And so this is the ubiquitous language right here.  So let me just go through this F-sharp code.  The vertical bar means a choice.  So a club or a diamond or a spade or a heart.  The star means a pair in this case.  So a card is a pick one from a suit, pick one from rank.  That's your card.  The list is actually a keyword in F-sharp.  That's very nice.  And this one with an arrow is a function.  So this means to deal something.  You start with a deck.  The one on the left side of the arrow is the input.  On the right hand side of the arrow is the output.  So you start.  The input is a deck.  The output is a different deck with a missing card plus a  card on the table.  So that's the output.  So that's the entire domain on one page.  So let me ask you the same questions.  Is this the reasonable amount of code to write for this  domain?  I've got nine classes on one page.  So I think that's pretty good.  In C-sharp, if I was doing this, there would be nine files  in a folder, probably.  Do you think a non-programmer could understand this?  If I had left off something like the king, do you think I  could show this to a non-programmer and say,  have I left all the cards right?  And they would say, yeah, no, you left off king.  It's like, oh, thanks.  It wouldn't be buried in some enum somewhere.  Another important point about this code is there's nothing  about databases here.  There's nothing about user interface.  This is persistent Ignoment.  Persistence Ignoment.  There's nothing about how it gets stored.  I don't care whether you store this in a SQL database,  whether you store it in a file system.  If you want to be web scale, you can store it in Mongo.  It doesn't really matter.  It's not part of the domain how it's stored.  And the other thing about this code is this is code, and it's  a design as well.  It's a design and code at the same time.  And that is one of the agile philosophies, really, is that  the most accurate thing to represent your design is the  code.  Comments go out of date.  Documentation goes out of date.  The only thing that is the truth about your application  is the code itself.  So it's nice if your code can actually represent your  design in a nice way.  And this is actually not pseudocode.  This is compilable code.  I could take this code, stick it in Visual Studio, and run it,  and get some stuff out.  So this is not pseudocode.  So I think that's really quite a powerful thing.  If you do this kind of approach, you don't need to have  your mail diagrams.  OK.  No new mail, no documentation, just the code itself.  The code acts as documentation.  If you change that code, at least you add a new type to a  new kind of card, for example, your code will fail to  compile because it's compilable code.  Right, so that's the sort of introduction to domain driven  design.  And let's talk about the F-sharp type system.  So the F-sharp type system is very different from what you're  used to in C-sharp.  So in C-sharp, you have classes.  In F-sharp, you have types.  Types are not the same thing as classes.  And the F-sharp type system is called an algebraic type  system, which is the same type system that's used in Haskell,  and the same thing that's used in OCaml, a couple of other  languages, very common in functional languages.  So algebraic is another one of those mathematical words.  So I'm going to use the word composable instead.  So it's a composable type system.  So unlike objects or classes, you can actually compose the  types together to make new types.  So what do I mean by composable?  It's like LEGO, right?  If you take two LEGO bricks and you stick them together,  you've got another thing that you can then stick other  things to it.  You can build up complex things by gluing  smaller things together.  So that's what composable means.  So if you do have two smaller things, how do you glue them  together to make a bigger thing?  Well, in algebraic types or composable type system, there  are basically two ways you can glue them together.  You can either multiply them together.  So a new type is an old type times another old type.  Or you can add them together.  So a new type is a type plus another type.  Now at this point, you might be thinking, well, that's just  crazy.  How can you add two types together?  How can you multiply two types?  What does that even mean?  That just sounds silly.  But I think if you just hold on another five minutes, I think  all will become clear.  So let's start off with the times.  So here's a very simple function.  So a function is basically a black box.  It's got input and it's got an output.  That's all the function is.  So I'm going to take the function add1, for example.  So on the input, I have a list of numbers, integers.  On the output, I have a list of integers.  And the way you write that in F sharp is int arrow int.  So int is the input function output is an int.  So that's pretty straightforward.  Now what happens if we want to add a pair of numbers together?  So if we add one to it, the input is a pair and the output  is added together.  So the output is easy.  We can say the output's an int.  But what's the input?  What kind of type is that input?  Now we could define a class called pair,  but that's got nothing to do.  It's not built from smaller pieces.  I want to actually create this type  by adding two other types or combining two other types.  So let's look at how we can do that.  So let's think about what a pair is.  So a pair basically means you pick one from the first pile  and you pick another one from the second pile, right?  So one column and the second column.  So let's say there are four numbers.  Obviously there are like 64k of four gig numbers,  but let's say there are four numbers only.  So you can pick four from this pile  and you can pick four from the second pile.  How many possible pairs are there?  There's four times four, 16 possible combinations, yeah?  So that's multiplying them, right?  Four times four is 16.  Here's another example.  Let's say you have a pair of booleans.  So true false and true true and false false, right?  So again, the first column is you pick one  from two possibilities and the second column  is you pick one from two possibilities  and the total number of combinations is two times two.  So the way you get the pair is by multiplying the first column  by the second column.  So that's the total number of possibilities.  So in fact, that's exactly how you do it in F-sharp.  You say a pair of ints is written as int star int, int times int.  And a pair of booleans is written as bool star bool.  So literally multiplication, OK?  So you can see where that's coming from.  It looks a little bit weird at first,  but it's actually quite sensible if you think about it.  All right, well, that seems kind of academic.  Maybe say, OK, well, it's kind of theoretical.  Let's look at a real example of how you might see it  in a real business application.  So let's say you have a bunch of birthdays.  So Alice was born on January 12th  and Bob was born on February 2nd and so on.  How can I represent these birthdays using the type system?  Well, we have a set of people.  The first column is a set of people,  all the people in the world.  The second column is a set of all the dates in the world.  And every possible combination of a person and a date  is multiplication.  So that's how I get the birthday type is  the every possible combination of the people type and the date  type.  So in code, in F sharp code, you would write it like this.  Type birthday equals person times date.  And that's how you create a new birthday type.  Right, so that's one kind.  So that's what they call a product type or a multiplication  type.  What about the other one where you're adding things together?  So let's look at how you might represent a choice.  So here's a function that says whether you have a fever or not.  You're passing some sort of temperature.  And if your temperature is more than 37 and 1⁄2 or 38,  where it says, OK, you've got a fever.  And if it's in Fahrenheit, there's  100s, say, and you get a fever.  So how can I document what the input is?  Well, the output's tabooly, so that's easy enough.  But the input is a choice.  I can either pass in a Fahrenheit temperature  or I can pass in a Celsius temperature.  How do I represent that?  So if you think about it, this is the same kind of thing.  I've got a list of possible temperatures in Fahrenheit.  And I've got a list of possible temperatures in Celsius  or centigrade.  But this is slightly different because I pick one  from the first pile or I pick one from the second pile.  So let's say there are four in the first pile  and four in the second pile.  How many possible combinations are there?  There's actually only eight.  I pick one of these four or I pick one of these four.  So there's eight possible combinations.  So that's addition.  It's what they call a sum type.  And how do you represent it in F-sharp?  They're both, say, integers.  So you have to have some way of differentiating the integers,  so you tag them with a little symbol.  So I'm going to tag the Fahrenheit ones with the letter F.  And I'm going to tag the Celsius ones with the letter C.  And then you write that in F-sharp as the temperature  type is a choice between an integer, which is tagged with F,  and a, say, a float that's tagged with C.  So that's how you'd write this choice type in F-sharp.  It could be one or the other, but not both at the same time.  All right.  So again, that's maybe a bit strange.  But let's have a look at a real example.  So here's a payment method.  So as an e-commerce business or maybe as a shop,  I can take cash, I can take checks,  I can take credit cards, say.  And you'd represent that as three different choices.  I can take cash, I can take checks,  and I can take credit cards.  Three different choices right there in front of you.  One of the nice things about these choice types  is you can have extra data attached to different pieces.  You can think of them as different constructors.  You might have a cash constructor and a check constructor.  And the cash, you don't need any extra information.  For a check, you might need the check number.  And for a credit card, you'd need the card type  and the card number, so a pair.  And when you actually use these things,  you want to look inside and see which particular choice was  actually used.  So when, let's say, you want to print the payment method  on a receipt or something.  What you do is use a match statement, which is the F-sharp  equivalent of a switch, basically, or case statement.  And if it's cash, you say print cash.  If it's a check, you say pay by check.  And one of the nice things about the matching  is it extracts the information inside at the same time.  So you match and you suck out the data.  And finally, if I pay by card, I can get the card type  and the card number at the same time.  So that's how choice types work in F-sharp.  And it's very cool that you do this match and assignment  in one step.  So these are not just enums, like in C-sharp,  because enums are just integers behind the scenes.  This has, these are more like subclasses, and each subclass  has its own data.  So you might say, well, why don't you model it with  inheritance?  Why don't you use subclasses?  Why have this special kind of choice type?  So how would you implement this in C-sharp or an OO language?  So what you'd probably do is have some sort of interface or  abstract-based class that represents all of them, an  I payment method.  And then you'd have a cash class or subclass with a  constructor, you'd have a check class that had its own data,  and you'd have a credit card class that had its own data.  So the problem with this approach is that the interface  has no common behavior really between the two.  I mean, you might say, well, yeah, the printing method is a  common behavior.  But that's really in that context.  I don't think it should be part of the core domain class  that it can print itself on a receipt.  That's really mixing, you know, that's not separating your  concerns well enough.  You should be able to print it on a receipt is a different  thing.  There's actually no common methods that  belong to the domain.  The other nice thing about the F-sharp approach is the  exadata is really obvious.  If I say, well, what do I need to store a credit card?  It's like, well, I need a card type and I need a card number.  Is that obvious from the C-sharp codes?  It's kind of buried in the constructor.  It's buried in the properties.  It's not really obvious where it is.  It's basically scattered around in many locations.  And in C-sharp, that would be four different files, probably.  You could have one class per file, four different files.  In F-sharp, it's four lines, four lines of code in one place.  The other thing about the F-sharp code is it's closed,  which means that you can't add a fourth option.  That is your limit.  If you want to add a fourth option, you can, but all your  code will break.  And then you have to fix up your code, which I think is a  good thing.  If you add a new kind of payment method, you want your code  to break until you've handled that particular new payment  method in all your class, in all your code.  In OO, in the OO version, anything that implements the  I payment method is valid.  So you might get an unpleasant surprise.  I might implement an evil payment method.  As long as it implements the interface, it's totally valid.  Now in some cases, you might want open.  You might want to have, oh, anybody can implement this  interface and it's fine.  I trust them.  But in business logic, most of the things are actually quite  restricted.  You have a restricted set of options like payment methods.  And adding a new one is actually something you want to  know about.  It's not something that you should just slip in behind the  scenes without telling anybody.  So what are types for in functional programming?  It's an annotation to a value for type checking.  So here we go.  It's just like in C-sharp.  You say this is an int.  It takes an int and it outputs an int.  But it's also a domain modeling tool.  So in this case, I can tell you that to deal something, you  have a deck of cards.  And you input this and you output that.  So you can actually model the domain using the types.  And it's both at once, which means that your domain  modeling tool is also compiled into your code.  So your code can never match the domain.  So I think of a static type system like this is almost  like having compile time unit tests.  If I have a unit test that says, oh, a payment card must  always have a card number or something, I don't need to have  a unit test for that.  It will not compile if the code doesn't match the domain.  So it's a compile time unit test.  So type all the things.  It's one of the mottos of the static type people, especially  the functional programmers.  All right, so what can we do with this type system?  Let's actually put it to use, do something useful with it.  I'm going to start with optional values.  This is a really common case.  So here we have our personal name.  And the middle initial is optional.  And the first and last name are not optional.  And I can't tell.  So can I use the type system to indicate that?  So let's go back to our strings.  So let's say we have a function that's the length of a  string, really, really simple function.  And the input is a string, and the output is an int.  That's a very simple function.  The only problem is that we have null in this list of  strings.  And null is evil because it's pretending to be a string.  You cannot use null as a string.  If I say setPhase as to null, that doesn't make any sense.  It's illogical.  So null is not really a string.  It's in the pile of strings.  If I say to null, are you a string?  I say, yeah, yeah, I'm a string.  And then you say, well, give me your length.  And you say, ha, you know, I'm going to crash your  application now.  And it's like, well, you told me you're a string.  It's like, well, yeah, I'm pretending to be a string, but  I'm not really.  So I think of null as like Saruman.  OK, it's going to betray you behind your back.  It pretends to be one thing, but it's something evil.  So in F sharp, null is not allowed.  Null is not a valid string.  Well, actually, in F sharp, unfortunately, it is a valid  string because of the way that it has to be compatible.  But most of the classes you create, your own classes in  F sharp are not allowed to be null.  So you never have to deal with nulls in general.  So no nulls.  So if you don't have nulls, what can you do instead?  So we have a list of strings here.  And null is not in them.  But we want to say, well, maybe the string's missing.  So how can we indicate that?  Well, we've already seen how we can do that because we have  this choice between something and nothing.  So the way we represent that in F sharp is exactly that thing.  You have a choice between a string, a valid string, which  is not null, and nothing at all.  And it's a sum type.  It's a choice type.  And we tag the strings with some string.  And we tag the missing with nothing.  So you see the some string or it's nothing.  And we write that like that.  So it's either some string or it's nothing.  So that's a type that you would see a lot in F sharp.  And you say, oh, that's really cool.  You have the optional string.  And then, oh, I want optional int as well.  Oh, optional Boolean's really important.  So you start having all these optional types floating around.  And at some point, you say, there must be an easy way to  that.  So let me define a generic type that takes a type parameter.  So in this case, it's an option of any type.  And it's either some of that type or it's nothing, none.  And that type is actually built in to F sharp.  So this option type is built in.  And it's used a lot in the F sharp libraries.  So with this option type, we can rewrite the middle initial  to say it's an option of a string.  And in F sharp, you can actually have a nicer syntax  where you call it a string option rather than  an option of a string.  So I think that's actually much nicer if I was showing that  to someone I say, look, it's an optional string.  I think it's pretty easy to understand.  All right, the next kind of type I'm going to talk about is  what I call single choice types.  And this is an example of a single choice type.  It's something and it's choice A of something.  But there is no choice B. There's only one choice.  Why would you only have one choice?  So let's look at some examples.  Here's an email which has only got one choice of an email.  Customer ID has only got one choice called customer ID.  Why would you only have one choice?  What possible use is that?  So think about this for a second.  Is an email address just a string?  All right, in your domain, can you add hello to it  without breaking code?  Can you reverse it without breaking stuff?  An email address isn't a string.  Once you've validated it, you really shouldn't be messing  with it.  You shouldn't be adding things and subtracting things.  You shouldn't be reversing it.  It's like it's a thing.  It's an email address.  It happens to be represented as a string, but it isn't really  a string in your domain.  Is a customer ID just an int?  Can you add five to your customer ID and still get a valid  customer ID?  Probably not.  I mean, maybe you can.  But your customer IDs, they might be  represented by ints in your database, but they're not really  ints in a domain.  So by using single choice types, you can keep these types  separate from their underlying representation.  So for example, if you have an email address which is  represented by a string and a phone number which is  represented by a string, by wrapping them in a single  choice, you've now made them different types, distinct  types, and you can no longer compare an email address with  a string, and you can't compare it with a phone number, and  you can't compare a phone number with a string.  They're just completely different types all together.  And you'll get compile errors, compile errors if you try and  compare them.  Similarly, if you have a customer ID and an order ID, and  this is a very common problem, they're both represented by  ints, and in your codes, you want to keep them separate in  your query strings to your DAO or whatever.  They're not the same thing.  If you try and compare them, you should actually get a  compile time error.  So are you familiar with the phrase primitive obsession?  So the primitive obsession is when you use ints instead of  domain objects like this.  You shouldn't be using ints to represent customer IDs.  The other nice thing about using a special type for the  email is you can wrap it in a constructor that does  validation.  So an email address is not just a normal string, it has to  have an at sign in it, say.  So very crude validation is that it has to match some sort  of regex.  So in this case, it has to have an at sign in it.  So in the constructor, you can say, well, if it does match  that regex, then you return a new email address, a wrapped  email address.  But here's the problem.  What happens if it doesn't match the regex?  What are you going to do?  You're going to return null?  No, because null is not a valid email address.  You're going to throw an exception.  Well, that seems a bit harsh.  Just because I passed in a invalid email, it's like,  can't you just give me something more useful that I  can process as a, well, they have to catch exceptions  all the time.  Well, I think we already seen the answer to this.  You use the option type.  So if it's a valid email, you say, yes, it's an email, some  email, and if it's not a valid email, you turn nothing.  It's like not a valid email.  But this is a proper type.  You're not throwing exceptions.  You're not returning null.  And you can tell what it does, unlike the null case or the  exception case, you can actually tell what it is by  looking at the signature for the function.  So you might think that the signature is, give me a string  and I'll give you back an email address.  And that would be true if I was using nulls, and it would be  true if I was using exceptions.  But I'm not using either of those.  I'm using options instead.  So the signature says, you give me a string.  I might give you back an email address.  I might not.  You'll have to handle both cases, because depending on  what string you give me, I might give you back nothing at  all, because it's not valid.  And you are forced to handle both cases.  When you take this code, at some point in your code, you're  going to have to say, well, is it something or is it  nothing?  But you can pass it around.  You don't have to handle it straight away.  It's not like an exception or a null.  You can pass it around until somebody has to deal with it.  So let's look at another example.  Here's a string 50.  In this case, I want to make sure that the string is  constrained to be less than 50 characters long.  So again, I have a little in the constructor.  I have a little test.  Is it less than 50?  If it is less than 50, I can return a valid string 50.  And if it's not a valid, if it's not, I return nothing.  So the constructor, the signature for the constructor  looks like this.  Pass in a string, and I might get better string 50 or I  might not, depending on whether you passed in a string  that was too long or not.  Here's another example.  If I say this is an e-commerce system, and I've  actually seen this in a real e-commerce system, what is  wrong with that picture is that I have like a million  things in my shopping cart.  That should not be possible.  I shouldn't really be able to add a million things.  Or maybe I can, but most shopping sites will not let me  do that, but they might let me do that because somebody has  only represented it by an int behind the scenes.  So what I really should do is create a new type called an  orderline quantity.  It wraps an integer.  It's not a normal integer.  It can't be negative.  It can't be 2 billion.  There's going to be some sort of constraints on it.  And so the nice thing about an F-sharp is I can create a  new type just for this domain.  It's because it's one line of code.  It's really easy.  In C-sharp, I should probably do the same thing too, but I  probably can't be bothered because it's a lot of work.  So most people don't actually do this.  And this is the kind of thing where you get bugs in your  code because you represent it as an int.  And then you have to have special code to handle  negatives, special code to handle more than 1,000 or  something.  Don't have that code.  Just don't allow it to be created in the first place if  it's not the right number.  So in this case, it has to be greater than zero.  So even zero is not a valid number for a  shopping cart quantity.  So if I do something with it, I'm going to have to handle the  case where I guarantee by having this type is  between 1 and 99.  I literally cannot have a zero quantity item in my basket.  Yes?  AUDIENCE member 1, question.  The question is, where would that constructor be  implemented?  The answer is it would be implemented normally near  the type itself.  So in Fsharp, you have a module which is basically a  namespace or a kind of grouping of codes.  And what you can do is you can actually make sure that the  constructor is the only way.  You can hide the built-in constructor, and you can make  sure that people are forced to go through that constructor.  And that would be the only way.  It's like having a private constructor and then having a  public factoring method.  And you'd put them together in the same file.  Does that make sense?  So again, here we return something or we return nothing.  So every time I add something to my order line quantity, I  have to take into account that I might get something back  which isn't an order line quantity.  So if I subtract 1, I might get nothing.  And in my code, I'll have to say, well, what happens if I  get nothing back?  Well, OK, maybe I have to move that line from the basket.  I'm forced to deal with that code.  It reduces bugs just by doing this.  So let's have a look at our code quickly, the challenge.  So our challenge was how do we do optionals?  And we're going to rewrite this now to use constrainString,  string50 rather than just a plain old string.  So that's a lot easier to see what's going on.  And then the other thing, one of the questions is how do I  make it very clear which sets of properties have to be  grouped together for currency purposes?  And it's really easy in F sharp just to create two new  little small types.  And then the big type just contains the small types.  And because it's really easy to do, I mean, this is eight  lines of codes.  And you can all be in one file.  You don't have to create three separate classes and three  separate files.  So in F sharp, you tend to get a lot more small types than in  C sharp just because it's so easy to do.  There's one thing we have not talked about, which is this  email verified.  So this is this Boolean.  It's only allowed to be set to true if the email has been  verified.  So let's have a look at that for a second.  So we have some business rules around this.  The first business rule is if the email is changed, you have  to set it back to false because it's not verified.  And the only way you can set it to true is if it's been  verified by some sort of verification service.  You know, they click on an email and there's a hash in the  email and you check that the hash matches.  And if it's OK, then it's all good.  So those are business rules.  Now, again, normally in C sharp, those business rules  would be sort of embedded in the code.  My question is, can we embed those business rules in the  type system?  So it's compile time error to get it wrong.  So the compiler will not let you set that to true by  mistake.  Is that even possible?  So let's see.  So this is not very good.  This is terrible because anybody could set it to true and  say, oh yeah, this is a verified email address, even  though it isn't.  So how would you do this in F sharp?  Well, the first thing you'd do is you would wrap the email  address in a new type called a verified email address.  And this is one of the things you tend to get in functional  programming, which is any time you have a problem, you  solve it by wrapping it in another type.  There's no problem that can't be solved by wrapping it in  another type, basically.  So you tend to have these types within types within types.  But because it's a one-liner, it's really easy to do.  And it's equally easy to unpack it as well.  So now I have a difference now between a normal email address  and a verified email address.  They're now different types, and they can't get mixed up.  That's good.  And how do I get one of these verified emails?  I have an email service, a verification service, and it  takes in an email address as input, and it takes in some  sort of hash, which you pass in, and it checks the hash.  And if it matches the email, it says, yeah, this is a  verified email.  Or it might say, actually, it's not.  So that's why it's an option.  I can tell straight away from this service that it might  not work.  So email input, an optional verified email is the output.  And then what I do is I define my email information as a  choice.  I say either it's an unverified email or it's a  verified email.  If it's an unverified email, it's just a normal email address.  If it's a verified email, it has to be one of these special  verified email addresses.  And the only people who can create this is this  verification service.  I can't create one of these things.  Only the verification service can.  So when I'm coming along and I want to change the email  address, I can change it to unverified, but I can't change  it to verified.  So this is a way of guaranteeing in the type system  that I can't have an accidentally verified email address.  So I've got rid of the Boolean and replaced it with two  choices.  And that's a very common thing you'll see in functional  code is every time you have these Boolean flags, like has  it been shipped, has the order been paid, all that kind of  stuff, those are replaced by a set of states, a set of  choices, and each choice might have different types  associated with it.  So let's go back to our original challenge.  Here is our email address.  We've broken up into we had one type originally, and now  we've got five, six types plus the verification service.  The questions were, again, which values are optional, what  are the constraints, which fields are linked, and what is  the domain logic.  So which values are optional?  Is this now clear from the code?  I could show this to somebody and say, which one's  optional?  And you say, yeah, the middle initial is optional.  The other ones are not optional because they're not  allowed to be null, remember?  So they're required.  The first name is, by definition, required.  If I don't say it's optional, it has to be required.  The constraints now, I've replaced it with these  special types called string 50 or string 1.  And the email address, again, is a constrained type.  So if I have a first name, I know it's going to be less than  50 characters.  I can't, when it comes time to put it into the database, I  know that I'm never going to have some database bounds  exception that I have to handle because I know it's going  to be within the right length.  Which fields are linked?  Well, that's easy.  I just created two little smaller types.  That was trivial.  And finally, it's the domain logic clear.  And it is, I think, because it's now very clear that I have  unverified and verified ones.  And it's also very clear that the verified email is a  different kind of thing than a normal email.  What's interesting about this is not only that I've now  encoded all those rules in the design, but the ubiquitous  language has evolved, too.  So in my design, I now have something called an email  contact info.  I have something called a verified email address.  So these are things that I didn't have in the original  design.  But in fact, these actually do represent concepts in the  domain.  If I was talking to a business and say, yeah, we have  verified emails and we have non-verified emails.  So I've actually documented that now, which the original  design didn't have.  And it's, of course, it's compilable code.  This is not pseudo code.  This is not a URL diagram.  This is real code that compiles.  And it would be basically the first file in your F-sharp  project.  So if you don't mind hanging around for another couple  of minutes, I just want to do one more thing, which is this  concept called making illegal states unrepresentable.  So let's say that some time passes and we now have an  address as well as an email.  This is the requirements are changing now.  And we have a new business rule that the contact must have  an email or a postal address.  So I need to be able to contact you somehow.  That's a fair enough requirement.  So does this type actually meet that requirement?  And the answer is no, it doesn't.  Because the way it stands right now is both the email and  the address are required.  They're both required fields, right?  They can't be null.  So they're both required.  So this doesn't allow for the fact where I have one but not  the other.  All right, well, I'll make them both optional.  So yeah, does that solve it?  No, that doesn't solve it either, because now they could  both be missing.  So the business requirement is you have to have one of them.  You can't have them both missing.  So how can I encode that business requirement?  Again, in C-Shark, we'd probably have some code varied in  a way, well, if they're both null, then throw an exception or  return an error or something.  It'd be nice if we could actually encode that in the  type in such a way that you didn't even have to deal with  that case.  You could not literally represent that.  So that is this concept called make illegal states  unrepresentable.  If you can't do something, don't even allow it to be in the  type system.  In this design, I could make them both optional or both  null.  It's like, don't allow that to happen.  So how can I prevent that from happening in the type system?  Well, if you think about it, that business rule says that  you either have an email address or you have a post  address or you have both.  That's what the business rule says.  There's only three choices, not four choices, not two  choices.  Well, how would you represent that?  Well, as I say, you always wrap everything in a type.  You create a new type with three choices, where it's  email-only or address-only or an email and postal address.  So I now have a type that represents that business rule.  And I literally cannot have both of them missing, because  it's not one of the choices in the type.  But so by defying a type like this, I can actually hard  code my business rule into my design in such a way that I  literally cannot mess it up.  You cannot have a bug from having them both missing,  because there is no way to represent them both missing.  And then I just replaced my email address as just one  new type now.  So what I've done is I started with them as separate  things, and I've merged them into a single thing, which now  has a set of choices.  So static types are really awesome, almost as awesome as  that.  One final thing, let's say that that's a rather restrictive  thing, an email address or a postal address.  What they probably mean is the business probably didn't  really mean that.  What they probably meant is there's some way that you  have to have at least one way of being contacted, because  you're a contact.  I should be able to contact you in at least one way.  So rather than doing that, what I might do is say, well,  this is different ways of contacting you.  I can contact you with an email, or I can contact you by  sending you a letter.  And then in the contact type or structure, I have a primary  contact information and a secondary contact information.  And the primary contact information is required, and  the secondary contact is optional.  So again, the type system has created, again, it might be  something that when you talk about this, the business  zone.  So yeah, of course, we have a primary contact and a  secondary contact.  It's a new part of the domain language now.  You've got a part of the ubiquitous language to have a  concept of a primary contact.  And again, the primary contact is not allowed to be null, so  it's by definition required.  It's very clear from this code what the business rule is.  So I talked about the challenge.  I talked about ubiquitous language, self-documenting  designs, algebraic types, designing with types, using  options, single case unions, and making illegal states  unrepresentable.  So hopefully this all makes sense now.  I haven't talked about states and transitions.  That's a really important thing.  Services, CQOS, how you do the functional approach to doing  use cases, and domain events, and error handling.  So if you're worried about using F-sharp, I actually think  you should just try it out.  Like I said, even if you just use the type system and don't  write any code, the support of Microsoft, if you want to go  mobile, it's built into Xamarin Studio.  That gets you F-sharp on millions of platforms.  So it's a very safe choice.  If you need to persuade your manager, I have some examples  at FP Bridge.  And there is the link to my site, F-sharp on Twitter if  you've got any questions.  Contact me on Twitter.  And if you need any help with F-sharp, contact me at my  consulting business.  Thanks very much.  If you have any questions, please come and see me  afterwards, and please remember to put the review  things, yes.  And there are some more F-sharp things tomorrow  morning, by the way.  Two F-sharp talks tomorrow morning if you're  interested in F-sharp.  Please go to those.
Scott_Wlaschin_-_Domain_modelling_system_0_2387.png Scott_Wlaschin_-_Domain_modelling_system_2388_4451.png Scott_Wlaschin_-_Domain_modelling_system_4452_7583.png Scott_Wlaschin_-_Domain_modelling_system_7584_8339.png Scott_Wlaschin_-_Domain_modelling_system_8340_8651.png Scott_Wlaschin_-_Domain_modelling_system_8652_9347.png Scott_Wlaschin_-_Domain_modelling_system_9348_10043.png Scott_Wlaschin_-_Domain_modelling_system_10044_10439.png Scott_Wlaschin_-_Domain_modelling_system_10440_11411.png Scott_Wlaschin_-_Domain_modelling_system_11412_11543.png Scott_Wlaschin_-_Domain_modelling_system_11544_13223.png Scott_Wlaschin_-_Domain_modelling_system_13224_14411.png Scott_Wlaschin_-_Domain_modelling_system_14412_14519.png Scott_Wlaschin_-_Domain_modelling_system_14520_14627.png Scott_Wlaschin_-_Domain_modelling_system_14628_15035.png Scott_Wlaschin_-_Domain_modelling_system_15036_17447.png Scott_Wlaschin_-_Domain_modelling_system_17448_19499.png Scott_Wlaschin_-_Domain_modelling_system_19500_19595.png Scott_Wlaschin_-_Domain_modelling_system_19596_20279.png Scott_Wlaschin_-_Domain_modelling_system_20280_20711.png Scott_Wlaschin_-_Domain_modelling_system_20712_21503.png Scott_Wlaschin_-_Domain_modelling_system_21504_22175.png Scott_Wlaschin_-_Domain_modelling_system_22176_22607.png Scott_Wlaschin_-_Domain_modelling_system_22608_22703.png Scott_Wlaschin_-_Domain_modelling_system_22704_23315.png Scott_Wlaschin_-_Domain_modelling_system_23316_23531.png Scott_Wlaschin_-_Domain_modelling_system_23532_23999.png Scott_Wlaschin_-_Domain_modelling_system_24000_24635.png Scott_Wlaschin_-_Domain_modelling_system_24636_25307.png Scott_Wlaschin_-_Domain_modelling_system_25308_26591.png Scott_Wlaschin_-_Domain_modelling_system_26592_28319.png Scott_Wlaschin_-_Domain_modelling_system_28320_29771.png Scott_Wlaschin_-_Domain_modelling_system_29772_30875.png Scott_Wlaschin_-_Domain_modelling_system_30876_32495.png Scott_Wlaschin_-_Domain_modelling_system_32496_32807.png Scott_Wlaschin_-_Domain_modelling_system_32808_33587.png Scott_Wlaschin_-_Domain_modelling_system_33588_37583.png Scott_Wlaschin_-_Domain_modelling_system_37584_42371.png Scott_Wlaschin_-_Domain_modelling_system_42372_44015.png Scott_Wlaschin_-_Domain_modelling_system_44016_44519.png Scott_Wlaschin_-_Domain_modelling_system_44520_45455.png Scott_Wlaschin_-_Domain_modelling_system_45456_48791.png Scott_Wlaschin_-_Domain_modelling_system_48792_49331.png Scott_Wlaschin_-_Domain_modelling_system_49332_50855.png Scott_Wlaschin_-_Domain_modelling_system_50856_59675.png Scott_Wlaschin_-_Domain_modelling_system_59676_59843.png Scott_Wlaschin_-_Domain_modelling_system_59844_61223.png Scott_Wlaschin_-_Domain_modelling_system_61224_61415.png Scott_Wlaschin_-_Domain_modelling_system_61416_62039.png Scott_Wlaschin_-_Domain_modelling_system_62040_62627.png Scott_Wlaschin_-_Domain_modelling_system_62628_62855.png Scott_Wlaschin_-_Domain_modelling_system_62856_63275.png Scott_Wlaschin_-_Domain_modelling_system_63276_63551.png Scott_Wlaschin_-_Domain_modelling_system_63552_64127.png Scott_Wlaschin_-_Domain_modelling_system_64128_65387.png Scott_Wlaschin_-_Domain_modelling_system_65388_65747.png Scott_Wlaschin_-_Domain_modelling_system_65748_66779.png Scott_Wlaschin_-_Domain_modelling_system_66780_66923.png Scott_Wlaschin_-_Domain_modelling_system_66924_67403.png Scott_Wlaschin_-_Domain_modelling_system_67404_67499.png Scott_Wlaschin_-_Domain_modelling_system_67500_68195.png Scott_Wlaschin_-_Domain_modelling_system_68196_70115.png Scott_Wlaschin_-_Domain_modelling_system_70116_70655.png Scott_Wlaschin_-_Domain_modelling_system_70656_73043.png Scott_Wlaschin_-_Domain_modelling_system_73044_73151.png Scott_Wlaschin_-_Domain_modelling_system_73152_73871.png Scott_Wlaschin_-_Domain_modelling_system_73872_74579.png Scott_Wlaschin_-_Domain_modelling_system_74580_75515.png Scott_Wlaschin_-_Domain_modelling_system_75516_77771.png Scott_Wlaschin_-_Domain_modelling_system_77772_78239.png Scott_Wlaschin_-_Domain_modelling_system_78240_78503.png Scott_Wlaschin_-_Domain_modelling_system_78504_79403.png Scott_Wlaschin_-_Domain_modelling_system_79404_80651.png Scott_Wlaschin_-_Domain_modelling_system_80652_83831.png Scott_Wlaschin_-_Domain_modelling_system_83832_83891.png Scott_Wlaschin_-_Domain_modelling_system_83892_83975.png Scott_Wlaschin_-_Domain_modelling_system_83976_86999.png Scott_Wlaschin_-_Domain_modelling_system_87000_87227.png Scott_Wlaschin_-_Domain_modelling_system_87228_88175.png Scott_Wlaschin_-_Domain_modelling_system_88176_89375.png Scott_Wlaschin_-_Domain_modelling_system_89376_89651.png Scott_Wlaschin_-_Domain_modelling_system_89652_89711.png Scott_Wlaschin_-_Domain_modelling_system_89712_91199.png Scott_Wlaschin_-_Domain_modelling_system_91200_91667.png Scott_Wlaschin_-_Domain_modelling_system_91668_92819.png Scott_Wlaschin_-_Domain_modelling_system_92820_93263.png Scott_Wlaschin_-_Domain_modelling_system_93264_93539.png Scott_Wlaschin_-_Domain_modelling_system_93540_93875.png Scott_Wlaschin_-_Domain_modelling_system_93876_94115.png Scott_Wlaschin_-_Domain_modelling_system_94116_95147.png Scott_Wlaschin_-_Domain_modelling_system_95148_95195.png Scott_Wlaschin_-_Domain_modelling_system_95196_95496.png