>> LENTCZNER: Thanks everyone for showing up for a crazy taste of Haskell I’m Mark [INDISTINCT] So, Haskell is scary, you’ve all heard it You’ve all heard the runs on Reddit, right? You know, it’s got no state, you know, who wants Lazynest? Lazynest is, it’s lazy, you know, and PHP has, you know, [INDISTINCT], screw that And after all, didn’t we just spend the last 20 years like making dynamic languages rule the world? I mean, we did, didn’t we? Right? And my ads–okay But Haskell is actually really scary cool It is functional, which turns out to be kind of scary and cool and it’s lazy and it has high order of functions and type in friends and it has monads Okay This is why I got hooked in the–in to Haskell I’ve actually been programming for more than half the time profession has even existed and so three years ago when I ran in to Haskell or sort of looked at Haskell again, I was shocked and really enjoyed that like, My god There was like something new to learn about programming I mean, something really new So that was fun It really does twist your mind, I mean, you know, Haskell is really–makes you really rethink a lot of stuff but the two things that I think it really got me is, look the language is beautiful, you write code and you just look at it, and you’re, like, Wow, those are like the nicest seven lines of code I’ve written in the last month Like they’re just gorgeous, you know, and so it’s really a beautiful code So, because of that reason, a lot of code to show you I have 50 more slides and every one of them I think has code on it So, we’re going to go really fast with you all Googlers so it will be no problem Mute we need a mute on some DC, hopefully some slide No? Mute I don’t know who it is All right The code is going to look like crazy-moon language, it’s just insane You know, it’s just totally different but not really but it is different, so just be brave, okay? Just be brave All right There is git repo, if you want to pull everything a little, of course, I edited the slides 15 minutes before we started So it’s not quite up to date, you can just Google for Haskell-Amuse-Bouche and the fist hit is this repo and I haven’t pushed yet to get the latest stuff so it’s a little bit out of date from the slides But it has not only the slides, it has all the source code I’m going to show you and Haskell files that you can load up in the repo and edit So, you can play along as well, If you want But I’m not going to give you too much time So, let’s start with something really, really familiar This is Bouche, not Haskell, right? And this stuff should look pretty familiar to anyone, there we go, a little bigger All right This is just standard pipelines on the shelf Okay, what do they all do? They all take input, they process it, they produce the output, as soon as they are able, that’s actually a feature of most Unix commands Most of those commands do not modify any state Actually, I chose ones which didn’t modify any state at all, right? But those are just small things you do, right? In short, those are functional, pure and lazy, right? So, you’re actually used to this stuff It’s actually not as crazy and weird as you think and, you know, the vast shell or the shell and the concept of the shell has been around for how many decades now and we still all use it, so it might have some value there Okay Let’s rewrite that in Haskell Hopefully that’s big enough for you to read So there are some gullible [INDISTINCT] on the first line which we’re going to ignore for this millisecond Because the next line, we’re going to talk about a lot and if you stick that in the file called run hask in a Part1.hs and run it; you give it this poem it’s input and surprise, it sorts the lines and gives you that poem as output Then master [INDISTINCT] or those who the reference Okay So, let’s look at the actual processing, all right, which is right on that first line It is not exactly rocket science We’re going to define a function called process which takes some t some text and it’s going to call some functions And the only difference from what you are used to is that functional arguments don’t go in parenthesis, we just used parenthesis for grouping So be brave, just look at the code Get the lines of t, it means take the string and turn it into an array of strings or a list of strings, technically a list
Sort that list and then unlines which is another library function which takes a list of strings, slams new lines into them and throws it all together All right So, the first line should be like dead clear, right? I don’t see anyone looking strange you can like, okay, everything is nodding yes, so good Okay. now, I know I had to take you back to high school and everyone hates that but in high school you hate algebra because, you know, you learn this, right? F of G of X can be written as this funky thing with a dot in the middle All right This is function composition F of G of X, all right, so you can see that While in Haskell, it turns out, that’s actually a programming language feature So in the same way, we can do that up here, we can fact it–we can sort of rewrite this, this way All right So, the function process of some text t is applied to that text t, the function lines composed with sort composed with unlines, all right So that data operator is exactly like it was in algebra All it just means is apply the thing on the left to the result of having applied the thing on the right, so unlines it then sort it, I mean, lines it then sort it then unlines it All right It reads kind of right to left which might seem kind of strange to you because bash things go in the other direction But look up here, right? I mean, it’s just getting rid of all these parenthesis Okay Now, here comes the real [INDISTINCT] We can actually do algebraic simplification or sort of the equivalent So, work with me here If process of–it takes some input, right? Process a function applied to some input t and all it is, is this composite function, these three things applied in sequence to t–in Haskell you should get rid of the t’s because we can say, Well, process–by the way, the tip marks are just valid characters for identifiers and I had to name them all three different things so they can go on the same file The process double tip mark is a function that is just the composition of these three functions Have I lost anyone yet? Good Onward Okay So we can code a bunch of other ones We can say sorting lines is unlines.sort lines, right? Compose those three We can reverse lines, we can take the first two lines because take two is a–no, it does what you think, right? So, anyone see a pattern? It’s a pattern, it’s algebra, we can factor it So, we can actually write a function called by lines which takes a function F and it’s equal to–we just write the same expression but stick our variable in the middle, right? So by lines of F is the same as having written unlines.f.lines So, now I can rewrite those three functions Sort lines write by line sort Reverse lines, by lines reverse First two lines, by lines take two Yes, yes, no, there you go, [INDISTINCT] that’s good All right Let’s write our own Okay I’m going to write a new function, sort of from scratch here it’s called indent This funny line at the top is a tight declaration, it says indent is a function that starts with a string, takes a string argument and turns it in to a string as a string result It’s kind of very functional style in notation, oddly enough All right Anyone noticed that this is the first type I have shown you anywhere? All the other code is completely 100% valid Haskell you’ll find it in the–in the files that are with the repo exactly as I wrote it here with no additional typing So, Haskell is a language that is really strongly typed and yet we didn’t have to type any types because Haskell is type [INDISTINCT] which means that when you type some–when you write on a code, the expression, Haskell figures out what type that must be when you write a type to a first order of approximation, 98% of time The type is for you, not for the compiler In fact, the compiler ignores what you write as a type, figures out what the type is on its own and then says, Did I get it right? Now, you might think that’s kind of crazy like aren’t–like, it shouldn’t be, but no The compiler it’s there because we write the types as communication between programmers and the communication of our intent and the compiler is actually checking us Checking to make sure we’re honest Okay So indent is a function from string to string, it’s really complicated, it takes an argument S, ended up pens at the double plus operator, a bunch of spaces to the front Great So, we should be able to follow our pattern All right By line sort by lines reverse and say by lines and dent, anyone want to guess? Boom, it doesn’t work And the worst problem is if you put this in the [INDISTINCT] you’ll see this horrible thing down there That is the Haskell compilers idea of poetry, it’s writing you a kind of a love poem but it’s from a compiler and so, as a consequence, we ignore it Do you agree with that?
This is just crazy moon poetry and you just have to deal with the fact that it’s there and most of the time you just figure what line number it is and go looking at them Okay What is the problem? The problem is, all our other functions sort and reverse took a list of lines and did something to them but we wrote something which takes a string Okay So, we’re going to use something called map Map to the rescue now, you probably all at this day and age program did a language that has a collections library and that collections library has either a four each or a map function, right? And usually map takes a functional argument, a function pointer or it depends on the language your working in and iterates through the collection applying the function and gathering up all the results and returning you a new collection This is nothing new Map exist and you–I’m certain everyone here has been exposed to a map function and just to make sure we are to realize what we’re talking about I gave you some examples, compare if we map reverse over this list of strings, right, it reverses each individual string versus mapping reverse to the list of strings which map reverses the list itself, got it? All right The same thing is like sorting some of you might at this point be scratching your nose and go, Wait, does reverse work on a list of strings or does reverse work on a string? The answer to that question is, yes it does both Okay So, to indent each line of our poem, right? I have to do something by lines but I better map, all right, by lines expects a function over a list So, I’m going to map indent over that list By lines map indent I could also factor that whole pattern out because we had a thing called by lines, have it each line, given a function–now, I’ve written this–now I’ve written a type Given a function from a string to a string, notice the parenthesis and the string return a new string So, let’s–let’s look at what’s going to happen, each line F is going to take this–it’s going to take a string, apply lines to it, give us a list of lines, map our function F over each individual line and then unlines the result back together into one big string to return So, each line is now useful utility function which does something–apply something to each individual line Yes? >> When you write maps space indent is that the same as indent.map? >> LENTCZNER: No, it is not So, the question was when you write maps space indent is that the same as indent.map? No, it is not We are passing indent as a function, as an argument to map >> Okay Map is a function >> LENTCZNER: Map is a function, right There’s no period or object There’s no receiver in this language It is not object oriented So, map is just a pure function at the top there but we’re going to–you’re getting close to a problem Anyway, close to [INDISTINCT] so indent line, we can do it this way or we can use this combinator of this thing we just build called each line–each line indent and then if you run them either you get indeed an indented poem, it’s very exciting But wait, where is the second argument to map? I told you back here, map takes a function and a list and returns a list In fact, at this point, looking at that top line should hopefully be kind of clear that that’s what that says It takes, right? It starts with it takes a function from A to B, a list of As and gives you a list of Bs but in this code up here, there is no second argument to map Where is it? All right Because it’s not there Because map of F–so look at map this way, we can say map takes a function from A to B and because [INDISTINCT] just trust me I can parenthesize the remainder So you can think of map as taking a function from A to B and turning it into a function from list of A to list of B, got that? If I just applied map to the first argument, I get back a new function it’s called [INDISTINCT] it’s [INDISTINCT] and I get back a new function, a function list of A to B, it turns, our indent which only works on a string to a version of indent which works on a list of strings We call this lifting or lifting up, map is kind of bringing our simple function up into the world of lists and that’s what’s going on All right And we’ll write some more code here, quickly I want to yell because we like yelling, right? So, this is another function from string to string and so, I’m going to yell and I’m going to map this function called to operate from the library listed uppercases characters And I map that over the string and I append a bunch of exclamations, and I’m going to
write yell each line and I’m going to use our each line function to apply this to each line of the poem And indeed what happens? I’ve yelled each line of the poem, not particularly exciting, it’s pretty much what we did before But what if I want to yell each word? Well, we’re very, very lucky, there’s actually like lines and unlines, the library has words and unwords So, we can define equivalently a function called each word that given a function will apply it to each word of the string So, right? We call words which breaks it up into a list of words We map F in this case, yell over that list of words and then we unwords to put it all back together And when we go off and do this, crap it all comes out on one line, right? Because it broke all the words apart all the words got slammed together with spaces and we lost all the lines So, what do we really want to do? We want to yell by words by lines Well, guess what? We can actually write yet another helper function Each word on each line, all right? Given a function F, this will apply to each word on each line by wrapping our function in each word and that we’re calling each word on our function and then calling each line on that And indeed, if I apply that, I get this, right? And I had managed to preserve the lines and do it every single word Notice that I have used the very functions we have defined ourselves as functions to more functions we’ve defined ourselves, right? So, what bus do we just get hit by This is the power of higher order of functions, all right? You can very quickly build yourself up a library for doing higher level manipulations of things and then re-use it very, very, very quickly Onward Okay So, we’ve talked a lot about functions, what about data? You got to have data in the program somewhere so, of course, we’re going to talk about structure data we might as well about list and so, one could use to define list like this This is actually a user defined type, this is not the built in list It’s just a list If you come from a certain persuasion, you might choose to call that mill and cons instead of end of list and link but let’s just read this When you have a piece of data of type of type–yes? >> You work [INDISTINCT] do you actually type what you’re [INDISTINCT] into a compiler? >> LENTCZNER: Either Good question So yes, I actually wrote the alphas because I just wanted to flex that Haskell was actually define in terms of unit code yohoo And so, you can–welcome to use Greek and variable names if you wish Actually, in fact, you’d probably not unlikely to see this, most people do in fact use Latin letters in this particular context So, that is actually a tight variable, tight variable So, this is–so, when you have a list of some type, either note the or sign there Either it’s just the end of the list, the empty list or it is a link of the list with some value of whatever the hell alpha ends up being and then recursively another datum of type list alpha, right? This is just a standard kind of recursive definition of the list Okay So, we can all play around with some obvious types, where we can define the value empty equals the end of the list Notice that we can kind of use these user defined options, we call them constructors–don’t think constructors like C++ or java Empty is end of list, one word is a link of the string apple and the end of the list, right? So that’s a one word list, two words is a link banana and then in parenthesis I create another link of cantaloupe of end of list, right? Kind of sort it should be sort straight forward, be brave, just go for it All right Pop quiz If we’ve given those three things I just typed, what do you think happens with the bottom with one of the first mysteries? So, anyone guess, what is mystery number one? It is a list of A pair It’s one thing, right? So, the first thing this is showing you is that, all right–remember, there is no modification of state in Haskell so when I declare the empty equal to end of list, I can use it just as well anywhere else You might think that’s annoying because like you can’t modify state but it’s actually really nice because things factor really well, like the guy who wrote mystery.1 is like, This is a single element list, I’m certain of it, you know Isn’t a change [INDISTINCT] you think? Mystery two, well, you can compose these things link the string peach and then what? And then some other list, right? Some other item has to be in a list [INDISTINCT] So, mystery two is a two word list, right? Peach apple Mystery three, anyone would guess what mystery three is? Who wants to be brave? >> Pineapples >> LENTCZNER: What? >> Lots pineapple >> LENTCZNER: A lots of pineapples Yes, it’s an infinite list of pineapples Haskell’s perfectly happy with this, completely happy Like you type it in, Haskell’s like, Sure, no problem
It works fine Anyone want guess what mystery four is? >> A tiger >> LENTCZNER: Yes, it’s a tiger, all right Because something that’s others that lists are all right We said it was a list of some type and all these other ones have been a list of string This first link has an integer but the second link has a string and if you looked at the definition you’ll notice that it had the same alpha in both places Yes? >> Okay [INDISTINCT] So, what is like, a context of mystery? >> LENTCZNER: What is the context of mystery? These are type of the top level >> So, I mean, at a point where mystery [INDISTINCT] >> LENTCZNER: Yes >> Okay >> LENTCZNER: Yes So, your names are all on top of the same It’s a mutually reclusive set of definitions Yes, so you can refer to yourself And the reason that this hasn’t go often to infinity at this moment is it’s lazy All right No one’s asked for what happens after the first link of the list so, we haven’t bothered to go look there and the fact that we will eventually go look one step further is fine Okay So, yes, number four isa type error Okay, let’s write some quick functions on list Good, I’m doing great on time All right Here are some examples of how you write functions Notice list back here has two different kinds a datum of type list can have one of two forms, it can be the end of the list that’s one form or it can be a link, that’s the other form So, strangely enough it is common that all our functions on list will have two clauses, yes? >> Going back to the type error >> LENTCZNER: Yes >> Well, [INDISTINCT] >> LENTCZNER: No Not of the type you are used to There are strange, weird, wonderful, odd things which you will be tempted to use in your first weeks of Haskell, you know, that let’s you do this, I really, really need a help, you know, a heterogeneous type And then when you’ve used Haskell for six months, you’re like, I’m so foolish I’ve never needed that heterogeneous type ever So–and this one you’ve got to be brave and like trust that this sounds crazy, that you can’t do this but in fact you really won’t actually need it There are other ways to achieve what you’re trying to achieve which are actually more powerful and more importantly safer Okay So, some functions Because list has two forms, a datum of type list has two forms, almost all functions on it will have two clauses, notice I have two equations for drop one So, we can read this pretty straight forward Drop one takes a list of some type and I don’t know what type it is and returns me a list of the same type If it has the form link first rest [INDISTINCT] pattern match variables they’re just variables for what we’ll be matching in those positions, then it’s just the rest of the list having dropped the first link And what if drop one gets a list of type form end of list, what should I do? Well, I don’t know We’ve decided that dropping one element off an empty list it’s just an empty list That seems like a nice safe thing to do All right, we’ll write end of list And do you want to guess what happens if you leave off that second equation? It is probably like, Dude, you forgot one, your missing out, right? So, one aspect about Haskell is that it’s pretty easy to make sure that you’d caught all the cases, all right >> So, it catches that before you actually [INDISTINCT] use that >> LENTCZNER: It catches it at compile time >> [INDISTINCT] >> LENTCZNER: Yes, at compile time, it’s like, You missed one Like if you really want to miss one, go turn off this warning here but like we really don’t suggest you miss one Why would you–why would you not want to miss one? You don’t want to miss one because–all right If you have all the cases covered, then you’re certain the function always has a well-defined value In fact, this is kind of something subtle, it takes a while to get used to If you have all the cases covered then you’re certain your function never crashes and I mean, never in a much more serious sense than the never that you are used to I mean, it never crashes It can’t Like it has a well-defined value, right? If you covered all the cases and the compiler doesn’t complain, all right, then the only possible problem that the function could have–I mean, it might not implement what you’re trying to do, right? It might have a different function than your computer different result All right The only thing it can really do is go often to, you know, go off diverge, go off an infinite computation That’s the only real error that you could have left It’s just kind of fun Okay Here’s another function called Just One It’s a little weird, it takes a list, it returns a list, if the list is just a link then we return a list of just that the first item, right? And what do we do if there’s nothing in the list? We just want to return, I don’t know it’s got to return something or get that compiler warning which yells at me So, I’ll have it return an empty list Okay It seems kind of weird but there’s a function definition Okay Pull back to reality Actually Haskellers, you know, lists are really common We don’t like to type so much and so, this is from the standard library I want to point out a little bit something amazing here
The syntax of the square brackets is actually built into the language but the type list isn’t This is actually defined in a library file who’s source code on your installation, you can actually go find and look and inspect In fact, you can copy them to your own modules and create your own version Which is kind of astonishing, right? I mean, it’s actually built in the language There’s nothing magical about how this works So, here’s everything I just wrote but it’s written with this new notation; notice end of list is written at this funny empty square, you know, double square brackets and link is written by an infix operator called Colin, right? So, Colin puts an item the A onto–and this is kind of a funny list of A. Don’t worry about it too much The syntax of list looks pretty much like what you’d expect, in fact, it’s so much like what you expect, what I wrote is Haskellers don’t even type that much And I flip back the words real quickly between these two, wait–stop that There you go The only real deference is on these lines, people like to write lists this way because they don’t like to write the silly Colin, look at the Colin, right? The string apple Colin linked on to the empty list They don’t like to write that, they like to write apple, you know, inside the square brackets it’s purely syntactic sugar that’s all And these are all the same functions and so much for that Okay Two more standard things and then we’ll get to some code, more code, okay A string is just a list of characters, really Here it is And then there’s this funny other type, a datum of type maybe It has two clauses too just like a list had two clauses but it’s even simpler than list; maybe is either a datum of type maybes, some type–it’s either nothing or just a single value Seems kind of crazy a little minor thing, right? This is how you use it, like maybe if this function takes–pick message gets maybe an integer, right? It has to have two clauses because there’s two forms, right? So, we pick message, if it’s just an N then I’m going to construct this string Pick a number like N, you know, show us how you turn a value into a string, you know, display it And then pick message if the value was nothing, I’m going to say a different message So, that’s how you use it, just pattern matching just like we did with lists So, we have this awkward function called just one, right? Remember I said like, what if the list is empty, what should I do? Like what should I return? It’s really awkward because I want the first thing on the list but just one gives me the first thing on the list but damn it, it’s inside another freaking list, right? It’s kind of annoying, right? So, you might be tempted to write the bad function at the bottom, in which case, you would be bad because look at it, it says, if the list is, here’s some cool notation stuff We like to–we don’t like to type a lot as Haskellers, right? If a list consist of a value A and the under bar is, whatever, I don’t care It’s a variable that matches but doesn’t–no one uses it Then it’s just A, just the first thing on the list but if it’s the empty list, well, I can’t like what A would I return? I mean, if A is integer, should I return zero? I don’t know, maybe zero is a useful value I mean, what are you going to return? Well it turns out it’s like nothing you can return in this case and so you write error and error is this magical built-in function which, like, kills your program and crushes it with a message Actually, it does if you end up trying to use it but–so you don’t want to use an error, it’s a bad thing So that’s a very bad thing to have happened So this one, like, shuts the compiler up but you end up using an error into your program So, here’s a better way So, let’s use maybe because the answer is this function maybe has an answer, maybe it doesn’t All right? And so, this is a much more clean way to right this all right? The first one on the list is maybe of something We have had just or nothing Okay Keep your eye on the code very carefully Here’s a real function that finds the first character after a star So, given a string maybe it’s going to return the character maybe [INDISTINCT] Notice we’re getting rid of nulls, there’s no, like, no nulls in this language all right? Find after star Well, if I have a list of a character and another character and then the rest of the list then if that character equals the star, let’s return just D because we found it, we have a character after a star else, let’s just recurs find after star We’ll put D in front of the rest of the list and call it on that list Let’s have another clause, if all else fails–under bar, this is a catch hall, catches everything, then nothing, there is nothing after a star Got it? Anyone confused on how that code works? No Yes?
>> So, you have mentioned matching semantics are likely to [INDISTINCT] >> LENTCZNER: Yes So the question is, “Are the pattern matching semantics in order?” And the answer is yes They write–they trust in the order that you write them None of this funny reordering or any of that stuff it’s, like, exact–just read it in order, that’s how they test it Makes it easy >> Well, how about just [INDISTINCT] >> LENTCZNER: So, just is right back here There’s this type called maybe, it’s a data of type might So, maybe it has two forms If you have a datum of maybe an integer, either you have nothing or you have just an integer So, there’s two forms Just like the list had two forms A [INDISTINCT] and a cons or end of list and a link So, there’s two forms So we can return either kind–all right, here we could return two things Now, in this case you might be asking–I’m not sure this question you’re asking is just acting like a function in this case; it’s acting like a constructive or building a value of type maybe So, this function is going to return a datum that has either two forms: just a character or it’s going to be nothing >> I think that [INDISTINCT] that when you define a type and give a list of constructors and >> LENTCZNER: No >> …constructors all have the same name as the type >> LENTCZNER: Yes >> …has [INDISTINCT] and give it new names for each form >> LENTCZNER: Yes Right Every form has to have a unique name, right? And that’s how we distinquish them and tell them apart All right And in essence, you don’t–in other language the constructive constructors, you know, you have–constructors are just different ways of building up, you know, an instance of that class but, you know, then you just have an instance that class then are all the same This is sort of the other way around right? When you build up and instance of maybe by using the nothing constructor, it is different in structure than the version that has just the value It actually has a different internal structure >> So, [INDISTINCT] >> LENTCZNER: No, no This is user define It’s not–it actually it’s in the library, it’s standard but this is just built out of a language >> Okay The point when you [INDISTINCT] >> LENTCZNER: Because you always need a tag–there’s tags in the front that identify Think of it as a discriminated union This is like a union of different struck and you need to have a tag in the front so you can tell which one you’ve got And you use that tag both when you build it and you use that tag when you tear it apart When do we tear it apart? Pick message here is tearing it apart, it is looking at the union and saying, “Huh, is this value of maybe have a just tag on it? Oh, then of course it’s got a value A that follows the just tag.” Right? And the bottom one says, “Oh, does this value of maybe have just a nothing tag on it?” Well, of course it doesn’t have anything else with nothing; all it’s got is nothing Nada Okay So, here’s the version that does string just find after star And let me change it to find after char, I’m going to make it more generic, I’m going to give it a argument It takes another argument, a character of [INDISTINCT] M to match And so all I did is instead of saying C double equals–all right, so I gave an extra argument M, you can see it up here, there it is All right, you can see that it does now compares against M instead of against the fix character star, I changed the tag signature, takes a character and a string and returns maybe a character so it finds after this character I had to add another thing here for nothing but–otherwise, the code is basically the same Oh, and when I recalled recursively, I had a pass M again Okay I’m going to make this once more generic So, this function, I made it a little more generic by checking for any character Let’s make this a template and make it work for any type not just strings Ready? One, two, three, go Anyone noticed the only thing that changed? Okay The name of the function, find after elem instead of find after char The only thing that changed here is the type declaration That’s it Now, I did add this very funny weird piece of cryptic nonsense, be brave, you know, trust me it’s good All it says is that A is a type that knows how to do equality, that’s all that’s saying But instead of going from char to string, remember string is just a list of char to maybe char, I just made this generic Go from some type A and a list of As and maybe A. Notice that the code is the same The actual body of the code is identical Yes? >> So, is the type line necessary? >> LENTCZNER: Boy, you’re like the, you know, like [INDISTINCT] man from the question Yes, so Mark, what is the deal here, like what–like what is the type line? The answer is, when we wrote this, the compiler compile the bottom code and went, “Wow, this is a nice cool generic function It finds any element after any other elements in a given list Oh man, he wrote this restrictive types signature, oh well, whatever fine, I’ll only let him
use it in context of chars and strings.” When I wrote this, the compiler did the same thing It read–looked at the exact same code, came to the same exact conclusion and said, “Ha, his type-line is right That’s exactly right That’s the type of that code This code is–this code will work if and only if A is a type that understands equality.” It figured that out because I used the variable here And it figured out that indeed there better be a list because I used the list constructor here And it figured out that the result better be .maybe because I used Just and Nothing It figured all that automatically That’s all it takes to make your code generic It is really common when writing Haskell to suddenly realize that the thing you just wrote for some particular case is actually complete generic and you just fix the type line and go on >> So you then–when you define string as an array of char, you also >> LENTCZNER: List of char >> Sorry You also manually specify the Maybe and the Just and the Nothing types in terms of that >> LENTCZNER: No, no, no >> [INDISTINCT] >> LENTCZNER: You don’t have to achieve or write that That’s all inferred Maybe was written–so when we were at maybe, right so this is just like, well Okay, so what happened like, there’s Maybe int and Maybe char, but I just wrote this thing called Maybe A. No, that A didn’t mean, oh yeah, when you get around to it, like, type a version with replacing A, that really is a type variable So you write that line, and Maybe is now defined for every type: past, present, and future And it’s already [INDISTINCT] Okay, onward Now, Maybe, actually, is really important Maybe is so important that Maybe is actually the thing that blew my mind This silly little teeny tiny itsy bitsy type, this was like the first thing that, like, [INDISTINCT] my first two weeks back in [INDISTINCT] I was like, “Oh, okay.” This is thing is really useful, okay? These functions–I just wrote there type signatures And you don’t have to really pay too much attention to them because just look at the names, these are all functions you’ve used in libraries all the time “Find the index of an element.” “Look up something on app,” right? “Shoot this prefix from this string,” you know “Get the port out of URI.” Anyone every written that one? Okay, these are all functions which may not have an answer And in almost every language and in every library I have ever seen, gee whiz, we write conventions like, “If the element is not in the list, return -1.” Anyone ever been bitten by that? Ever? Right? That is a sucky design All right, that’s just bad Look how easy it is when you have Maybe, you–because you can declare precisely and so here is the first aha that types in Haskell Types in C and C++, as we know, are for the compiler to make sure it lays it out in memory correctly I mean at least initially Types in Haskell are for you to communicate with other programmers what you mean in a really deep sense In a sense I think that is deeper than others All right, so these are all examples of functions where Maybe is far better than returning Null Did Null mean it wasn’t there? Did Null mean it was an error? I mean what is that Null? Like, I don’t know what that Null means Is the empty string an error? Or did stripping the prefix from the string return me the empty string because it was only the prefix or did–you all see the errors here, right? Okay So let’s look how you use this So it turns out this other fun stuff about Maybe because once you have something of this concept into the language or that you’ve been building language, you can now start building better utilities for using it, all right? So for example, all right Here’s a function called addaweek.day, it comes from a library, right? So we add day 7 to some day object and we get, you know, one week later And imagine I’ve got some list of interesting dates and we’re going to use our first one function which given a list returns Maybe 1, right, because if the list is empty, then you get nothing So I want to find, all right, one week later from that interesting date, I can’t apply addaweek to an interesting date Everyone see why I can’t apply it directly, right? Addaweek takes a day, but interestingdate has a maybe a day, right, because it might be a nothing So how do you do that? Now in most other languages, what we would probably do at this point in our code is we would write an If statement, right? If date equals null then do this, else right Okay, and we would probably propagate that null further up the line, if date equals null, return null Else, add seven to the date, okay? Here, we use fmap What is fmap? Well, you know what map is, right? Map is like a function, like, for example, addaweek And map would apply it to a list of days, adding a week to every single one If map, let’s just take a function of days and apply it to a maybe day
And fmap says, “Well, if we just have a day then we’ll apply it to the inner value and return just that And if we have a nothing, we’ll just return a nothing We’ll propagate the nothing Fmap does exactly what we want So, furthermore, if you want to think about this like–I’m sorry, have I lost anyone? How fmap–what fmap does? Fmap takes a function from A to A–actually from A to B, but [INDISTINCT] on that In this case, it takes the addaweek function which goes from day to day, and allows us to apply that function inside–to the value inside a Maybe If there’s a Just in there, we’ll apply it If there isn’t then not Of course, we think of–yeah? >> [INDISTINCT] >> LENTCZNER: Well, it’s in the library But it is user-defined, yes >> [INDISTINCT] >> LENTCZNER: Ah, how does this–how does it know how to apply the real value or not So here’s an even bigger sort of–here’s a Simon for a true head explosion, how that is done is not built into the language either That’s in the library as well So you can go and find how fmap is implemented And you’re like, “Oh my God, it can do that That’s cool.” A little outside the talk, but >> [INDISTINCT] >> LENTCZNER: That is true, right >> [INDISTINCT] >> LENTCZNER: Yes, there is writing code for that Although–yes So–all right, so fmap, in the same way that I said, you could think of map as taking a function from A to B and turning it into a function from list of A to list of B, we’re going to give fmap, at least in this context, as taking a function from A to B–or in this case, day to day–and turning it into a function from Maybe Day to Maybe Day Fmap is lifting your function up into this other environment Okay, and so you can do a week later Now, the cool thing about this stuff is that all the stuff is in the library And you can build things which end up being really powerful Here’s an operator It’s got a funny spelling, greater than vertical barl, less than–greater than the vertical barl, less than, whatever You can define your own operators out of symbols and Haskell Amuse-Bouche, people sometimes do This function don’t pay too much attention to it It does exactly what you think it does It is short-circuit evaluation on–based on maybe It runs the first function, favorite show, which returns maybe a string if the person has a favorite show, or it returns show with name, right? And it does show with [INDISTINCT] so it takes–by four it takes two maybes and if the first one is just a value, it returns that If it’s nothing, then it returns to the second one It’s short-circuit choice The cool thing about this is, this is not–right–now, we all work in languages with a short-circuit choice, but they’re generally built in and you cannot build user operators to do the same thing, or user functions that do same thing Must you’re working in common less when you’ve got some–or scheme and you’ve got some great macro system, right But, you know, most of us are stuck with, you know, C++ Where you can’t really do this, it turns out you can make your own functions do this kind of stuff all the time because it is lazy And so, the reality is that, any of these operations can be extremely complexed to compute, but because the Or operator will never, you know, if your operator never selects that option, and never returns it, the computation never actually gets done So, that’s kind of fun Here’s another common thing we often do, all right So this would’ve been a series of ifs have we–have to write this was no, as the key value as the value indicating that there was no answer [INDISTINCT] so this is much more concise, all right Okay Here’s another thing we do, so here’s a set of functions that, like, get headered, it takes a string and a message and maybe gets a string because there might not be a header And parse state gets a string and maybe returns to a day because maybe it isn’t parseable And mailbox for a day, it takes a date and maybe we have a mailbox and the user’s file system for that date or something, you know, who knows what that function does but they’re all valued to maybe And so what I wanted to do is, I want to pass the values along stopping at any point in the sequence in which I get nothing So get header for a day, that answer is nothing, we’re done we return a nothing Otherwise, I need to sort of unwrap the just value and pass it to the next function, parse state which if it succeeds in parsing that header as a date, then I want to unwrap that maybe to just get the date value out and pass that to mailbox, all right So we would normally write this as a giant cascade of ifs, a nested ifs all the way at the bottom And the else [INDISTINCT] to the whole–either we’d return from the inner part or worse, if we had to continue to use the value we’d have to set some value It’s the default value at the top or no, and do the [INDISTINCT] you know, it would be some horrible nested thing And so, we have this kind of injection operator, it’s pronounced “bind”
Which is does that Now, I won’t give quite too in there but it’s get a little bit to the question about like, how does it know how to do F map So, it turns out that these functions, these things, these operators are actually part of type classes which I’m not going to explain too much But, are wonderfully useful and the answers is that they’re highly generic so it turns out we can use F map actually over lists We can use that alternative thing with lists, we can use it with–we can use bind with things that are monads These things are highly generic and get used for lots and lots of it’s [INDISTINCT] places Okay Do we have time for just one more? Yes, we have 11 minutes so, go Now, the thing I really love about Haskell, one of things I really love It’s a strongly type language, that types really help you encode what you mean to say to your fellow programmers, the types the compiler will really catch your ass when forget at light, oops, you didn’t cover the empty case, you know, it’s really nice But here’s the thing I like most about the types in Haskell, you don’t actually type them very much Okay Here is a wrong lengthing code function, I will not through how it works, you can work that out It’s a fun little puzzle Well, it’s not really a puzzle, just a fun little piece of code The only type declarations are on the very first line, it says if A is a type that knows how to do equality, then given a list of A, I will return a list of pairs of A and an integer right, this is standard wrong lengthing code Okay And blah, blah, blah And now I’ve got–I’m aware lets me introduce like local functions, these are just local functions that I’m only using inside this other function that’s where the ware clause is I’ve got local variables, I’ve got this crazy function called next group which seems to take one, two, three arguments, I think You know, it’s got tests, it’s got all the stuff in here The only types I wrote were up at this top line And yet, right The type of every single thing on the rest of this function has been completely inferred by the compiler, checked, verified And I get all that protections for all those things even though I didn’t bother to ever write their types All right This is like the–so this is just like [INDISTINCT] it was like, wait a minute, it’s all the benefits of type checking or even more benefits of type checking but I write it like I used to write python or I didn’t write types anywhere, like, oh, that’s nice I don’t have to write all those things Now, C++, x11, 0x11, whatever it’s called these days has auto, the auto type which is somewhat like this, although I don’t believe it’s quite as powerful or quite as hubicueous And, you know, there are languages that we use that sometimes have types or not, or let you–have things un-typed This is great This is types that you don’t type-checking but you don’t ever type them Now, let’s compare that to C++, are you ready? That’s fun There are a lot of types here, and what bothers me most is the programmer is There are a lot of types that are repeated a lot Okay So first of, I have to tell, see something that this is generic, okay, whatever Now, I have to decide list of a pair of Ts and Ns, okay that’s a lot more wordy than the way you write then in Haskell but I had to write that on Haskell And it takes as an argument a list of Ts, I had to write that in Haskell too, we’ll ignore the constany Then I have this local variable and crap, I had to duplicate the freaking type again and I had to do that And then, here’s the one I really love I have an etorator but I like that I have to type, type to tell the compiler that the next thing I type is a type Right? I mean, this is really bloody awesome Now, it’s true, C+–the new C++ will you write auto there in and will figure it out Yey, C++ learned something from Haskell or other type inferencing systems But, there’s a lot of type stuff you have to write here and it’s pain, and it’s knarly, and it’s in the middle of all the damn code and it annoys me By the way, just another minor little point, the type systems has lots–it can lets people do crazy wonderful things If you’ve never encountered a quick check library, I don’t know if Haskell was the first quick check library but I think–and who knows But it’s certainly–here’s a bunch of properties about that run length encoding function I just simply read them as functions from a given input and to bullion and I expect these all to be true Like, I expected the length of the list equals the sum of the second elements of the run lengthing coded lists Oops that’s mine–sorry, that line is really long, right And run length code the list, I take the second elements of all the sum and I summed them and I expect that to be the length of the original list That’s kind of, you know, a run length encoding invariant And these are all various invariants that I just I wrote Okay I would like to actually test this, so I could got to my unit and test, frame, or can write, you know, several hundred, you know, unit tests so I could write–well, I probably write maybe a dozen tests unit, you know, tests cases for this by hand But in Haskell, because of the type system I can use the thing called quick check and I can ask quick check just to check this function and quick check will derive from the type
of the function, the possible set of inputs, like it could go there Then generate test cases and it’s relatively smart by generating test cases that actually matter, like, you know, like, oh it’s a list I better try empty list that’s got to be really important I better try a list of just one item, you know, it gets all the good corner cases And it generates cases so this actually allowed me to run 300 test cases on my run length encoding function You can actually, really, honest to god, like, pull this in, type it and run it This is the entire–sorry, that plus this, plus the loading the module quick check is all it takes to be able to run this There was no actual additional scaffold thing I’ve left out Okay So, that’s actually really sort of fun Okay So a few other things to point out about the Haskell ecosystem, we’ve gone to the language a lot but the ecology of Haskell is actually tremendously nice to work with GHC, the Glasgow Haskell–the glorious Glasgow Haskell Compiler is the–probably premier standard and the most common used compiler now It has a command line ripple called GHCI the interactive version which is just a delight to use It’s really trivial load all where all these code up in there and reload your code and you can ask if things like, I wrote this code and I didn’t write a type signature, can you tell me what the compiler thinks, the type of this code is? That’s actually really common for Haskell programmers to do I don’t want to figure out what it is, you just tell me Cabal and Hackage, Cabal is a packaging and building subsystem and Hackage is a very large package repository of now about 3000 packages Cabal is the nicest package manager I personally have ever used It’s the only one I know that knows how to install things locally just for you by default You know, it can do system installs or personal installs and it does all the recursive dependency analysis and download and configure and reinstall those things and it’s just enjoy to use Hatek is the inline documentation system which I worked on so, recently so it–but it’s nice and it looks cool Hugo is astonishing Do I have three seconds to show you Hugo? I do Okay Oops, that’s what I want to do All right Hugo again, the power of types, Hugo is a search engine for code that you’ve never seen the–just–let’s say I have a function, I need to go from maybe some value and the list of values and I want to end up with the list of values Is there a function that does that? Oh, yeah there is So, you can actually–or you can see like, what’s a better example? Like, I’ve got a–I’ve got a string I’m looking for something that’s like a, I don’t know You know, what manipulates two string, you know You can actually search by type signature and find all sorts of wonderful functions that you need It’s astonishing how quickly it is to find what you need And the search is not just what’s–the search is like all the packages and stuff, so Hugo is very wonderful and great It is worth noting that–I think it’s a very recently hash Haskell and freenode was the largest room, I see it has typically 6700 people on it It’s a very friendly community and it’s a really great place to get your questions answered anytime of day or night, just kind of fun Want to learn more? Go Haskell internally, we’ll get you a bunch of stuff including some of these links as well Haskell is actually used here at Goggle and if you select secret corners find out more there What else? Learn new Has–these are some great online tutorials and stuff and, we’re done, thanks I have two minutes for questions >> What does it look like when you write something [INDISTINCT] >> LENTCZNER: So, yes What does it look like when you write big table or some big giant server, and is it this pretty? The answer is, yeah Lots of it are, so one of the nice things about Haskell is it’s very easy to cleanly separate that parts of your code, it’s really good and [INDISTINCT] is modularity and reuses very, very high and so often is really easy to take the parts of your code that knarly in dealing with the, you know, with the network stack in dealing with, you know, the vagaries of–well, like [INDISTINCT] back in web servers and Haskell that do standard stuff talking on my sequel And it’s very, very easy to sort of incapsulate because you could do always nice [INDISTINCT] functions that deal with the IO stuff or deal with the database stuff You can stick that on the scion and have like your logic be nice–and your logic and your business logic, if you want to call that back in stuff really clearly separated out It’s also the case that, because of the high orderness and laziness often in libraries, we have to–because we don’t want the user to actually execute user code if it’s not
necessary, we all have to bubble control back out to the user Users of libraries are generally have to do the control operations Highlable control operations and Haskell you can–you can bury all that back down in your library so, the short answer is, yeah it’s a lot nicer In my experience writing the exact same server in, well big server library in C++, python and Haskell, the Haskell code was literally one-third the size I can give you pointers that code’s open source if you want to actually see the comparison of Haskell that’s one-third of the C++ size It’s about half the size of the python Did I say Haskell? That’s like, python Yes, there’s a question over here? >> Actually, I want to know which office has all the [INDISTINCT] >> LENTCZNER: Yeah, who’s the big office is that? >> Big or [INDISTINCT] >> LENTCZNER: Oh cool, wow Hi New Yorkers Great Anything else? >> [INDISTINCT] >> LENTCZNER: I can answer that question offline >> [INDISTINCT] build system, is the build system supported? >> LENTCZNER: Yes, it’s in the, yeah Yeah, out build systems had stuff in it Blaze has support for Haskell >> What kind of [INDISTINCT] >> LENTCZNER: Well, I don’t like to write client web front end code because I can’t get the damn Haskell to run in time The processor on the front end I would in an instant You know, in my mind Haskell has, of the last couple years finally traversed into the realm of like, yup It’s a good general purpose programming language enough functionality is to almost any kind of stuff that you need I don’t know, I’m too much of a sand to answer that question My answer is I do everything in Haskell if can All right I can stick around and we’re officially over and we can stop the recording, thank you And I’ll stick around if anyone wants to talk or go over or find a