Effective Haskell Solving Real-World Problems with Strongly Typed Functional Programming

Emily Pillmore • Rebecca Skinner | Gotopia Bookclub Episode • February 2024

Rebecca Skinner, author of "Effective Haskell," discusses key topics from her book in an interview with Emily Pillmore. The conversation touches on teaching philosophy, the practical approach to learning Haskell, the use of GHC versus building a system, and the significance of laziness in Haskell. Skinner shares insights on Monad Transformer Library (MTL) choices and hints at future explorations. The interview concludes with a focus on Skinner's programming journey, emphasizing the joy of coding and the importance of embracing failure as a crucial part of the learning process in Haskell.

Share on:
linkedin facebook
Copied!

Transcript

Rebecca Skinner, author of "Effective Haskell," discusses key topics from her book in an interview with Emily Pillmore. The conversation touches on teaching philosophy, the practical approach to learning Haskell, the use of GHC versus building a system, and the significance of laziness in Haskell. Skinner shares insights on Monad Transformer Library (MTL) choices and hints at future explorations. The interview concludes with a focus on Skinner's programming journey, emphasizing the joy of coding and the importance of embracing failure as a crucial part of the learning process in Haskell.

Overview of "Effective Haskell"

Emily Pillmore: Hi. My name is Emily Pillmore. I'm here with Rebecca Skinner, who wrote a new Haskell book. Do you mind introducing yourself, Rebecca?

Rebecca Skinner:. I'm Rebecca Skinner. I wrote a book called "Effective Haskell." I'm also a lead engineer at Mercury, where I use Haskell every day.

Emily Pillmore: All right. Thank you. For those of you who don't know, my name is Emily Pillmore. I do a lot of stuff in Haskell. And I'm just here interviewing my friend Rebecca, who came out with a fancy new book. And I'm fairly happy to see this book in the ecosystem because it does cover some very interesting parts of Haskell that I haven't seen up to date in the past 10, or 15 years, even. Do you wanna get right into talking about the book, or is there anything you wanna talk about or plug beforehand?

Rebecca Skinner: Let's do it. Let's jump right into the book.

Emily Pillmore: All right. Cool. So, the book is titled "Effective Haskell." Who is this book for?

Rebecca Skinner: When I was writing the book, the archetype of reader that I had in mind was somebody that is an experienced developer, maybe not a super senior developer, but somebody that's been writing code for a couple of years, probably professionally, but maybe, you know, as, like, a regular hobbyist, working on open source. Somebody who's never used a functional programming language, maybe doesn't know a lot about Haskell, maybe has never even used a statically typed language before, but is interested in picking up Haskell because they really wanna build things with it, right? They're not learning it entirely for the intellectual exercise, although I hope that's part of it, but because they wanna get things done.

Recommended talk: Elm in Action • Richard Feldman & Thomas Anagrius • GOTO 2020

Emily Pillmore: Nice. So, keeping it simple, and keeping it project-driven, I suppose, and then focusing on how to just build stuff.

Rebecca Skinner: Right.

Emily Pillmore: Good summary? Okay. Great. Okay. So, within that, how does that differ from other books that we've had in the ecosystem?

Rebecca Skinner: I think that when I look at all of the material that has historically been out there for Haskell, there's a lot of stuff that I would say is high-quality material, but it tends to fall into a couple of categories. Some of it is, I think, well-written material that's out of date, right? It was written quite a while ago. It maybe hasn't kept up with the changing way that we write Haskell in the real world. And then there are materials that I think are aimed at people that are interested in learning Haskell from a more, like, theoretical standpoint, or an academic standpoint. And, you know, I think that many of those materials are great, right? And they're a really good way for people that learn that way and have that motivation, but they're not for everyone. And I wanted to write the book that I thought would appeal to, you know, people like me, maybe people that are going into Haskell without a really strong math background to start with, but, you know, want to learn the language, and feel like maybe they can learn this other stuff through Haskell, rather than going the other way around.

