 You can think of this as a ScalaZed 101. If it's my look at what I've learned with ScalaZed and sort of an introductory, this is enough to hook people, hence the gateway drugs. Colt Fredrickson has put together what he's actually called ScalaZed 102, which is immediately after this talk. He had asked me for my slides a few weeks ago to sort of make sure that there's not overlap. So I strongly recommend, I haven't seen the talk, but it's probably good. I recommend after this that you stay for Colt's talk because they are meant to be complimentary, that if you want to sort of continue the thread of what you see in my talk, that's a good way to go. That said, I think I've done enough conferences at this point, people may be familiar with who I am. Otherwise, I'm Brendan McAdams. I work these days for a company called Baldradius. We do training and consulting and other services around the type safe stacks. So if you're looking to build out a team, augment a team and anything else around Scala, come find myself or Mike Kellen today. We'll be around, our sponsor of the conference so we'll be sort of visibly in the Baldradius shirts here. That said, let's take a look at a skeptical look at Scala's Ed gateway drugs. And for a very long time on teams I've been at, probably since 2009 when I started Scala, I was poking around and looking at Scala's Ed. And anytime it came up within teams I was in, it essentially came from me or someone else that we are not using the Zed word. We're just not going down that road. You know, let's avoid talking about this. It did turn out that I lied. My last project, I was at Netflix for about a year and we kept running into these persistent problems with the way we were doing things that I started exploring actually validation in Scala's Ed. So my talk's a little backwards from how I started because it turns out I needed something before I got to validation. So we're gonna look through things in the right way or at least what I think is the right way. So the question that comes up of course is when I say skeptic and I talk about this we're not using the Zed word partly jokingly but really I was doing myself a disservice to some degree avoiding it. And there were a lot of reasons why I was doing it and I suspect for other people they're similar. One of the biggest one is that I've seen it as intimidating. There's a lot there. There's a lot of code and other things, a lot of constructs that are confusing necessarily to someone who's not familiar. People always speak about it being more pure or more hascally or more maffy. It doesn't necessarily sell me or at least it didn't sell six years ago me. Now I think it's a little different after being exposed to the people in the Scala community. I'll also be the first to admit I'm not necessarily great at math. I didn't take any calculus courses or anything else and I did okay with algebra but all the other trig stuff and everything else confused me. It could be that I'd be fine a calculus but I don't have a CS degree either. So from my standpoint I'm not someone who's steeped in years of algorithms and LISP courses and math courses and all these other things. So this doesn't necessarily make sense to me when I look at it for the first time like it might for some people. And I mean this is a legitimate question. I like to think that I got over this question about a six months into my Scala development but the reality is we all fall back on this from time to time which is, well what's wrong with what I have in standard Scala? I have a tool that can do this without introducing another library. Now the reality that I've learned about Scala's Ed is that it's magic. And obviously I'm using hyperbole here quite a bit but there is a lot that is in Scala's Ed that really feels magical in how much easier it has made certain things that I could have crafted my own solution that would have been Elmer's glue and popsicle sticks and never quite be right. And so there's a lot of things where these are structures and concepts and other things that aren't just new to Scala's Ed but exist in other languages, exist in theory and other things and so there's grounding behind what it does. But it can feel like magic from time to time because just things happen. People have thought of that problem that I needed to solve. So the road that I followed and I mentioned that I worked for about a year at Netflix when I started on the team there. We were, sorry there were three people who had been working on the project for probably about a year and I started to run into the same problem over and over again, which is how I started exploring this. But I will say that once I got started, once I sort of dipped my toe into the water with Scala's Ed it was hard to stop and another member of my team as well, Ryan Delucci sort of hit the same point where it's like we kept wanting to hold ourselves back from jumping into the next thing. So it is really sort of addictive as you go along and you get into that gateway drug bit. The constructs are really powerful and they're really useful. And now this goes without saying although I've been doing this for a while, I've given this talk four or five times, I still would like to encourage you to think of me as an amateur rather than an expert on this subject. I could not hold forth for hours on all the details of Scala's Ed. I know this little domain that I'm talking about today really well but there's a lot more from things like Colt's talk and other things that I'm hoping to learn today. From all the things that are going on there. And this is not a category theory or a Haskell talk so let's be practical. I will mention Haskell only one more time in this talk at the very end so you don't have to worry about me assuming that you know Haskell which has been something that's eluded me from time to time. I learned Haskell a couple years ago and I need to revisit it clearly. So here is the road to Scala's Ed for me. What I want you to think of things as what I would like you to learn is hey, this stuff might be useful. I don't even feel like I need to convince you at the end of this talk that you need to go home and use Scala's Ed. I just want you to think, hey, there might be some value in what he's talking about, I should think about this. If I at least interest you a little bit then I've done my job well here. I am not going to teach you that a monad is a monoid in the category of endofunctors. But I suppose that is an important thing to remember. So we're not gonna get really heavy on terminology and theory and everything else but we're gonna look at this practically. So the problems to solve this project that I was on, we were building an API server that was part of a larger app with an AngularJS frontend. Our service was Scalaatra doing REST and there were a lot of services. It grew and it grew as we were going along with all of these different things. There are actually several applications interacting with us. An error passing was something we kept running into as a challenge. So providing clear errors and also validating input. We kept running into these problems where the frontend team would send in JSON that our JSON parser would choke on for some reason. And sometimes it was because an optional field wasn't defined right or they sent quoted string where it was expecting an integer and it would often fail silently. Now of course as I started to look it turns out that there was something we could turn on that would dump that info. But as far as the frontend guys were concerned, I mean at least the default behavior, these JSON errors were being swallowed. They were getting a generic 500 exception and had no idea why. So then of course it frustrates the debugging for your frontend devs. And for anybody calling your API when they don't get clear information about what went wrong that means that they now have to capitalize the time of one of the programmers on your project to dig through log files and do things that we should keep ourselves from having to do by giving better tools to our users. Because ultimately when we build an API anyone who calls that API as a user that means that your frontend developers are users or even most importantly think of them as customers in that there's a way you wanna treat your customers that's probably a little above how we think of users. And so let's think about these guys as customers. So the idea for me was to help developers help themselves and also to get off having to dig through log files because it wasn't like oh this is terrible I shouldn't have to do this this is beyond me. It was just like why are we repeating this same task over and over again instead of improving what we're doing. So if an error occurred the question of course is did the API receive bad data? Did it receive invalid data such as the JSON failed to parse? Did the database fail? Did your hovercraft fill up with ills or some other ridiculous error? Because I have occasion we've all run into some weird like kernel exception or something else that we've never seen before that just happens for no reason. Something happens that we should communicate to the user. And what if multiple errors occur? How do we communicate all of this effectively? Are we digging through log files because we gave them a 500 error or do we give them clear information? And you can also think of this in terms and one of the things I started doing was that there was if we were in the dev server I could send more information about what went wrong to the front end guy so he can look at the JavaScript console and then in prod I can pare down what we do and don't send. So there of course first we might look at either or either in Scala. Scala's built in either is a pretty commonly used tool. It has left and right projections. Which essentially means that there are two possible sides to either it can be left or it can be right. By convention in Scala it's generally agreed upon that left indicates an error and right indicates a success. So you might have either of throwable and string which means that the left would be a throwable if there's an error the right would be a string. It's a good concept but there are some limitations in interaction and I ultimately get corrected on this slide constantly. I think I've adjusted it to take into account the criticism I've had for this. But most specifically when I say there's some limitations there's no map or flat map implementations on the default either. You have to call a method specifically to force a right projection. So you sort of have to know or assume that you want to treat it in a certain way and honestly a data construct like this should just be usable the way we want to use it without having to do type conversions. So this is a rough look at either, I can say right, singleton right with a string and get back in either of nothing in this case because I haven't told it what the left is and string. Success.isRight will tell me whether and either is right or left. Success.isLift but of course by default I can't throw that in a for expression which is the first thing I want to do when I make a call to something that gives me an option or something else is be able to comprehend or something else over it in a clear manner. So it's not a monad it can be a pain in the ass to extract. I'm trying not to use words like monads so don't worry. So it is time to actually look at Scholaset rather than it's time to start the music and light the lights. It is time to look at Scholaset. So the first thing that I, I just wasn't the first thing I found in Scholaset it should have been the first thing I found in Scholaset which is why we talk about it first. The alternative is what's known as a disjunction. My understanding is this is a math concept too so those of you with more advanced educations and me might go yeah of course. But Scholaset's disjunction also known as backslash forward slash. However it's defined in either.schola. So it is sort of a complimentary to either but since there's already an either in Schola it has become backslash forward slash. I will refer to it as a disjunction for the most part. By convention in disjunctions just like with either. Right is success and left is failure. However there is some tendencies in disjunction that actually encourages that further. So the symbol dash backslash forward slash is left. The symbol backslash forward slash dash is right. The easiest convention is just remember that the dash is on the side of the you know which piece it is just like with plus colon and colon plus the colon is always pointing at the list or the sequence. So disjunctions assume that we prefer success. The right is also known as right bias. So essentially this data construct assumes that you're hoping for a right. And just like with option you can map over some but you'll always get none back if it's none. There's sort of this bias towards giving you what you need. Four comprehensions map statements flat map statements basically unpack where success you know rights continues and a failure abort. Just like you would sort of see with option which we'll look at. So we'll say one thing there are two ways essentially of annotating the type when you're talking about disjunctions best practice wise what I've found what I've had recommended to me is that when you declare types you prefer the infix notation. That is the first example that's up here where it's error space disjunction space success. So your left type disjunction right type because it reads very clearly this is on the left this is on the right. As opposed to the standard notation where disjunction would take two type arguments in square brackets. So consider that infix notation at least for disjunction is something that can help clarify. You can quickly convert values to right or left here. I can have string success dot right and I get back an instance of a right disjunction same thing dot left for failure. So these post fix operators allow us to create disjunctions. There's also operators on the singleton for disjunction which seems to be what I had recommended to me early on is this is the best way to do it. I may be misremembering that but we can invoke left and right methods on the disjunction singleton and get the same effect. And then finally we can go fully symbolic. We can use the type constructor for right or for left directly. I think it reads a little easier to say disjunction dot left or dot right. Your mileage may vary and so there's a couple of ways to do this. I've mentioned option a few times already so I wanna digress quickly to look at what I mean there. Option is a pretty commonly used container in Skull there was just an entire talk about it. It has a none and a some subtype. Some has a value, none represents something with no value. Like disjunction there's also a bias here. Basically option is biased towards some when you feed it into a fore expression or a map or something else. But comprehension with it has an issue with undiagnosed aborts and this was one of the first things that I ran into with our Scala project that I was trying to solve which is this example isn't as detailed. I did a blog version of this and I need to port something like code from that back but essentially I wanna look at some examples of when we comprehend over options in Scala. So the first thing is I've got a couple of case classes here address user DB object to represent some fake data. I've got an instance of Brendan with a user entry, no address and some other guy where there's no user entry because user is optional here at all. If I go for DAO generated from Brendan, user generated from DAO.user because Brendan returns an option and then user is an option. So in this case I get back a sum of the user Brendan but if I do the same thing with the some other guy user who has no user object I get back none. Now imagine if this fore expression is three or four or more levels deep. Now the question of course is why did I get a none back? Was the user empty? Was the database object empty? Was the address empty? The phone number, like any of these things we're extracting at some point we have to answer the question of why they're not there and we do things like putting underscore equals log.info to debug it in our fore expression. So there's potentially a better way to do it because the question is what went wrong? So here disjunction can come to the rescue. A comprehending over groups of option can lead to these silent failures, this sort of silent death in the fore expression where we have no idea where things went wrong. Scall Z actually luckily includes implicit to help us convert option to disjunctions and vice versa and the bias, the right bias on disjunction makes it easy to work with here. So on a left we'll get potentially useful information instead of none. Left can be a value and therefore we can include an error message or something else that our users can leverage. So in this case I've got a bunch of examples of constructing, I'm sorry, of converting options to disjunction. You'll see at the top and hopefully this code is readable enough at a distance. I'm saying none backslash forward slash greater than which is the symbolic way of basically saying convert an option to a right disjunction. Now what's important to note here, obviously there's also a alphanumeric version of that to right disjunction that does the same thing. The argument to to right disjunction is what the left value should be if the option is not a sum. So that argument is saying if it's none, return a left with this value. So in this case I've chosen to return specifically no object found or no user found or something else. In instance at the bottom, some my hovercraft is full of eels, converts where a left is gonna be no object found. Obviously we get some same thing for to right disjunction. So now I can do this for expression where I include some error information. Hey, the user wasn't found or the join failed because there's no user object or this user has a company ID but that company ID doesn't exist in the database. All of these things are errors. Maybe I don't show to the actual users of the product but the consumers of my API can get good debugging info. And so at the bottom, the join failed no user object in a left tells me what went wrong. So suddenly we have much more useful failure information. And of course the question comes up what if we wanna do something beyond four comprehensions? Disjunction can be treated as a monad, we can do things in four comprehensions but there are limitations to what we might be able to do here. For example, I can only really return one error. So this brings us to validation. This is actually where I started in Scala's Ed only to find out that there were some examples in six that didn't work in seven anymore and I really needed disjunction. And then it turns out validation was complimentary to what I built. So validation actually looks very similar to disjunction at the first glance. And you can convert between them just like you convert options over. The sub types of validation are actually very specific here. They are success and failure. You can assume that there's a bias towards success but not quite in the same way that there's a bias with options or disjunctions. Validation is not a monad. You can't put it in a four expression unless you convert it to a disjunction. But what it is is an applicative functor. And again, I'm trying to avoid using these words but that is what it is. And so you can chain many of these validation objects together and if there's any failure in the chain basically failure wins. All the errors get appended together. So now I've put together a new user, Brendan with an address there. I've also got Cthulhu who happens to live in Relya where he is waiting, dreaming. No such person, a guy with no user object at all. And then Wandering Joe. And Wandering Joe just happens to wander from place to place and do his thing and just sort of lives out of hotels. Basically like a consultant. Only I actually pay for an apartment at home. So validDB user is a quick function here. It returns a validation of string and user. And I'm just doing a quick match on dbobge.user given the last talk, talked about how you shouldn't do this pattern match. It's still an example. So if there's some user, I return a successive user. If there's none then I return an instance of failure. So you can see here that I can construct these things directly. ValidDB user, Brendan gives me some user. I'm sorry, success user, ValidDB user, Cthulhu, the same thing. No such person gives me the error message, does not contain a user object. And then finally Wandering Joe is a successive user. Now if I go into a, hey, let's break down the address. Well, if there's an address and a post office validation function returns true, is this somewhere where your mail carriers are gonna go? We return success. If it's not recognized by the post office, we return an error. If there's no address, we return an error. And if there's no user, we return an error. So we've sort of built something up with this validation that represents success or failure. The first user is success. Let's assume that the mail, the postal service does not deliver to Relya. In this case, we will get invalid address, not recognized by postal service, no such user for no such person, and user has no address for Wandering Joe. So how do we stick all of this together? Because right now, all I'm showing you is how to return one error. The answer is that ScalaZet has a number of applicative operators. All of these can be used to combine validation results together to build a bigger aggregate. Star greater than and less than star are two of the ones that you'll probably run into first. Star greater than takes the right hand value and discards the left, assuming the right hand value is success. Less than star, as you might guess, does the reverse takes the left hand and discards the right. Errors win here. So if the right hand side is a success, but the left hand side is failure with star greater than left is gonna win. So here, running quickly through it, one dot sum star greater than two dot sum returns sum two. Because they were both successes, and so the right hand side wins. The other way around, one dot sum less than star, two dot sum, sum one wins. But less than star, did I get that the other way around? Sorry, one dot sum less than star none still returns none because of the right bias. And I'm reversing those, sorry, left bias. And the same thing for none, two dot sum. Even though we're saying you should take the right or you should take the left, if there's an error in there, the error wins. Validation will chain all of the errors together though, instead of short circuiting. So here, for the most part, valid DB user, Brendan combined with valid address, take the right hand side if they're both success, returns an address. Cthulhu gives us an error, wandering Joe gives us an error, but look at this last one. I look at valid DB user no such person and then valid address no such person dot user. And I've got this one big globbed error message together. It's both DB object does not contain a user object and no such user. So of course, what happened to this last entry? And the way that star greater than is called on validation, it appends all the errors together. It actually turns out that each object is capable of defining what its behavior is when there are multiple errors in a star greater than call or a less than star. And validation happens to say, glob all of the sides together into one thing. So we need another tool to make this make sense. And this is non-empty list. So apart from the sort of invariant that it has to have at least one element, this is a Scala list. So it's an implementation in Scala's ed of a list that has to contain at least one element. It's very commonly used with validation to put error messages together and to signal that there's gonna be at least one error here. It's actually so commonly used that there's a type alias. Validation of non-empty list of left and right is also aliased as validation NEL left right where it's assuming that the left is gonna be a non-empty list. And like a list, append allows elements to be put together into a new list. So if we look at the same function for valid DB user with NEL, you'll see at the bottom I do failure of non-empty list. And we can be explicit and construct a non-empty list by hand, or we can use some helpers. So in this case, it's dot failure NEL says return a right hand side. And valid DB user NEL, no such person with valid address, no such person. Now these errors actually give us a list of errors instead of a glob strict. So we've got this non-empty list that represents these new errors. There's one last operator I wanna show you in Scala Z and this is another applicative operator that can be useful. And that is pipe at pipe. And we'll talk about what to call that in a few minutes. But this basically combines all of the failure and success conditions. To handle success is we provide a partial function. So valid DB user, Brendan CA, pipe at pipe, valid address NEL, Brendan CA user works much like star greater than or less than star, but we can provide a partial function that says if there's success, feed all of the success objects into me as a tuple. And I can do something in this case like print out what the user is. All of the other users will return any L of errors just like star greater than did. So we can sort of see that here, no such person gets a combined list. One last function error handing we're actually gonna skip this just because of time. And so I wanna talk real quick about a final thought on naming. From the skeptic side, the common use of symbols gets really interesting. Agreeing on names, at least within your own team is important. You guys have to know what to call something. Although it's defined in either.schola, disjunction, calling it either gets confused with scholars either. So disjunction obviously makes more sense. Here's a few of the names that I've heard for pipe at pipe. There's also a Unicode alias of basically circle star. Usually at the end of this, someone will give me at least one more. So if you've got ideas, please let me know. Oink, I've heard it called oink. It looks like a pig's tail. Cinnabon or Cinnabon bun. I think that was what I ended up calling it. Dick Wall pointed out that there's a similar thing in Britain called a Chelsea bun, which is the same as Panorazan. TIE Fighter. Continuing the Star Wars theme, we could go with Princess Leia's hair. Admiral Ackbar. Scream. Scream 2. Home Alone. And I continue to lobby for Pinkie Pie as the definitive answer here, because why not? So if you'd like to know more, and this is really the last thing I'm gonna say, because we're just bumping up against our time, some resources, the things that really helped me. And remember I mentioned that I was gonna mention Haskell one more time? Eugene Yucata, and I always worried that I'm pronouncing his last name wrong, so I'm sorry Eugene, if you're watching this video. He has a free website called Learning Scholas Ed. And what he has done is to go through another book called Learn You a Haskell for Great Good, which is a fantastic book, it's available for free, but I recommend you buy a print copy. The idea here is that learning Scholas Ed that Eugene put together essentially says, let's read Learn You a Haskell for a Great Good, and we're gonna get this much done each day. And then the Scholas Ed learning post is all about, okay, you just read this chapter in Learn You a Haskell for Great Good. Let's look at how Scholas Ed maps those concepts to Schola. So you sort of get this bridge from the Haskell knowledge over to the Schola knowledge, it could be really useful. And that's Learn You a Haskell.com, if you wanna download, you know, get the ebook copy or actually buy a print copy. So that said, I think I have time for one or two questions and then Colt is on. It's the snout operator, too. I read it as a hat for some reason, like when I'm just... It's Pinkie Pie, Daniel. It's not a Pinkie Pie. Pinkie Pie. Okay. I've been calling it Cinnabon since... Although now I'm, you know, totally on the Pinkie Pie bandwagon, so Cinnabon is so six months ago. All right, well, thank you very much, everyone, and let me know later if you have questions as well. I'll be around.