 I'm going to talk about idiomatic Scala. Your options do not match. So who here has ever seen some code that looks like that? If some boolean equals true, return true, else return false. And of course, I use some JavaScript syntax here because Scala developers do not do that. Yeah, so we know this code is just silly. Even I would say I'm a terrorist, very novice. Anyone would probably just write return some boolean, of course. Now, raise your hand who has seen or even written some code like this, option match case some, case none. More hands, more hands, more hands, don't be shy. I know everyone did, everyone. OK, so I really don't like this code. It's a bad pill of mine. On my code reviews, I never let that go. And the reason I don't like it is because to me it feels too literal, unsophisticated. It's just not the right level of abstractions, just not high level enough. It's not declarative enough. It feels very procedural. If you squeeze your eyes and look, it feels like if some else, if none. It's even worse than if else because you still have to put the if none there. It's too literal. I don't like it. But you may say, well, but pattern matching is functional. Pattern matching is a good thing. Yes. Basically, all the talks I've been through since yesterday talk about pattern matching. And indeed, pattern matching is functional. But you know what? Higher other functions are functionaler. Higher other functions are the functionalist things we have. The good news is that pattern matching option it's almost never necessary. Because usually you have cleaner and more expressive ways to get to the same results. So if you go to the Scala doc page for the option class, this is what you're going to see there. The most idiomatic way to use a Scala option instance is to treat it as a collection or monad and use map, flat map, filter for itch. A less idiomatic way to use Scala option is via pattern matching. So it's not me who is saying that. It's the Scala doc. It's the word, OK? So an expression of the form option match case, some case none, can be written as some option map full get or else bar. That's it, OK? And the talk is over. So that's all you have to do. Well, actually not. But there are better ways. So since Scala 210, there is an alternative that it's even more concise. You can use fold. So you can have option dot fold bar and full. So just pay attention that full and bar got reversed now. None come first, some come second, OK? And fold gives additional benefits compared to pattern matching and map get or else. Because it's even more type strict than the other two. So for instance, if I have a pattern match here and I did a mistake, I have an int and I'm putting a string there by mistake. The compiler will happily accept that. And both A and B are going to have a type of any and a value of two. So if I run this code, we can see that A is of type any value two, B is of type any value two, just like I said. So this is the Scala compiler telling us that this is fine, it's acceptable code. But if I try to do the same using a fold, I'm going to get a type mismatch error. So the compiler will not going to accept my string being mixed together where an integer was expected. That by itself should be reason enough so it's more type safe. But we still can do a lot better than use fold. No, we do not need to stop there. Option offers us a few dozen methods and higher the functions that can be used to better express some more specific transformations. So for instance, if I have an option fold false true, just it's equivalent to option is defined. I just call option is defined. And if it's unknown, it's going to return false. If it's a sum, it's going to return true. So let's see some example of those pieces of code. Just a few definitions here. I'm going to have three variables, A, empty, and non. So one is an option which contains the string A. The other is an option that contains an empty string. And the other is just a non. And I'm defining two functions here. One is a predicate that will test if the string is empty. And the second one is a transformation function that will convert the string to uppercase. So this is the base test case that I'm going to use. So let's get this executed. R is fine. And just to show you that I'm not lying, so you do not need to trust my word here. I created a helper function to test it for me. I don't want to be testing everything by hand. Let's get this evaluated. So just to show you that my test method works, it's not lying. I created two functions here. And you see that they do return the same case, the same value for non. But they are going to return different values for non. So when I run that, oh, sorry. So now I'm going to test it. So I can see that some A is equal for both. Some empty string is equal for both. But the case for non, they're different. So my test function is telling us that it did not work. So this is just to validate that the two alternatives I'm going to be showing here, they do evaluate to the same values. So my first case is that. Option match, case sum, A, I'm going to return sum, F, A. Case none, I'm going to return none. So does anyone know what this is equivalent to? OK. It's equivalent to map. So this is an option map F. So if you have a code like that, a match statement with those case, you can simplify it to a map. Very simple, just one line, much easier to read and understand. So let's test this. And we can see that, yes, both functions return the same results for all inputs. So now I have case sum, A, I'm going to return A. Case none, I'm going to return a B, a string B, any value, any string. Who knows what that one is? Get it on us. Yes. OK. So if we try it, we get the same values. Awesome. Now I have the combination of both. I know case sum, A, I'm going to return F, A. Case none, I'm going to return a B. That is fold. Well, you guys are good. Yes, same results. Case sum, A, false, case none, true. It's empty. And we see that they do return the same results. Now it's the reverse. Case sum, A, true, case none, false. It's defined. Or since it's called a two-ten, I can also use non-empty. And non-empty is cool because it's the same one that's used by the other collections. So you have a consistent interface. And I'm going to show this later when I just get useful. So same results, no surprise here. Case sum, A returns one, case none, zero. OK, OK, OK, no? Sorry? Yeah, yeah, everything here you can do with a fold. We got that already. So I'm looking for something that is simpler, shorter. Yeah, good one, sir. Size, OK? And we have here the same values again. Sum A, sum A, none is going to return an option B. Or else. And again, same values. Next one. Sum A is going to return A. Oh, almost. It's called earn now. So what the hell do I need that? Java, yay. You guys are awesome, OK? Yeah, if you need to pass an option to a Java API, you just call earn now. And the results are there. Now it's getting complicated. Case sum A, if PA, and if you remember, P is a predicate that tests if the string is empty, I'm going to return sum A. Otherwise, I'm going to return none. Filter, yes. And also you can call it as find if you want. It's just an alias for the method. Same results everywhere, cool. Case sum A, if not PA, sum A, case, any other thing, none. Filter, none. Unfortunately, there is no find, not. Filter, not was introduced in till nine. It's not the later one, too. Sorry? It's not the later one, too. Next one. Case sum A, I'm going to return if A equals an empty string. And of course, this empty string is just any value I want. Case none, false. Contains, actually. And contains was introduced in 211. So let's run. Now the thing that you should pay attention here, and I've seen some developers making this mistake, is that contains tests if the option contains that string. It's not if the string inside the option itself contains the substring. So something like option banana contains A is going to return false. That does not work like that. For that, we need the next function, which is something like that. Case sum A, PA, case none, false. Do we know what that one is? And that is exist, OK? So we see that they return the same value. If I want to do what I was trying to do before, if I want to see if option banana has the substring A, then I combine both. So option banana exist. My string contains A, and it's going to return true. Now we have case sum A, PA. And remember, P is a predicate testing if the string is empty. So this is a Boolean true or false. Case none, true. So just I see some, whoa. OK, who said for all? I mean, you're good. Yeah, so this is just like exist. The only difference is that none is returning true, not false. So this is for all, and it was introduced in Scala 210. And here are the results, OK? So why would you want a none to return true? It's a kind of opt out. If something's not defined, do I want to default to false or true? It depends on your application. There are applications I use that, but sometimes it's not rare that I use for all. At first it feels strange because we always think of none as false, as no, as zero. But sometimes you want none to stand for something and use for all. Next one, case some a if a returns one, case anything else, zero. Finally, I get one that you guys don't know. No, not collect. That is count, OK? So I can use option count. And we see the same results. This one, case some a, print line a, case none, I'm just going to return unit. For each, you guys could be giving this talk. And you can see here that some a did print a twice. Some empty string did print two empty lines. And none, of course, did not print anything. So yeah, it worked as expected. This one, case some a, write a, case none, left b. And b, again, is a default value. Not, not to either. It is to write. And I don't like this method name. So yeah, what it does, it converts an option to either. I don't like the name because if you pay attention, you call to write b. But what you're going to get, actually, is a left b or maybe write something else, OK? So this would be better named, in my opinion, this would be better named to write or else b, you know? So let me repeat myself a little bit here. Yeah, so we tested, it works. So here, and now that Daniel is here, the fun is over. He's going to say everything. This is the same thing, but it's reversed. I'm not going to offend your intelligence. This one is to left, OK? And we see we get the same results. Case some a, I'm going to return a sequence a, case none, nil, two sequence. Yeah, that one is easy. And I'm not going to repeat myself. There is a two list that does the same thing, but returns a list type instead of a sequence type. And just because I promise I would not repeat myself, I'm going to repeat myself now. It's set. You just call it two sets, OK? And there it is. And congratulations. You got all of them, but one. I'm impressed. I will not get as many. I just wrote that. I didn't read it. OK, so you may say, I saw someone saying I have something against that. And I would love to hear your opinion soon. But before you say anything, sir, I want to say that this is all nice and funny. But you know what? This is a matter of personal style. I don't care. I like pattern matching. I'm going to be using pattern matching. And my point here is that no, this is not just a matter of personal coding style, OK? Using high order functions brings you some real benefits. And let's see how. So let's see I have a case class, bad employee. And it's not the employee that is bad. It's the case class that is bad, OK? And it has a name. And it may or may not work for a company, OK? And we have two methods here. One method is employed. We'll test if the option is not empty. So using pattern matching, if there's something there, I'm going to return true, otherwise false. And I have another method works for that takes a string. And I will see if my company matches. If it's not defined, of course, I'm going to return false. But if it's defined, I'm going to compare the company I work for with the company you're testing and give you the answer. So pretty simple code. I have Joe that works for Acme. And I'm going to ask if Joe is employed and if Joe works for Acme. So let's run this code. And what we get here, of course, no surprise. Joe is indeed employed, and it works for Acme. So let me show this slide again. Look at how many lines of code we have. Let's see how it looks like using the high order functions a lot shorter. Just two lines. Do you want to see it again? This is using pattern matching. This is using the high order functions. Of course, we can run just to be pedantic here. And we get the same results. Thing is, and now I'm going to show you my point, is that this is a tough economy. And not everyone has a full-time job. Some people, they have many part-time jobs at more than one company. So the way we model this case class does not reflect reality. Yes, sir? Yes. It contains dates about me. Yeah. I could use XS. OK. But then I would have to pass, just as Daniel said, a predicate testing if the value is equal. Thanks, Daniel. So I was saying, we should not assume that the person is going to work for just one company. They may have many part-time jobs at different companies. So now we have to reflect our case class. And did you see the difference? I'm going to do it again. This is the old one. This is the new one. I just changed the option to a sequence. Don't believe me? Again, option, sequence. I did not have to change a single line of code. I did not have to change my methods. I changed the collection, but my methods stay the same. So this kind of consistency across the collection, so all the collectors, they have the same interface. This is just awesome. Look at how easy it was to refactor that. So now poor Joe can work for Acme Corporation and for Med Lab. And if I want to test if Joe works for Med Lab, of course he does work for Med Lab. If we go back, so for this one, if I had to change my option to a sequence there, I would break all the part-time matching that would not work anymore. You would have a lot more work to do. So can you imagine just how much work would be saved? This is a very simple case, class with just two very simple methods. Can you imagine how much work would be saved on class with many more methods and methods with multiple changed operations? That would be a significant amount of work for you to do to refactor for a simple change like that. And when I was using the higher functions, I just changed the collection type. I didn't have to touch anything else. So if this is not reason enough, I don't know what could be. So again, it's not just a matter of personal style. It does reflect on code quality, on maintainability, on testability. It's a lot, lot easier for us. And again, this is just, it's more than option. Do not limit yourself to options with the things that I try to show you here. Abusing pattern matching can be considered a code smell. It's not always the pattern matching. It is the most readable or concise construct. It's the thing about nails and hammers. If you have a very powerful hammer, everything looks like nails. So first thing, I see that a lot. It makes me cry. Do not pattern match on the Boolean for God's sake. Come on. There's nothing wrong with using an if-else. They are perfectly fine. They evaluate as an expression. You can assign the result of an if-else to a value. Do not pattern match on a Boolean. Do not pattern match on a single case. Yes? Well, I'm actually, so I'm curious, with respect to pattern matching on a Boolean, do you think it's acceptable to pattern match on a Boolean when it's a Boolean buried inside some other AT? Like if you're pattern matching on some complex, or would you use an F or would you like pull it out? Like, whoa, whoa, whoa, whoa, whoa. Well, it depends. Are you pattern matching something else on that structure? You use common sense. So if you have a case class with a Boolean, do not pattern match on the case class just to pattern match on the Boolean. Call A dot a Boolean and do the if-else there, I think it's common sense. Just this is not stricter. I mean, the thing is produce readable code, maintainable code, something like that. Again, and if a statement, it's perfectly fine. If you're gonna have just one case, you know? If this starts to grow, okay, use the case. That's really, really good idea, but just for one, not needed. And for things like sequence and strings, there are methods that you can use to avoid pattern matching. You can use this empty, hat, option, tail. There are a lot of those methods that they do replace pattern matching. If you're using enumerations, use with name. So here the reference on these lights, the code for this presentation. I wrote an article where I give some more details. I go a little deeper on the subject. It's on our blog at originate. And I know people are going to ask the tool that I used is on GitHub. Okay, if you like it. Let me know if you use it. I would love to hear about presentations that I use in it. So that's it everyone. So thank you so much. If you have more questions, feel free to talk to me.