Emily Pillmore: Right. So, I guess you could say bridging the gap a little bit between beginner and what it would take to maybe read those more complicated books, with more theoretical topics.

Rebecca Skinner: Right.

Emily Pillmore: I mean, that's something that Haskell's needed for a long time. It's often the major complaint, I think, from people. So, it sounds like we've got some good material here. I'm really happy to see this if you can't tell. Okay. That explains a lot about what you cover in the book. Do you wanna explain a little bit about what you cover more in-depth, and then we can talk about more specific topics?

Rebecca Skinner: All right. Well, I guess a good starting place is actually where I think "Effective Haskell" differs from some of the other materials. Not just books, but other, like, tutorials and materials that somebody might come across. And one of those is, you know, I start people off very early learning about some specific, like, extensions that GHC has added, and treating those as a core part of the way we write Haskell. And part of the motivation there is thinking about somebody that's gonna pick up Haskell in a real project. They may be going to start using Haskell at work. They're going to run into a lot of things that you might not come across if you're, like, starting with, like, Haskell '90 or Haskell 2010, right? But these are, like, a real part of what people need to know if they're gonna be effective. The other difference...

Emily Pillmore: Things like locally-scoped type variables, and bang patterns and that kind of thing.

Rebecca Skinner: Deriving via is the one that people are most surprised that I introduced so early on. And I would say I don't see that used incredibly often in the production Haskell that I've worked in, but it's one of those newer things that I think has high utility, and it does come up. And it just fits so naturally if you're willing to sort of, like, accept the fact that we're working in GHC's very specific dialect of Haskell, right?

Teaching Haskell: Philosophy and Practical Choices

GHC vs Building a System

Emily Pillmore: I noticed very early on that you also start people on not using a build system, but rather calling GHC itself to run programs. Could you talk a little bit more about that choice?

Rebecca Skinner: There's both, like, a philosophical and a practical part of that. The philosophical part of it is, I think that people ought to understand what their tools are doing, because tools are things that, like, help us accomplish our goals, right? But ultimately, like, no tool always solves all of our problems. And understanding what's going on, I think, sets us up better to work through anything that comes up, right? I'm just, like, really a fan of starting from the bottom and going up. More practically, though, I wanted to avoid overloading people with too much information. Haskell has a reputation for being hard to learn, and I think that a lot of that comes not from any particular concept being too hard for people, but the rate at which they come up, right? So, I was trying to be mindful that we're gonna, like, step through, and teach one or two things at a time. And so, by the time that we do get to using Cabal, and building larger projects, at least the core language isn't so scary, and so it's not such a big leap to add this one more thing.

Emily Pillmore: That makes a lot of sense. I think it's often taken for granted that, you know, whenever you get started writing Haskell, you're kind of just thrown into the weeds with things like purity and referential transparency and kind of expected to suss your way through, it in a very principled and almost academic sense. But, you know, it's often most people's first interaction with those words, let alone those concepts, let alone those experiences, because I think it's the only language that I've used that's usable in industry, that uses these concepts to any sort of effective degree. So, that's a really good point. I'm glad you did that. So, I guess that explains other choices in here, like waiting so long to introduce things like monads or MTL.

Rebecca Skinner: I think that a really common challenge that I see people learning Haskell running into is this, like, "Trust me, this will make sense later." We tend to do that, right? Like, there's so many Haskell tutorials that tell people, like, okay, we're gonna use this do notation here, and these, like, funny arrows. And don't worry about it, right? Like, you'll understand it later. Just cargo cult it. And I feel like that makes people uncomfortable, even if they don't logically realize they're uncomfortable, right? It makes it feel like you're standing in quicksand. And this kind of plays into another pathological case that I see when people are learning, really, anything in programming, but Haskell in particular, and that's, like, I'll pick on monads, right? Like, one of two things happens when somebody first encounters monads. Either they say, "That's too complicated," and they, like, grab their ball and go home. Or they say, "This is the divine truth of how programming should work. I'm going to use these for everything," right? I'm like, neither of these is the right answer.

