diff --git a/podcast/78/transcript.markdown b/podcast/78/transcript.markdown new file mode 100644 index 00000000..9d33f4fc --- /dev/null +++ b/podcast/78/transcript.markdown @@ -0,0 +1,221 @@ +*Samantha Frohlich (0:00:15)*: Hello and welcome to this episode of the Haskell Interlude. Today we’re going to be doing something a little different. We are going to be focusing on a particular part of Haskell: teaching it. So, Farhad and I — + +*Farhad Mehta (0:00:28)*: Hi. + +*SF (0:00:29)*: — are joined by Jamie Willis, who is a teaching fellow at Imperial College London. We’ll discuss live coding, botany, and why Haskell is the best language for teaching programming. + +Okay. So today we are joined by Jamie Willis from Imperial College London, where he is a teaching fellow. Hello, Jamie. Welcome. + +*FM (0:00:53)*: Hi, Jamie. + +*Jamie Willis (0:00:54)*: Hello. Thanks for having me. + +*SF (0:00:55)*: Yeah. So, how did you get into Haskell? + +*JW (0:00:58)*: How did I get into Haskell? There’s two ways in which I got into Haskell. The first was I learned it as a first-year undergrad. And when I say I learned it as a first-year undergrad, I definitely did not. Did I do Haskell as a first-year undergrad? Yes. Did I understand it? No. Mostly because I think I was very stubbornly clinging to my favorite bang bang. Life wasn’t great. + +Then, in, I think, the summer of 2016, one Nicolas Wu, who I believe has never been on the podcast and absolutely should be, he asked me to do an internship with him. And I was like, “Yeah, sure.” And he was new to Bristol at the time. What he asked me to do was to rewrite the compiler that I had written over the summer — well, over the previous term in Haskell. He had other grander plans for me, but he needed to bootstrap me first because I didn’t know Haskell. During that course, I basically wrote a little Python compiler to Python bytecode in Haskell. And this was my first proper exposure to Haskell. And I’m going to claim that’s how I got into it.  + +My sort of aha moment was one of the stipulations he put on it was that I had to use parser combinators. Before that point, I hated parsers. Parsers were the worst thing. Didn’t like this whole LR, LL nonsense. And then did not vibe with the ANTLR, didn’t like parser generators. And here I was confronted with parser combinators. Obviously, I had to learn them. But the way that Nick taught it was basically being like, “This operator, this one here, let’s just put some together.” Fine. And so I got used to it. + +And then I think my big click moment, where I was like, “Okay, now Haskell is cool,” was I needed a parser for signed numbers. And I was like, “Well, I have a parser for natural numbers. If I can pass the sign, if I can get that to return either identity or negation, I could act them.” And that was like my click moment, where everything suddenly fell into place. + +That half made me a functional programmer. I was already half a functional programmer in denial, because I was a Java programmer who really loved streams. Streams were my jam. And yet, I hadn’t put the connection together with Haskell yet. So that’s how I got into Haskell.  + +And then the only thing that Nick did wrong in this venture was that, in an effort to try and get me into Haskell and off of Java, he said, “Have you heard of Scala?” And I said, “No.” And he introduced me to Scala. And he was hoping that this would be a gateway. And in reality, what it did was it turned me into a Scala programmer. So I’m both a Haskell programmer and a Scala programmer. But yeah, that’s my origin story, summer of 2016. + +*SF (0:03:27)*: How did you go from undergraduate summer 2016 doing an internship to a teaching fellow at Imperial? + +*JW (0:03:33)*: Yeah, so that’s also a pretty fun story. When I was at Bristol, Lloyds Bank was running a scholarship scheme. That no longer exists anymore, sadly, but the idea was that they would support you through university. So you’d get some money for doing some stuff, and you’d get access to some internships and things like that. And the requirement that they put on it was that you had to do 100 hours of volunteering a year. + +In my first year, obviously, I did my 100 hours, but it was quite difficult. You really struggled to find volunteering stuff that fits around your studies and stuff like that. And then in second year, I had a hack. I was like, “Hang on, what if I volunteer as a teaching assistant?” So I didn’t tell anyone. I didn’t go to the school office, and I was like, “Hi, I would like to be a teaching assistant, but you don’t need to pay me.” I just sort of rocked up to the labs, got adopted by the TAs that were already in the lab, and did my 100 hours of volunteering, and then some. And during that process, I was like, “Huh, I really like this, and I’m quite good at it.” I completely changed tack from that point. I was like, “I’m going to be a teacher.” + +And then basically, what was happening was, concurrently to all of this, Nick was constantly asking, “Do you want to do a PhD with me?” And I was like, “No,” repeatedly. And then we get to almost the end of my degree, and I tell Nick, “Yeah, I would love to be a lecturer. That’s what I want to be.” And he just smirked. He was like, “You’re going to need a PhD for that.” And I was like, “Ah, okay, you got me, you got me.” + +So I joined Bristol as a PhD student, and they sort of created a special thing there, which I would now know as a teaching scholarship. But at the time, we didn’t really have a name for it. Ironically, it was based on a scheme that runs at Imperial. I was there for a good year. I did some PhD stuff. Then Nick took a job at Imperial and took me along with him. So I actually had to apply for the real teaching scholarship that was at Imperial. And I got in. + +And then a couple of years down the line, Imperial has a course called Advanced Programming, which is like an extracurricular, and I was invited to give a lecture there on the state monad. The Director of Undergraduate Studies at Imperial for Computing was there. He was in attendance. It was kind of his course. He saw my lecture on the state monad, and then he emailed me afterwards and said, “When are you finishing your PhD? You need to be a teaching fellow here.” That was basically its set in stone.  + +So from that point, it was like the race was to finish the PhD and wait for the department to find an opening for a teaching fellow and then apply for that. And then that all worked out. And here I am. So yeah, that’s the story. + +*SF (0:06:00)*: What was so amazing about your state monad lecture? What’s the secret sauce to teaching Haskell?  + +*JW (0:06:06)*: I think the thing about that lecture was it was quite practical-driven. If I remember correctly, I took one of their weekly exercises that they’d already done. It had a bunch of state threading. It was awful. And of course, as Haskell programmers, we look at that, and we’re like, “State monad goes there.” My trick is that I didn’t show them the implementation of state once. I basically refused to. So all I did was I showed them the operations. I gave them some intuition about how we could compose them. So we wrote modify with the get and a put, and we built some of the small things. And then it was mostly just like, “I’m going to show you how to solve this problem.” Either you’re going to get some insight about that, or you’re not. You can’t catch everyone. But I think, compared to going into the weeds, where you spend a bunch of time trying to write the instance and creating the monad from scratch, I think just showing how it’s used, and then going later and being like, “Oh, I actually see how that does the plumbing,” is the more effective strategy. That’s how I approached it. And I just did a very sound job, which was good, because the previous time I’d done a lecture on monads, I completely fluffed it. It was awful. I lost everyone.  + +I think it was one of my very first lectures. I was an undergrad at the time. I was really good at one-to-one teaching, but one-to-one teaching strategies don’t scale because normally, if someone doesn’t get something, you just change tack, and you can keep changing tack, except when you’re in a room full of people, that doesn’t work because you’re going to lose the other half when you do this. I just kept changing tack until I’d lost everyone. It was a mortifying nightmare lecture. I was like, “No, this is the worst thing I’ve ever done. I’m never doing that again, never teaching monads.” So this was my redemption arc with that lecture there, where it was like, not only did I successfully teach monads, but I got a job offer out of it, or a job suggestion, rather, because it still took many years before that would materialize. + +*FM (0:07:57)*: And you currently teach Haskell at the undergraduate level. Is that correct? + +*JW (0:08:01)*: To an extent. So, I teach advanced programming. That’s true. And I also teach the sort of practical lectures in the Haskell course. Last year, I taught the full thing. So I did actually teach the whole of Haskell, but that’s because Nick was away on sabbatical. So when he came back, he wanted his course back. So, I don’t teach the whole thing anymore, but I’m still very heavily involved in both the labs, the practical lectures, advanced programming. I also write the tests, but I only got to teach the full course once. It was a good year. + +*FM (0:08:34)*: So, which semester do the students normally have their first exposure to this? + +*JW (0:08:38)*: I was their very first lecturer. So first lecture at Imperial. + +*FM (0:08:42)*: First lecture first. Wow. Okay. + +*JW (0:08:45)*: Yeah. Haskell. + +*FM (0:08:45)*: So first semester, they’re fresh. They’re totally fresh. + +*JW (0:08:48)*: Mm-hmm. + +*FM (0:08:48)*: Haskell is the first thing they see. Okay. + +*JW (0:08:50)*: Yeah. Haskell is the first thing they see. The way we kind of rationalize it is it’s like a great equalizer. So, you’re going to have students that come in with no programming experience, and you’re going to have people that come in with loads of programming experience. And the ones that come in with programming experience are the worst. They already have a way of doing things. They already have habits. I remember coming to university with programming experience. My code was awful. At the time, I thought it was great.  + +The idea is, like, if you just taught a conventional language, like, say, I don’t know, Python, then you’ll end up where half the cohort is completely lost, and the other half is absolutely storming ahead but also not learning anything at all. If you teach Haskell first, everyone is confused. And this is a good place to start. People that have a more mathematical background are going to be like, “I see what’s going on here.” People who have an imperative programming background are going to basically be slapped, and we’ve got to get them to relearn how to program in the way that we want them to think about it. That’s kind of the strategy, and I think that’s a decent one. At least, from talking to my tutees last year, they came in, and a lot of them said, “Yeah, I have programming experience.” And then by the end of the six weeks where we do Haskell, they were like, “I’ve come to understand that I didn’t really do any programming, and now I understand programming.” + +So, I think it definitely works. It’s pretty cool.  + +*FM (0:10:10)*: And where does this fit into the general curriculum at Imperial? Is this course called Functional Programming, or is it just called Introduction to Programming? Or what is it called, and how does it follow up to the other stuff? + +*JW (0:10:22)*: It’s got a really dumb name. It’s called Computing Practical 1. + +*FM (0:10:25)*: Oh, wow. + +*JW (0:10:26)*: So, I think there are plans to change the name. I don’t know what it’s going to be yet. But it is a big module. In the same module, it basically transitions at week seven to Kotlin. Then you roll all the way through spring, you come out in summer, and then it switches to C. So it’s definitely not a functional programming module. It’s like a programming paradigms module, where it’s like we’re going to expose you to three major paradigms and hope that you draw connections. I think most people come out of it thinking, “Oh, yeah, they just taught us three languages.” It’s like, no, that’s not what we were doing.  + +But yeah, it transitions into Kotlin after that point. It used to be Java. And then we modernized. Of course, it’s a university, so modernization takes an age. By the time we switched to Kotlin, Java had become the better Java. But hey, ho. So yeah, they switch on to Kotlin, and they do object orientation for a bit. But they also take some of the functional programming through with them. And then they move to C, where they’re on their own. + +And Haskell does come back. So we teach the algorithms course in second year, also taught by Nick. He’s taught in Haskell. It’s like the most unconventional algorithms course, I think, that exists because I would say it’s a course about immutable data structures, which is really just a valuable topic. Immutable data structures are great, and they’re not just for Haskell. But it’s a course about that and the connections between data structures and algorithms, rather than like a traditional algorithms course, which sort of just blurts out various things about pathfinding and graph traversals and all kinds of random problems I’m never going to need to solve again. + +So Haskell appears there. And then it’s one of the officially supported languages for their big compilers project in the second year as well, alongside Scala. Haskell has quite a presence at Imperial, but we think that it really builds strong programmers, giving them that top-down perspective first, where they can think about how to destructure problems, just leads to the sort of high-quality graduates that we end up having.  + +*FM (0:12:15)*: Interesting, interesting. The curriculum at Imperial is, I would say, non-standard. I’ve taken a look at many of the curriculums all over the place. You are a bit of an exception, given that you do focus on this functional programming aspect. I find that a bit sad, but I tried in my sort of faculty to get functional programming. And the furthest I got it was a second-semester course. I mean, the first semester course, I would have gone thrown out. How do you see this? I mean, I think it’s also very personality space. I guess you really need to have someone who really has some amount of political leverage in order to do this. Why do you think we are in this position at the moment? I remember when I did my undergraduate, functional programming was basically the course I learned. It was called Introduction to Computer Science. Why are we so marginalized now, as in the FP community? What do you think about this? + +*JW (0:13:03)*: So I think at Imperial, it’s very deep-rooted and cultural. It’s got a strong history of this. But I did some looking into this. What I found is, if you look at how strong a department’s programming languages group is, that seems to be a pretty good correlator for the languages it teaches. You look at them, and you sort them by their CS ranking or whatever, and you find that all of the top ones are all teaching Haskell. The top two, which are Imperial and Oxford, Oxford is the top one, and the only difference they have to Imperial is that they teach Haskell than Scala. So they’re slightly more functional-programming leaning. And I’ve been trying to push for Haskell than Scala at Imperial for ages. The problem is, it’s not enough to differentiate Kotlin and Scala for that to be a compelling sell. If we were still teaching Java, I’d manage it. + +I think if you look at those, like Bristol’s another good one, really massive programming languages group. They’re teaching more modern programming languages that give exposure to more of the paradigms. And I think that’s kind of it. A weird thing I’ve observed about PL people is that they’re always the best teachers. Purely anecdotally, it seems like all the really, really good lecturers that I’ve run across in my time in academia are very often PL people. I don’t know what it is about them. They seem to have more of a passion for teaching, maybe because the programming languages stuff is so fundamental and early that you really can just dig into it.  + +And so you get a lot of strong personalities as the teachers, and that really engages the students as well. I think it just rolls like that. It’s like the strength of your PL presence in the department, because, of course, you would have PL people teaching PL modules. And if you’re doing that, of course, they’re going to have the same kind of attitude of, like, we want to teach abstraction and top-down thinking.  + +But it is a bit of a shift. I mean, the way it works for Imperial is that, really, we want to change the way they think, and we really pride ourselves on the strength of the programming skills with the people that come out. If you start with other languages, I don’t think you get that depth. I mean, there’s evidence to suggest this. There was a study done. I can’t remember exactly what university it was, but it’s one in Sweden. They taught Java across two years. So, first year and second year, not temporarily two years.  + +At some point, they switched to teaching Scala in the first year. So they taught Scala and then a year of Java. And what they found was the quality of Java being written at the end of those two years was higher as a result of having done Scala first. I think that’s true. I think that’s also true of Haskell. The exposure they get is making them stronger programmers overall. And that’s the strategy that Imperial is going for. It’s not about which language is the easiest to start with. We know Haskell is not the easiest language to start with for most, but we think it has more value. + +*SF (0:15:50)*: Speaking about starting with Haskell, where do you start? Because there’s a lot of interlinked things to get going. We keep changing at Bristol our functional programming course because we can’t decide where we want to start. Where do you start? + +*JW (0:16:02)*: Yeah, it’s controversial here as well. I mean, you’ve got your basics, right? So you need to cover expressions, types, and functions in some order, in some way. The three of us that have taught Haskell here at Imperial within a span of five years, I think, have all done it slightly differently. Tony, who used to teach Haskell before Nick, his first lecture horrified me. He basically starts with expressions, spends the entire time in GHCi. And that has all sorts of weird consequences because he asks, “What’s the type of 7?” And suddenly Num a is existing in the first lecture. And he showed list comprehensions in the first lecture as well, and things like that. I was like, “Well, this is crazy.” + +If you leave Nick alone, Nick’s first lecture is just types. So he’ll start with all the types. He does counting with types. So he’s like, “What is the number of elements of a pair of A and B?” and stuff like that. I was doing a hybrid of Tony and Nick, but when Nick isn’t left alone, what he teaches first is functions, because if you teach types first, they get a bit lost in their first tutorial because they can’t do anything yet. I was teaching functions first and sort of basic functions, just trying to link it to maths and what they should already know, like what their baseline already know, and working out from there, and kind of highlighting the importance of expressions, because the big thing about functional languages is the equational reasoning, and that comes from the fact that we’re expression-oriented, sort of doing that step by step. Well, how do I evaluate something? I substitute this definition in, and then I substitute this definition in, and then I collapse them. That was kind of my focus in the very beginning. In those first three hours, basically, there’s three lectures in that very first week, Thursday and Friday, they’re just doing these bits. + +But I think Nick went for something new this year, where he wanted to motivate it a bit more. So he taught a bit of the lambda calculus, which was rogue. Yeah, it’s like it’s always in flux. And I don’t really know exactly what the best way is yet, because as I understand it, I think Bristol this year decided to opt for a mini version of Haskell, right? Where you took away all of the fancy bits, and you were left with the core lambdas and case and literals. + +*SF (0:18:13)*: Yeah, we had a student make a little interpreter. It wasn’t quite for Haskell, but for a Haskell-like language. And on his user studies, we found that students preferred case expressions and then pattern matching. So the actual construct, and then the syntactic sugar, because they’ve been struggling with pattern matching for whatever reason. But when we did this user study, and his mini language just had case statements, they were like, “Oh my gosh, I get it.” So we went fully to that. We went lambdas, case expressions, and we’ll find out if it pays off. + +*JW (0:18:49)*: So, I mean, what is your perspective at the moment? Did you think that that did work?  + +*SF (0:18:53)*: So the TAs for the first lab were really like, “Yes, this is like their —” because it really rocks the boat. They come in. I think we were their second lecture, 10:00 a.m. on a Monday of their first week of uni. And we throw this at them, and they’re like, “Oh.” But we think we’d much prefer that they go, “Oh, gosh, I actually need to think about this,” than have a misconception. + +*JW (0:19:17)*: Yeah, right. + +*SF (0:19:18)*: Because if you come in with C knowledge, you’re like, “Oh, I know what a function is,” or “I know what a variable is.” And this misunderstanding lurks and doesn’t get addressed. Whereas we were rocking the boat. + +*JW (0:19:31)*: 100%. I mean, I kept saying it this year. This year, my catchphrase is, “In order to learn, you must be uncomfortable.” + +*SF (0:19:39)*: Yeah. + +*JW (0:19:39)*: I’ve kind of observed this, because our weekly exercises now have mark schemes, a revolutionary new concept. So I can actually see trends now. And what I’ve observed is they learn something in the early weeks, and they’re like, “Great. Pattern matching, recursion, I can live with this.” And then they just stop. There’s a lot of people that just stop at that point because they get that, and it’s what works for them basically 100% of the time. They don’t get involved in being uncomfortable. So they’re not learning about higher-order functions, because it’s like, “Oh, I don’t quite understand those. But recursion works, so why wouldn’t I just use recursion?” And they’re not getting out of their comfort zone. And it shows, because those mark schemes are getting harsher and harsher and harsher on not using those things.  + +So yeah, I think throwing them completely out of the comfort zone to start with is probably a really great idea because they’re forced to engage in exactly what you want them to know. So that’s interesting. Maybe we should do this. + +*SF (0:20:36)*: Speaking of comfort zones, what do you think about the use of students speaking to LLMs to get help? Because we’ve noticed that happen a lot because it’s a lot more comfortable to chat to your LLM friend. + +*JW (0:20:49)*: Yeah, this is the thing. So my strategy for this year has been whenever I see a student with an LLM in a lab, I go up to them. They’re probably trying to fix some code. So I’m like, “Oh, have you tried Ctrl+W?” in the most innocent way. No one who’s on this call pressed Ctrl+W if you don’t know what it does, which, of course, closes a tab. So they just close the AI tab. I’m like, “Now think for yourself,” and I walk away. It works every time until they know what Ctrl+W does. But it’s a teachable moment. + +The problem with it is that generative AI is like an overly enthusiastic teaching assistant who’s also not very good. They will just tell you the answer, which, training number one for teaching assistants, is you don’t tell them the answer. You ask them somewhat leading questions that help them get to the answer. The bad TAs are the ones that just cave, right? They give up, they tell you the answer to your problem, and they go away. LLMs are like that, with an added dose of overconfidence, which is even worse. So they start learning misconceptions and stuff from it. And basically, I make the bold claim that you can’t learn from AI, which is not entirely true, but it is true when you don’t have the critical thinking skills to distinguish between garbage and useful information. Yeah, it’s a problem. It absolutely is a problem. + +I’ve heard from a former student about my own teaching. He was like, “When I was a first year, you bugged me because you wouldn’t tell me the answer to things, like, ever. You would always just keep digging.” And at the time, this was really frustrating. And then when I came out of the other end, I realized quite how valuable that was. And he became a teaching assistant, and he would do the same thing. And he was like, “I was directly inspired by that,” because he was basically out of his comfort zone the entire time, and so was learning. And if I was just giving him the answer, he’s gained nothing from that. + +*FM (0:22:37)*: Talking about comfort zones, what is the comfort zone of your students at the end of the course? I guess you must have some sort of student feedback survey or something like that. What percentage of the student population do you think warms up to this? With me, I would think about a third. What is it? What’s your experience with this? + +*JW (0:22:56)*: It’s hard to judge, actually. They have this hard transition when they go from Haskell to Kotlin, and it’s not even across a break. So you might imagine you get to the end of term, you go away for a while, you come back. No, it’s from one week to the next. It’s like suddenly ta-da, Kotlin. And at least last year, the sense I got on the ground was that people were not happy about that. So there was a lot of grumbling. There was a lot of, like, “Why are we doing this? This is awful.” And that gave me a good sense of, like, a lot of people are taken to Haskell. I think this year there is more of a sense of a few, which is something we understand. So it varies per year, because, of course, the end of our course does hit to monads. So it ends on a hard note, or a traditionally hard note. So yeah, it’s kind of difficult to judge. But you do get a lot of people that do retain that interest. But it is hard to judge numbers. I don’t know exactly what the proportion is. + +*FM (0:23:46)*: Do you get a storm of people coming up to you and saying, “Hey, can I do a project as part of my bachelor’s thesis in this?” Are there a lot of them? + +*JW (0:23:55)*: Yeah, me and Nick are both quite popular in this space, a little bit differently for me, because they get exposure to me again in the second year. A lot of my projects are about that side, and the Scala side, and parsing and stuff. But yeah, we are quite popular as supervisors. I get the feeling that generally, there is a very good understanding of functional programming, especially those fundamentals. Everyone knows folds. That’s the most sort of transferable thing that you’ve got. Like monads, sure. Monads are great. But also, do you need them in any other language? Probably not. If they don’t quite get monads, fine. I’ll let that slide. But if they can take folds and higher-order functions and the thinking, and I think generally that most of them do, so then most of them are hitting that key there. + +I mean, to put it in perspective, last year we wrote a final test. So our tests are actually programming tests, timed and in exam conditions. It was an awful test because it was a homogeneous test. It was a mistake. It was about recursive descent parsing, but it involved monads, because you want to handle failure. And so the Either monad appeared. And as a result, it became almost solely a monads test. You could get through it without knowing monads, because you can just pattern-match your way to victory. So the most common mark was that, basically, people that pattern-matched their way through most of it, perfectly happy. That was in the 60% range. And then, surprisingly, the second most common mark after 60% was 100%. And these are people that got monads and just blitzed the test because if you knew the monads, there’s nothing difficult about it. You can get through it very quickly. But that gives us a sense of, like, wow, second most common mark. There are a lot of people that got monads and got through this. + +So, in terms of a good litmus, that was also pretty impressive because we’d always been afraid of examining monads before that point. This is the first time we did. And the person who wrote that test basically said, despite its flaws, was just like, “No. Well, this proves we can examine monads.” We’re just never going to do it to that extent, but I’d say that from that, we’ve got pretty good outcomes in terms of the functional programming teaching. + +*JW (0:26:03)*: Nice.  + +*SF (0:26:03)*: We’ve spoken a lot about the structure of the course, but how do you actually do the teaching? Do you use slides? + +*JW (0:26:11)*: If only I was that prepared. I hate slides. I hate slides for a couple of reasons. The first is they’re so unengaging. They don’t allow you to showcase how to think or the thought process. And they also are always correct. Okay, that’s a lie. Most of the time they’re correct, or at least once you’ve run them once, they’ll get corrected, and then they’ll be fine. The person who’s delivering the slides can feel a bit like they can do no wrong. It also gives an indication of exactly where you are in the lecture, which you might think is a good thing, but it’s not when you’re running behind or you’re running ahead. And the students can tell, right? They can smell the blood in the water. It also blocks off avenue for discussion. There’s nothing worse than having a small discussion in a lecture, and suddenly the lecturer realizes, “Oh no, I don’t have enough time,” and is now frantically flicking and skipping through slides. It’s the worst. + +So I just don’t, unless I’m teaching a course where I kind of have to. My strategy is I’m going to start with a blank LHS file, and we’re going to write things. It’s kind of inspired by the way that Nick does it, except Nick uses a notebook and writes by hand, which is wild. You can’t even guarantee his code compiles. But it basically goes like, yeah, I’ll do some writing. I’m going to talk about some concepts, and I type quite quickly, which can be a bit of a shock. But once you get used to it, it’s like what you find is I’ll tell you about the idea, and then I’m going to write a lot of examples. Whereas Nick’s a bit slower. He’s more methodical. So he’ll talk more, but he gets to write less examples because he’s handwriting, and it’s just prohibitively slow. And it’s quite difficult if you need to flip between the two of us. But what I’ve found, at least the second years currently, who were taught by me, they were like, “No, we really liked the sheer amount of examples.” + +So I’m writing examples, and we’re having discussions, and people can ask questions, or we can get sidetracked, and that’s fine. I know where I want to get to. They don’t know where I want to get to. So if I want to change tack, that’s okay. I can follow the flow. And then the idea is that at the end of the lecture, I go away. And this is the time-consuming bit. I expand the NHS file to write about every bit, and add in the discussions that we had, and add in some additional clarification for things I felt people weren’t getting at the time, like doing a very manual evaluation of a function or something like that. Those notes are what I then upload.  + +So it’s like, during the lecture, I’m writing the notes, and then I’m expanding afterwards with the knowledge I’ve gained from just having taught the lecture. And some people don’t like that because they like to go into a lecture already knowing what’s about to happen. I’m like, “Fine.” But I think there are so many benefits the other way around. I’d like to find a hybrid, maybe where I give a small deck of slides, which gives some general ideas that I want to cover, and then I still do it live and make it up as I go along. But I think it’s effective. It’s different. And I think not everyone can do it. It’s very scary to rock up with a blank file and be like, “Magic is going to happen in the next two hours. I don’t know what it is yet.” So some people just need to be more prepared. They’re like, “No, I need to know what’s going to happen and how it’s all going to fall out.” And I’m like, “No, I embrace the chaos.” + +But that is my approach for teaching, and that goes for Haskell when I taught algorithms last year. I’m teaching Intro to Compilers this year. I’m going to do the same thing, as long as I can get away with it. If I was teaching a mathematical course, probably no, or something like, I don’t know, databases. I’m not going to be live-coding SQL statements the entire time. But for the courses that I teach, it’s a really effective strategy. + +*SF (0:29:40)*: And what is your favorite topic to teach in Haskell? + +*JW (0:29:44)*: It’s my favorite topic to teach in Haskell. Trees. + +*SF (0:29:47)*: Trees. + +*JW (0:29:47)*: Trees. But that’s because I’m a secret botanist, and I have too much fun with the trees lecture. It’s borderline problematic. I start trees by drawing a tree on the board, like the stereotypical tree that a child would draw. Very thick trunk, and then just a big bushy blob on top. And I’m like, I pointed out, “Is this a tree?” And they’re like, “Yeah, yeah, yeah, obviously, of course.” I’m like, “No.” Cross it out, draw it again, upside down, like leaves and all. And I’m like, “This is a tree.” And then I draw the sun at the bottom right-hand corner of the board to make that very clear that that is the correct way. And they all have great fun with this. + +And then you spend the whole lecture coming up with, due to Haskell’s limitation of unique names and constructors per data type and the fact that my notes compile, I have to think of all of the unique botanic names for various constructors. So my trees, and you’ve got bushes, and they’ve got nodes and tips and leaves and forks. And then you’ve got rose bushes. They’ve got vines and flowers and thorns. If that’s what you want, tips without nodes that are leaves that don’t have any values in them, those are thorns. Prickly, you want to avoid them. + +And whenever I get to talk about trees, it’s just a lot of fun. I remember I did the tree monad in one of my last lectures last year, and I got distracted, as I often do when trees are involved. And I started talking about how you can graft different kinds of trees onto each other. For sufficiently similar kinds of trees, you can have like a lemon and a lime tree, where some of the branches make limes and some of the branches make lemons. I was explaining that how the farmers do this in the orchards is that they use bind to attach a branch into the tree. And I think it was my favorite moment of the entire course. There’s someone in the front row who turns to their friend and said, “Wow, those farmers are clever.” And this just made the course for me. I was like, “This is hilarious.” And I did get a question in one of my minute papers, which are like the little feedback sheets: “Did you miss your true calling as a botanist?” I’m like, “Yes, yes, I did.”  + +So that is my favorite topic to lecture in Haskell, just full stop. It’s simple. Everyone loves it, because it comes after hard bits, and it feels like the course has slowed down for a bit. And it is just too much fun. It’s like I shouldn’t be allowed to teach trees. But yeah, that’s my favorite topic. + +*SF (0:32:11)*: How do you approach teaching the infamous monad? Do you use the burrito analogy, perhaps? + +*JW (0:32:16)*: No, all of the analogies are garbage. I mean, I talked a bit earlier about state monads, where it’s like, if I’m teaching a specific monad, I’m not going to talk about its implementation. When it comes to monads, applicatives, and functors, because I’m live coding it, right, I have to do all three, and it’s kind of annoying. Oh, well, because I think applicatives are the hardest to understand with a bunch, and they have to come before monads. But the functors everyone gets. That’s nice and easy. And then you get to applicatives. And the way I like to talk about applicatives, I talk about multiplicity. I talk about basically app being a multiplying operation, because if you take lists, right, you app a three-length list and a two-length list, you get a six-length list. So you can very much describe it as like it is doing multiplication. It’s like a Cartesian product, but different. And you can show that that works for a lot of different structures. Like maybes, it’s just zero and one with multiplication. Fine. And pure is the one. So it’s the smallest thing that contains that thing, and it doesn’t influence multiplication at all. + +And then when you get to monads, this whole analogy sort of collapses down. You have to change tack again, where you can either talk about it as like applicatives are about combining things, monads are about flattening things, if you’re thinking about on a structural level. And that works out quite nicely, because you can just say you’ve got generalization of concat. Then you kind of bring, like, well, yeah, but we don’t just use monads for structures. So then you have to be thinking about applicatives are a way of combining independent things; monads are a way of sequencing things. That’s how I have to go about it. It’s like I want you to take away it’s sequencing. Like no bells, no whistles; it’s just a way of sequencing things. And sometimes it takes a while for that to sink in, purely because people are like, “Is that it?” It’s like, yes, everyone makes it out to be really scary and all sorts of things, but it’s just sequencing. How do I put one thing after another? + +But it’s still challenging. It’s not easy by any means. But I think I like to talk about how, if I could rename them, what would I rename them to? And it wouldn’t be monad. Yeah, so I wouldn’t call it bind, because what intuition does that give you? FlatMap or concatMap is a way better name. It gives a better impression of what it does. And I would call functor “mappable” and applicative “combinable,” and just go with that abstraction. But yeah, I think the analogies just don’t work. You just need to get to the essence of what is the thing.  + +*SF (0:34:34)*: You’ve spoken a lot about the value of examples. Which example do you think is best to motivate functor applicative monad? + +*JW (0:34:42)*: I mean, functor, anything goes. Just throw them all. There’s so many of them. Applicative, there’s only one for applicative. It’s parsing, like you can’t do anything else. Monad, it’s difficult. I mean, everyone has a different one they like to cling to. Maybe it’s like a good opener. List is the easiest opener, because you can just connect it to list comprehensions, but you don’t really get a sense of what it means to be the list monad until later on. Some people like the writer monad, which is a bit rogue. I think monad is got to be maybe. I also like the tree monad, because it’s almost in a way quite visual, but it’s tricky. Who is the first monad is the hard question. I don’t really know. There’s a lot of different compelling reasons why you would pick one over the others. + +*FM (0:35:27)*: So in your course, you first start with Haskell, you move on to Kotlin, so object orientation, and then to C.  + +*JW (0:35:35)*: Yeah. + +*FM (0:35:35)*: That’s a hardcore imperative. How do you make the bridge to these things? I mean, I do it the other way. I mean, I don’t do the first one. But somehow I think it’s easier to just say that, okay, now you looked at a real wild language where everything is possible, and now let’s restrict it to just pure functions. How do you make the step between a pure language? And then what do you say now we have a store, and continue with that? There’s a bit of a gap there. How do you fill that? + +*JW (0:36:02)*: Yeah, I think it’s the challenging bit. When I was at Bristol, they teach C first as well. I always found that people struggled with state, which, for longtime programmers who started by finding it all very intuitive, that was always very surprising to me. It was like, “State? Oh, okay.” And that was fine. But I think that still holds water. So the fact that we get to that kind of last — I mean, in practice we don’t, because Kotlin is going to run you into state as well, but I like the progression. Why do I like the progression? Because if Haskell continued, if we had more Haskell and we were doing more concepts, where would it go next? I think it would go to the ST monad, and actually thinking about state in that sense. And the ST monad is really interesting, because it’s like you can have your state, but you must give it up. And this is like a rule, I think, I stick to even when I’m not programming in Haskell. So like, welcome to Kotlin. Now you have mutable data structures. I think if it were me teaching it, I’d be stressing, how do you use them responsibly? If I’m in a function and I need to build up a list, of course I’d use a mutable one, but I want to turn it into an immutable one at the end. The focus of OOP really is how do you build out large systems. And then you get to C, which is, as you say, super unrestricted. Anything goes in C. And you could start there, but I think you pick up bad habits.  + +So I think the value is having seen the other languages, which are more restrictive. I would hope that you understand why restrictions are good and that you can be disciplined. I think in practice it doesn’t quite work out like that, but it depends on the messaging. So the second years are currently doing a big operating systems project in C. One of the things I like to tell them is, like, imagine if C were an object-oriented language. Which bits would you see from which other bits? And they’re like, “Oh.” And suddenly now they know, like, I don’t have a way of defining “private,” but I can still create a convention. I can still be restrictive and be disciplined, and I can get some of the benefits of the structure that I’ve seen elsewhere.  + +So that’s kind of the message I would want to impart. It’s like, why were pure functions good? Because you could reason about them. Just because you move into a world which has side effects doesn’t mean you have to do side effects. You can still create the separation. You can still give up mutation. Now you’re in a world which doesn’t have encapsulation, and it doesn’t have objects and methods. That doesn’t mean you have to give up those things. Like, a C programmer can still program with pure functions. They don’t have the capacity to do fun and interesting things out of the box, but they can still be disciplined and benefit from the things that we try to teach them. I think that’s the lesson I would try and get them to take, as opposed to it being about unrestrictive, you can do whatever, figure it out. The thing I want you to understand when you’re doing C really is about manual memory management, memory layouts, and the low-level ideas of how stuff works. But I think by teaching it the way we do, we can better show how you program effectively in C, maybe.  + +*FM (0:38:48)*: Thank you. That makes sense. + +*JW (0:38:50)*: This is, of course, just my vision, as opposed to how it actually goes. But maybe someday I should talk to the C lecturer and be like, “Have you considered this?” + +Yeah, I don’t know. If I was teaching the entire course, that’s how it would be. + +*FM (0:39:00)*: What would you tell the board of other universities in which functional programming was not seen as the first experience to programming that students should be taking, which is the majority? + +*JW (0:39:13)*: What would I tell them? I would tell them about the joys of sandboxing. The sea is a dangerous place. Lots of dangerous things in the sea: sharks, all kinds of stuff. But before you go to the sea, you should probably learn how to be safe on the beach, right? And the beach is great. It’s got the sea there, but there’s also sand. But as a result of the water and the sand, there can be quicksand. There’s all kinds of traps. So maybe before we go to the beach, we should play in the sandpit, right? There, we can just get used to sand. + +Haskell is the sandpit, an OOP language is the beach, and C is the sea. What you want is for them to learn in an environment where they are restricted, because they are forced to think about ideas and how to do the most effective stuff first. I want them to be able to understand how to best write functions and reason about things before they start just throwing loops at problems or throwing mutation at problems. Throwing them in the sandpit means that they kind of have to just learn how to play in the sandpit, unless they bring their own jug of water. But where are they going to get that from? That’s the kind of thing. It’s like, do you want to carve out programmers that really understand those ideas and can apply them, and can write code that is maintainable, and understand the process by which that happens, and create an equalizer? Then I think you should be teaching Haskell first. Do I think Haskell is the best language in the world? No, I’m going to be honest. But is it the best one to start teaching on? I think yes. + +*SF (0:40:40)*: Would there be anything, though, that you would change about Haskell? + +*JW (0:40:44)*: I have a laundry list. So the obvious one, as a teacher, has got to be type classes. It’s the first thing that comes to mind because they get in the way all the time. But I would follow Simon Payne-Jones. I watched a fireside talk between Simon Peyton Jones and Martin Odersky. Martin Odersky is the maker of Scala. Simon Peyton Jones doesn’t need an introduction. And they were asked what they’d each want from the other’s language, which is very funny, because Martin Odersky said global type inference, and Simon Peyton Jones said subtyping. These are two incompatible features. So they are the thing that the other wants but knows they can’t have. + +Simon, you’re right. I want subtyping. Subtyping is so useful. I would happily give up global type inference to get subtyping because I guess for me, I’ve read a lot of compilers, right? And an identifier appears in so many places. Maybe here, there, left-hand side of an assignment, a general assignment that is, on the right-hand sides, in expressions, all over the place. I don’t want to have to write three different identifier constructors. Or what if I want to make it so that my plug to the Design Patterns for Parser Combinators paper? I want to make my AST for expressions represent the associativity of the operators. I need to have an expr type, and then a term type, and then a blah-blah type, and so on, and so on, and so on. But in order to make a term an expr, I need to have a wrapping constructor. And so your things are littered with these wrapping constructors in a similar sense, and it’s like, if you look at what’s possible in a language with subtyping, it just works.  + +Those things are naturally expressed, and you get all sorts of really interesting stuff. Covariance in a subtype language is the same as being a functor. It’s just that instead of saying, “I have an A to B function; I get F A goes to F B,” you’re like, “If I can upcast an A into a B, I can upcast an F A into an F B.” It’s like a free fmap, i.e., fmap identity is identity. That’s a really cool idea as well. Contravariant functors end up being contravariant types. And there’s just so much joy to be gained, even from functional programming, where you’ve got subtyping as a construct. If I had to create a new hypothetical Haskell that can’t exist, subtyping is what I’d pull in. And I just have to accept that it can’t exist, because global type inference is also useful. But yeah, from an educator perspective, those type classes, grumble, grumble. + +*SF (0:43:03)*: Awesome. Thank you so much for coming. + +*FM (0:43:05)*: Thanks, Jamie.  + +*JW (0:43:06)*: No, thank you for having me. + +*Narrator (0:43:08)*: The Haskell Interlude Podcast is a project of the Haskell Foundation, and it is made possible by the generous support of our sponsors, especially the Gold-level sponsors: Input Output, Juspay, and Mercury.