Emily Pillmore: Yeah, it's only the two camps.

Rebecca Skinner: Right.

Emily Pillmore: That's true. That's true.

Rebecca Skinner: I wanted to help people build the intuition that this is neither too complicated for you to understand, nor is it, like, this thing that you should be trying to use everywhere. It's, like, a tool, and it solves a particular problem, and I'm gonna help you develop an intuition for what that problem is so that you can see the bounds around where this is a helpful solution and where it isn't.

Emily Pillmore: That makes a lot of sense. I think we're currently, benchmarking, at this current day, we're entering into the yearly discussion around monads again, in various social media circles, and going, is this worth it? Is it worth the trouble? I think focusing on the problems is kind of the answer, right? It solves a lot of problems that you see in, like, mathematics, as well as in programming, but in particular, mathematics, where it's very difficult to cargo-cult the abstractions before you understand the problems that they were built to solve. And oftentimes, like, you know, as somebody who got their start in math, I've had to go back and read history, more than math, to try and figure out exactly what I'm looking at, if someone introduces a particular syntax or abstraction. And I think the same thing is probably true of Haskell, right? You have to know what we're trying to solve.

Rebecca Skinner: And my experience is true. I don't think it's unique to Haskell, even if it has a particularly powerful manifestation in Haskell, right? I think you see the same thing when somebody first learns about design patterns, and then goes throughout their entire code base looking for opportunities to write a singleton, right? Sort of the same energy.

Laziness in Haskell

Emily Pillmore: It happened with free monads, I think, a while back, and then it happened with, what, effect systems and everything. It cycles in two to three-year cycles. So, it's been really interesting to watch. It happens in other programming languages too, where people... I remember reading the giant, thick, 1200-page Perl book by, I think it was Conway, and they introduced, you know, dollar and dollar-dollar, for references and variables. And it was like, what is this? I had no understanding of what the domain model is, like, what a reference is, until later when they explained the rudiments between the two. But then, you know, I've had to have this thing in my head for 10, 15 pages, while picking out, you know, various facts about how to use them. It is just overhead. But to that end, I noticed that you cover laziness very early on. Could you explain that approach?

Recommended talk: Domain Storytelling • Stefan Hofer, Henning Schwentner & Avraham Poupko • GOTO 2022

Rebecca Skinner: I think there's, again, this, like, the duality between the practical needs of just teaching people things that they need to know early on, so that they're not left for too long just with me saying, "Trust me," right? And, you know, Haskell is a lazy language. And I think that if you don't address that head-on, people just really don't quite appreciate how that changes the way that we think about writing programs. And they run into, like, problems that are hard to diagnose if you're just not used to a lazy language. It's surprising what things take people off guard, right? Like, why did my program let me assign this infinite list, but then it crashed when I tried to, like, find the last element of it? And then, the other side of this is it also, I think, is a really good way of motivating monads, for example, right? So, the canonical example of monads is I/O. And I'm sure somebody out there is gonna, like, tell me that I'm wrong here, right? But if we roll with it...

Emily Pillmore: Somebody. I know the person. I know exactly one.

Rebecca Skinner: If we roll with it, right? Like, a really good way of helping people come to terms with, like, monadic I/O is to go through this exercise of saying, like, okay, let's pretend that we don't have this, but we're working in a lazy language. How else are we going to have a program that makes any sense at all? How are we gonna be able to read a file and then write a file if we have no idea of ordering? And so, I think that that was another really strong motivator for introducing it early.

Emily Pillmore: It's a good point. I mean, that's often one of the things that beginners cite as sort of the most confusing. Is there any way that you demystified the laziness, to some degree, or in some way that was different than previous tutorials, that sets it apart?

Rebecca Skinner: I think that a big part of it is just being very explicit, right? There are these sections of the book where, much to the chagrin of anybody who's concerned about page counts in their books, I dedicate quite a few pages to, like, manually unrolling the way that evaluation happens in Haskell. And I think just showing people where there's a thunk, and where a thunk becomes an expression, and, like, where the next thunk is, helps people develop an intuition, and realize that it's, like, not that scary, in a lot of ways. I think it is very natural to the way that most people think about running code, right? Like, when we think about the way our programs evaluate, even in a strict language, right, we tend to take the mental shortcut of saying, like, "Well, and then we call this function," right? Which is kind of a thunk. And then we have to go through the, like, burden of actually unpacking that strictly, in a strict language. And so, helping people break out of that habit, and realize, like, actually the language is letting you think about this in the way that I think is most natural for most people, and calling it out, seems to have worked well.

Emily Pillmore: I have heard that a lot of people think lazy, but they expect strictness, in a lot of ways. There's an interesting debate that goes on about whether or not laziness is worth it. And I happen to be "yes" on that. But it's very interesting to see that, well, a lot of people are, or a lot of books and a lot of resources haven't gone into as much depth, I think, as yours. The last one that I remember is maybe "Parallel and Concurrent Haskell" by Marlow, which was, like, 2008. But he only really goes into, like, sprint in GHCi, and says, "Okay, you know, here's kind of how it works," but nothing nearly as explicit or as illuminating. So, I was fairly happy to see that.

Rebecca Skinner: I'll be honest, some of it's just, like, me geeking out too, right? I'm like, this is cool, and I just want people to appreciate it.

Emily Pillmore: You can tell. For the diagrams, where you show where things are thunked, and the flow, is novel and unique. I'm pretty stoked that somebody is explaining it like this. Because I shouldn't have to go and say, you know, to somebody who wants to understand laziness, "Here, read," you know, "'Purely Functional Data Structures,' and also, 'Parallel and Concurrent Haskell,' and then read the Wiki article on laziness." It's good to have it in one place, is what I'm saying.

Rebecca Skinner: If the people who read my book come out the other end of it and no longer think that the first step to making an efficient program is to add strict data as an annotation in all of their modules, then I think I've done one of the things I set out to do.

Emily Pillmore: I think you got that in your book. Thank you. So, at least we do that. I mean, that's a win right there, right? Okay. Skipping ahead a little bit in the book, can you speak more to why you focused on MTL as the main source of effects in your program structures?

A Practical Perspective on MTL and Future Explorations

Emily Pillmore: Skipping ahead a little bit in the book, can you speak more to why you focused on MTL as the main source of effects in your program structures?

RebeccaSkinner: All right. We can talk about theoretical benefits to other ways of representing effects in code, but I think, in practice, if you go looking at any piece of Haskell code, especially in my experience in the industry, but even open-source applications, right, it's just far and away the majority case. And I think that somebody going into a codebase that maybe is using effect system, or even, like, isn't using a tagless final encoding, and is just using, like, straight-up transformers. You're gonna go into that better prepared, I think, having gone through an MTL-style experience, and, there isn't the page count to cover every way that we might do it. So, I tried to just give people what I thought was gonna prepare them best for the most code that they would run into.

Emily Pillmore: I guess that's a good reason for a follow-up book if you haven't already started.

Rebecca Skinner: I haven't.

Emily Pillmore: "Effective Haskell 2." Be like what...

Rebecca Skinner: "Effectiver Haskell."

Emily Pillmore: "More Effective Haskell." Yeah. Or, "Haskell, The Good Parts," you know, would be, like, this big. DWARF symbol debugging. I suppose more interesting effect systems. That could be fun. All right, though. Well, we're about halfway through. Do you want to talk about yourself?

Rebecca Skinner: Sure. I think that I am less interesting than my book, but I'll give a little bit of background. So, you know, I live in St. Louis, which is only interesting because we used to have the Strange Loop conference. This was the last year for it. We had ICFP once. So, that is, at least to someone like me, the hallmark of the city.

Emily Pillmore: That was the first ICFP I ever went to, by the way, is that one.

Rebecca Skinner: Same. I've been using Haskell since 2008 or so, and I've been trying to be involved in the Haskell community since maybe 2016. So, a very long period as one of those, like, many silent people out there, just, like, using Haskell, and not arguing about monads and effects systems on the internet.

Recommended talk: Functional Programming in 40 Minutes • Russ Olsen • GOTO 2018

From Graphing Calculators to Type-Level Adventures: A Journey through Haskell Programming

Emily Pillmore: How long have you been programming, period?

Rebecca Skinner: All right. I mean, I started programming in, like, middle school. I got a graphing calculator that had, like, TI-BASIC. And I had no idea that I was programming. I just realized I could cheat on my math homework by writing all the steps out, like, in the calculator. And I took a programming class in my sophomore year of high school. I ended up taking AP programming my sophomore year of high school, and, like, just couldn't ever imagine wanting to do anything else. I thought, before that, I would be either a fashion designer or an archeologist. And, you know, I took one C++ class, and that was the end of any other aspirations.

Emily Pillmore: Oh, man. We could have had a designer Rebecca Skinner.

Rebecca Skinner: I started my career writing C++, really working in, you know, sort of, like, quasi-embedded systems, and appliances, and got interested in functional programming, yeah, around 2007, 2008, and it just got out of hand from there.

Emily Pillmore: One of the big topics that I was excited to see in the book was the fact that you talk about micro-benchmarking and, sort of, memory layouts, in various capacities, using things like vectors, mutable vectors, and non-mutable vectors. Can you talk more about that decision, and what you hope people take away?

Rebecca Skinner: I think that a big part of my motivation was helping people internalize the fact that even though we're dealing with a very high-level language, right? That is unabashedly very far away from the architecture of the machine that we're running it on, that Haskell can be a very performant language. It has a lot of flexibility to run well in scenarios where we need good memory characteristics, we need good runtime characteristics. I think that, especially with people who jump into Haskell and don't have a lot of experience with, like, laziness, right, there's a lot of opportunity for space leaks, and people kind of look and say, like, oh, Haskell has, like, terrible memory performance, or oh, Haskell is slow. And I wanted to point out, like, look, if you're running something that can run at, say, the speed of, like, the JVM, you can probably write something in Haskell that has acceptable performance. And so, I wanted to highlight that, and I also wanted to show people sort of a tour of really common techniques that at least I use, that I go to first when I'm thinking about optimizing.

The other thing I wanted to do was I wanted to show that not every optimization is about removing the things that Haskell does well. So, if somebody's going through the optimization chapter, what they're gonna see is, actually, like, by far, the biggest performance benefit that we get is, like, using more laziness, right? We're, like, using laziness to memorize things. And then, you know, as we begin incrementally doing more and more micro-optimizations, we see where the sort of, like, high-level, very abstract Haskell plays nicely with the lower-level concerns, you know. I wanted to show off ST because I wanted to show how, you know, the types, and the type system, actually gives us concrete benefits to performance, right? And I think that's interesting, because people, like, for myself, right, coming from a C and C ++ background, you know, I wouldn't have thought about the ways that leveraging the type system would let us do optimizations that we couldn't otherwise do. And then, some of it's just for fun.

Emily Pillmore: Types can get us a lot of the way there, in terms of establishing the invariants we need to execute certain kinds of loops, with certain kinds of guarantees that, yeah, a lot of the times we take for assumption, in, like, C-style programs, or in C++, or Java. I have noticed this in my coding lately as well, where, you know, I'm more structured when I can apply certain optimizations, as opposed to really using the type system to nail down a domain, you know, as closely as possible. What I'm looking for is, like, oh, man, where can I, you know, get away with not error-checking in a loop, for example? Yeah. So, I guess there's a little bit of, like, there's a power-to-weight kind of ratio that you wanna think about, with types and stuff. And I think the benchmarking chapter kind of illustrates it well, where, you know, we don't always have to drop down into mutable vectors to talk about the most performant thing in the world. Sometimes we can just do the right thing with vectors, and let the compiler do the rest of the work..

Rebecca Skinner: Right. And sometimes we import the nasty, unsafe parts of the libraries that we really shouldn't be looking at.

Emily Pillmore: Every time I've used things like, you know, unsafeAccursedUnutterable IO, or, I'm sorry, accursedUnutterable IO, I've always come back, like, within a year, and been like, "Do I need this? Did I need this?" It's fun to play with, but, like, I probably don't need to be that unsafe, right? It's been very interesting.

Rebecca Skinner: One of my favorite little Easter eggs is, that I wrote an entire chapter, and finished a complete chapter on unsafePerformIO for the book, which I ended up having to cut because the book was just too long.

I didn't feel like handing people that particular very pointy object if I had to pull something out. So...

Emily Pillmore: That's probably fair. However, please post it. I would love to read it.

Rebecca Skinner: I do plan on making it available online as soon as I find some time to clean it up. Because I found that it was a really good opportunity to talk about, like, let lifting, and the way that the compiler, you know, reorders things, and why unsafe is safe, but only if you understand exactly how your program is gonna be transformed. So...

Emily Pillmore: I suppose you really have to track your reads and your writes at that point, and just hope you understand. That's the big question, is, like, I hope I understand my program model well enough that it's not gonna cause, like, heap corruption. All right. So, at the end of the book, you know, we spend all this time in benchmark, lower-level memory layout land, and we talk about concrete projects, and then we talk about, you know, various abstractions you can apply. 

Emily Pillmore: But there is also a type-level programming chapter. Do you wanna talk more about why that was included, and what that gets us?

Rebecca Skinner: Yeah. I think this is, to some extent, the most surprising chapter for a lot of people, especially people who have been using Haskell in industry, because I find that people frequently say, like, "Well, do you ever really use that in production?" And I think this chapter is me really talking to people who have been using Haskell for a while, maybe the people that might be using the book to teach Haskell to, say, like, new hires on their team, and persuade them that there is a space for this, and there's a space for these techniques that fit in well with a very pragmatic style of writing code. I think that there is a real advantage to Haskell in the way that it gives us such a broad spectrum of the ways that we wanna interact with the abstractions that we can build, right?

We can write, like, the Haskell '98 style, like, very straightforward functional code. We can write code that uses, like, mutable vectors and unboxed types, and see with different syntax almost, right? And then we also can write type-level code that fits in, I think, well with these other types of abstractions. And so, you know, this goes back to thinking a lot about the way that we can use the type system to enforce invariants, and then have the implementation of those invariants be somewhere on that spectrum, of very performant to, like, very easy to work with. And so, I think that type-level programming, the way I think of it is, you know, we're writing an application whose user is the programmer that is working with our code, and we're just giving them a toolbox to work with these other more concrete abstractions more easily.

Emily Pillmore: That's a good way of talking about it. I suppose a lot of the time, we talk about writing for users, but in a sense, other programmers can be users of our code. It's good to keep in mind. Do you have any other bits of wisdom for people who want to dabble in the type level, or dabble in the lower level, that you'd like to talk about?

Rebecca Skinner: I think, honestly, in both cases, right, the real answer is, like, just do it. Go have fun. Fail.

Recommended talk: Calling Functions Across Languages • Richard Feldman • GOTO 2023

Emily Pillmore: Benchmark it.

Rebecca Skinner: You can learn a lot from doing, you know? Nobody gets good at writing type-level code without writing some horrendous type-level code. Nobody gets good at writing low-level high-performance code without, like, a runtime error here and there, without a seg fault, right? 

Emily Pillmore: Yeah, definitely been there.

Rebecca Skinner: Make space for yourself to fail, and that's where the learning happens.

Emily Pillmore: Having fun with it is a good one. I think, you know, while we're here in the interview, one of the things that has helped me lately, in the past, you know, two years, has been a library called eventlog2html, which has allowed me to, like, do data visualizations on various, like, heap profiles, for when I'm benchmarking stuff. And you can do it with, like, really small executables, and you can gain so much knowledge so quickly about what your program is doing. Especially just going through the GHC options, and be like, oh, I should toggle, like, -hy instead of, like, you know, like, just -l and -au or something. It's really fun.

Rebecca Skinner: Yeah. Reading the manual is surprisingly effective, right? Like, you know people should still read "Effective Haskell," but you can get pretty far just reading the manual.

Emily Pillmore: I mean, you're not gonna understand the thunks, you know as you get in "Effective Haskell"

Learning Haskell: Embracing Failure & the Joy of Coding

Rebecca Skinner: I think one of the patterns that you see in the book, a lot, is this pattern of walking through something and letting it fail, and saying, like, "Oh, this went wrong," right? "We tried to do this, and it didn't work. Why did that happen? Let's take a step back, think about what's going on, and then try to figure out how we can prevent that." And I hope that somebody coming away from the book, like, really retains that approach to writing code, and does get that sense of curiosity, that says, like, "Oh, I'm gonna go look for ways that I can understand what went wrong," and, rather than being discouraged, look at this as an opportunity to figure out, like, what they can do next, and how they can build better.

Emily Pillmore: I love that. We're very denotational in Haskell. We're like, specify first and then write the thing, and if it's not done the first time, that you didn't specify it well enough. But that's kind of counterintuitive, and kind of antithetical to the whole ethos of programming, as far as I understand it, which is, that there are tools for a reason. You wanna have fun with it. If you wanna try stuff, make the rocks think.

Rebecca Skinner: Right.

Emily Pillmore: Okay. So, now that you've finished up with the book, what else are you doing?

Rebecca Skinner: Well, there's the whole second part of, now I've written a book, I have to finish writing up solutions for all of the exercises. I'm just about ready to publish, by the time this video is up, most of those should be available at the time that we're doing this interview. I have the first seven chapters' worth of solutions available. There's, you know, errata, and no matter how much you try to not leave out words and use bad grammar in the book, the gremlins will get in there and make some of it appear. 

After that, I have quite a few projects that I've just really had on the back burner, and I don't know exactly which one I'm gonna pick up, but I'm really into this idea now of writing a game in Haskell, that teaches people how to program. So, no promises, but I'm hoping I'll make some time for that.

Emily Pillmore: I've not seen a game in Haskell before. I'll be interested to look out for that, see how you do it.

Rebecca Skinner: There's a pretty small but active community of people that are writing games in Haskell, so...

Emily Pillmore: Interesting. What kind of games? Like, three-dimensional? Like, 2D, like, roguelike type things?

Rebecca Skinner: A lot of, like, 2D and roguelike. Those seem to be popular, right? They're easy for, like, the one person to do. I think you have a lot of people like me who have much grander ideas than they have the time or capacity to make, like, all of the art and assets that go into a game. So...

Emily Pillmore: Well, shoot, like, an RPG maker written in Haskell, would be pretty cool. And probably not the worst-size project in the world.

Rebecca Skinner: We'll see if this ever takes off, but I wanna write a Metroidvania, and you get, instead of, like, a suit or gun upgrades, you get little fragments of a programming language, and you use that to augment your abilities, using the things that you've picked up. So...

Emily Pillmore: New extensions and functions and stuff.

Rebecca Skinner: Exactly.

Emily Pillmore: Like extended preludes.

Rebecca Skinner: Yes.

Emily Pillmore: That's a pretty cool idea. It'd be fun to teach.

What are your favorite libraries? I don't know. I'm running out of ideas here. I think we talked about a lot of the stuff 

Rebecca Skinner: I'm gonna throw out, like, a hot take here, right?

Emily Pillmore: Okay.

Rebecca Skinner: I'm gonna say prelude, or base, right? And everybody's like, "Oh, no. We should be using, like, this alternative..."

Emily Pillmore: How dare you.

Rebecca Skinner: We should be using these, like, alternative preludes, and, like, based as partial functions. It's terrible. Like, you should feel bad about yourself. I think, yeah, base doesn't have as many batteries built in as some of the other languages that you might use. But I feel like it's a really good balance between giving you some good abstractions and also being, like, eh, sometimes, like, partial head, you know what? Like, it's fine. I trust you. I feel like it has this sense of practicality, that sometimes people need to be reminded of.

Emily Pillmore: I suppose, in the discussions, there's a lot of talk about perhaps, like, a strawman beginner who might shoot themselves in the foot with things like head. That has never really like rung as true for me, because usually, I like that. Like, if I'm ever calling head on an empty list, I messed up. Like, I need to figure out where that bug is, and I probably don't have the correct code there, and I probably wanna fix that. It's a very, like, training-wheels, incurious way to think about beginners. I don't know. Maybe, like, some people are just fundamentally a little bit, you know, built differently, but, like, when I was a beginner, I liked it when my programs failed, and maybe that's just the masochist in me. Like, you know, I got started with Perl, where everything was failing all the time until it didn't. It was nice. Like, it was a good hunt, like, a good thing to do in your spare time. Like, "Oh, man, how do I get this program to work? It's not working."

Rebecca Skinner: And I think that, as a beginner, you expect things to go wrong, right? You know that you're learning, and you know that things are gonna fail sometimes, but you also wanna see success. And I think that this, like, having you have to deal with wrapping and unwrapping non-empty lists, or, like, looking into a, maybe every time you take the head of a list, right, like, maybe, in a real production environment, you'd want that. But I think it just, like, drags down. It's, like, burdensome for people that just want to, like, get in there, get some code out, learn, have fun. And that's really... You know, for me, a lot of Haskell is about having fun, right? Like, I love the language. I have fun with it. I still just really enjoy all of the time that I get to spend writing code in Haskell. And, you know, I wanna bring that to other people, and I think that, honestly, the design of, like, base and prelude strikes a good balance there for people that just wanna, like, get in there and have fun and start writing some code.

Emily Pillmore: That's fair. That's a beginner take I tend to agree with, then.

Rebecca Skinner: I eagerly await the many people yelling at me that I'm, like, completely wrong and unfit to ever, like, teach anyone Haskell here.

Emily Pillmore: But you wrote a book. You could just point to your book. Like, where's your book?

Rebecca Skinner: Yes.

Emily Pillmore Although some of them have written books, so you'll have to be prepared. Yeah. No, I like that hacker mindset. That's kind of what I would call that. It's like poking things to see what breaks, and then adapting accordingly. Like, you know, as a former beginner, if I used head a lot, and I don't use head anymore, because I've learned that it's not a good thing to use. But I had to learn that somehow, right?

Rebecca Skinner: I still do. Not in, like, code that I care if it fails, but there are plenty of times that I'm like, you know what? I just, like, I need this thing. And if it crashes, like, I don't care. The only person I'm hurting is, like, myself for the next 10 minutes before I never pick this thing up again. And that's fine.

Emily Pillmore: My barometer for maturity in my programs is now I just pattern-match more often because I can fit a comment in there about what it's supposed to be doing. That's a little bit nicer than... I don't know. That's just personal preference. But yeah, I think we're at the time. It was great talking to you, Rebecca, and congratulations on your book again. And it was wonderful talking with you for the past hour.

Rebecca Skinner: Thanks so much. I had fun.