*intro music* Welcome to Elixir Outlaws: The hallway track of the Elixir community ANNA: How are you both doing? AMOS: I’m doing fantastic! I’ve been writing way too many property tests over the past couple days. We’re implementing an FTP server in Elixir, so I’m utilizing PropCheck and Erlang’s FTP and inets, and generating, basically a big test suite that exercises FTP fully, so, when it’s done, anyone who wants to write their own FTP server can. ANNA: That is so cool! CHRIS: How have you found property testing to be so far with that? AMOS: So, it’s worked out really well. Most of the property testing I’ve done has been small and at the functional level, and I keep trying to do full system level, and when I saw the FTP thing, I thought, ‘wow, that’d be simple to do full system and to really reason through. One of the things that got me with Prop Check is the preconditions not having the actual return values… CHRIS: Ahh, yes! Symbolic call hell. AMOS: Yeah, so I was like trying to check that if the return was okay to have on precondition and then errored to have another precondition, and then I realised, I can’t. CHRIS: So you’re using Prop Check and you’re using the StateM stuff for all this? AMOS: Yeah. And it’s working pretty well. I have found some issues - I’m working with Ranch, right, and some things aren’t real time or they’re call backs, like I get an okay back. But then if I check the state of the system, it may not quite be to where I expect it to be, just because of timing. So, that’s one thing, but I’ve run into that befor when doing full system checks on a website. Right, so when you click on something on a website, you - you can’t just assert it right away - that it changed - because it might take a second. CHRIS: Right, yeah, it’s not quite deterministic enough. There’s time involved. AMOS: Right, yeah, well, unless your webserver is written in Phoenix, then it takes seconds. Microseconds. CHRIS: Two million users. A single box. AMOS: On a Raspberry Pi. CHRIS: On a Raspberry Pi…in my closet. ANNA: Sounds done… What’s been the most - what was the biggest learning, given that you haven’t quite done this before? AMOS: The symbolic responses. CHRIS: Do you wanna explain what those are, in case people haven’t used StateM and don’t know what symbolic calls mean? AMOS: Sure… So, when the tests start up, they generate a list of commands, and that list of commands looks like an MFA - Module Function Arguments - and then, as it’s generating that list of commands, ti has to generate state representation changes, so what your test thinks the system kinda looks like, so that your test can later use that to assert on. So as it generates these, you also - it could generate some command orders that don’t make sense like, ‘connect’, ‘disconnect’, ‘disconnect’. Well, I’m already disconnected. So you want to be able to say, ‘well that’s not really a valid command set’. But as it’s generating these, uh, like, when you connect, it might give you a PID back, and you might need to use that PID in the next command. But since it’s not actually running on the command - this is probably very Proper or StateM dependant, but it sends back Var:1, so like a map. And... for like the first command’s response. The second command has Var:2 for it’s response, the third command is Var:3… So you can use that Var:1, Var:2, Var:3 later. You don’t really have to keep track of which variable it is if you just - like, I treated it like a PID in my case, because it was returning a PID. But! You can’t do it in your preconditions where you’re trying to eliminate what the commands are that aren’t valid. I can’t say ‘this is a PID’, because it’s not. Until it runs a second time and when it actually has the answers and is checking, and then you can. So I was getting a failure that said ‘precondition false’. And I was like ‘preconditions should be used as failures. Those are for making sure that my command sequence is right. And then I found out I was trying to check for things to be PIDs and all kinds of crazy stuff. CHRIS: Right, you you’re experiencing the problem where you actually need to care about the thing your getting back, and - yeah, you just can’t do it. And the reason that I would explain, too, is when it initially creates the command sequence, it uses your idealised model to do that. You know, when a part of a model is ‘when I’m in this state, I can generate these sets, or something in this list of symbolic calls that need to get executed later on. And those are guaranteed to sort of be in the correct order because they’re based on your state machine - or, they’re guaranteed as long as your state machine is written correctly. AMOS: Guaranteed to match your state machine, whether it’s right or wrong. CHRIS: Yeah, yeah, exactly. So, but once you have generated that sequence of commands and that sequence of commands has found a fault - the way it shrinks in StateM, is it starts removing them blindly. It just starts removing them from the sequence. And at that point, all bets are off that your sequence is in any sort of meaningful order anymore, and that’s why you need the preconditions. And, the typical way that you get around the symbolic variable problem is - because, like you said, it’s not actually being run yet and you don’t have values yet, and all it can do is return a symbolic variable. The way you get around that is by creating a new symbolic call, with the symbolic variable, as part of the argument. Does that make sense? So if you want to use a PID, you could have a function - or if you want to check that the thing you got returned in the precondition is a certain way, then what you can do is have a function in your test module that is PID, or, you could have like, an ‘is foo’. It could accept an argument, and then when you want to call it in your precondition, you call it with a symbolic call. So you say like, ‘call__module__’ - so the module you’re in - and then pass the symbolic variable as the argument. Does that make sense? … This is impossible to explain with just words. AMOS: I’m getting it because I’ve been in this now. I didn’t think about that. CHRIS: Well that’s because it isn’t - it’s not clear, while you’re doing that. This is why this stuff is so hard. And I think it’s why a lot of people haven’t dove into this stuff, because it is complicated to understand how you interact with all these variables, and what is - this bites everybody. Everyone who starts doing preconditions immediately is like ‘why can’t I actually use the return it gave me?’ Well, that’s because it doesn’t exist yet. And that’s the way around it though - is you continue just to use symbolic calls, and then they get execute correctly when you actually run against the real model, but during the generation phase, they don’t. AMOS: And I’ll put a link to the FTP test that I’m working on so you can get a look, but I’m not doing any of that what he’s talking about where I’m checking that it’s a PID in the precondition now. I just decided that if it’s coming up as an error in the postcondition, I should just fail. Unless later I have something that is a failed connection that is supposed to come back as an error. Then I’ll have to worry about what he’s saying. And, you said ‘is PID exists’ - I think, ‘will be PID’ would be a good… ANNA: Oh, yeah, that would make sense. CHRIS: Right, yeah, yeah, or like ‘maybe is a PID’. Or ‘maybe is an error’. AMOS: Oh, then it gets confusing with ‘maybe Monad’. CHRIS: We don’t wanna talk about that. ANNA: No, we don’t. Well, are there any - y’all have done more property testing than I have - are there any - and there’s complexity in it, I agree - have you found… I think part of it is just getting into it and trying to understand, but for folks who want to start, what - from y’all’s experience, what documentation would you recommend to help with understanding? CHRIS: Oh, it’s time for our weekly Fred review! AMOS: Well, instead of saying Fred, I’m just gonna go straight to the source, and if you really like white papers in academics, you could read John Hughes and Curt something, wrote the quick check paper. But that’s not gonna teach you the Erlang side or the Elixir stuff, so then, Chris, do wanna do the honors? CHRIS: Well, I think it’s come up on every episode we’ve done so far, but Proper Testing is really really good. That’s a great place to get started with this. You can also read through the StateM docs that are a part of Proper’s docs. So if you’re using PropCheck, that stuff will make sense. There is a paper by John Hughes, talking about EQC and their experiences with EQC. I don’t remember the title of that paper. But I will try to find that paper, and it goes into explaining a lot of why state tests work, and why they chose symbolic calls, and that was really useful for me to get that backstory and that context of why they use symbolic calls and symbolic variables and how you deal with them. And actually, that really helped me just formulate an understanding of what was going on. ‘Cause in the paper, if I remember correctly, they never considered not doing that, because it’s so obvious that you would do that. And I was like ‘oh, it’s very un-obvious to me, why you would do that and what that is’ and, yeah, the paper is like ‘it’s a no brainer. Of course we did it this way, because it makes all the sense in the world’. AMOS: I’ll leave creating calculus as an exercise to the reader, ‘cause it’s trivial. CHRIS: It’s just a simple matter of programming, at this point. That’s my favourite hand-wave-y, BS, scientific journal term, ‘and then it’s just a simple matter of programming’. AMOS: Yeah, I should pull out the FTP test to their own github repo and then just say ‘FTP server, trivial’. ANNA: It’s just a simple matter of FTP, right? CHRIS: I went to a talk once where the premise of the talk was like ‘learn all about distributed logs’, meaning like Kafka, and the underpinnings of that stuff, and the first slide was like, ‘given you have a distributed log, then here’s all these things you can do with it…’ That’s a really big assumption. ANNA: But it’s easy, right, ya know. CHRIS: It’s a simple matter of programming. AMOS: If you do get out there and start using PropCheck and Proper, and reading both of the documents and working, push back some documentation to PropCheck, ‘cause it could use some help. And I’m not trying to say bad things about it when I say it could use some help. We all could use better documentation all the time, because we all learn differently and prove differently, so get out there and prove stuff. ANNA: Well, and that’s just part of the conversation that we had last week, right? If you have the capacity or bandwidth to help, in any capacity, it’s useful. AMOS: So, what have you guys been up to? ANNA: Have you been doing anything fun with Elixir, Chris? CHRIS: No. No, not at all… AMOS: I learned this morning I’m the only one writing Elixir full time right now. CHRIS: That’s changing for me really soon, which I guess we can go ahead and - it’s all official now, so I guess I can go ahead and say this outloud. But as of - this podcast is no longer going to be evergreen, ‘cause I’m gonna date it - but as of tomorrow, Friday, May 4th, I will no longer be working at Le Tote, and I will be taking a job with Bleacher Report to work on a lot of their back end systems and services and scaling stuff. ANNA: That’s gonna be fun! CHRIS: Yeah, I’m super super pumped about it. ANNA: Congratulations! CHRIS: Thank you AMOS: Maybe you could write some property testing. CHRIS: It’s - I’ve already messaged Friend of the Show, Ben Marks, and I said, ‘hey, we need to work out - you need to get your legal team on this GPL licensed Proper thing and figure out what that’s gonna look like, ‘cause we’re gonna need that’. AMOS: So, stated in PropCheck, in the - at the bottom of their read me, it says you can test your library with it, so I’d just look the other way, since PropCheck uses proper, and pretend that that’s my legal step forward. CHRIS: There is an issue open on Proper, and the issue is more or less ‘can we replace the GPL license with something that’s more permissive, because it scares people away from it. And the push back there is, ‘well, it’s basically an academic research project. We want to retain these ethics or whatever’. But in any case, there’s been a long discussion about it, and the statement was made in that issue that, as long as your library is open source, then you can use Proper for that, where ‘use’ is pretty ambiguous, and it’s also, like, I fully respect that, and that’s great that they came out and said that, like ‘hey, we’ll never challenge you if you’re using it for your other open source thing’, but like that’s also not legally binding in any way. So like, it’s great that we have a good faith effort to do that, that’s a great thing, but for certain companies that do have concerns about it, there’s a whole thing. AMOS: There is one way around it, if you’re nervous. CHRIS: An open source library? AMOS: Well, that works CHRIS: Or just don’t tell anybody. ANNA: That works too. AMOS: That also works - I would never suggest it. But put it - put your tests in a separate project entirely, and then have that depend on your main project. CHRIS: Yeah, I’ve heard of people doing that. And I’ve also heard of other companies, that were large companies, that had legal teams that looked it over and said ‘as long as you’re never shipping the Proper source code or your tests to production, then it was all fine’. AMOS: Do you have to open source to make your tests available to people? You don’t have to put those online? CHRIS: No, it’s like ‘it was all cool as long as you didn’t put it on a server’. And if you’re cutting releases, by that I mean, you’re baking like a real Erlang release, using like Distillery or something, then you would - then that would be you, ‘cause you’re not going to bake in your test dependencies and your test into that release, but, like, I still know people who deploy Elixir with Git. And in that case, like, I don’t know, are you okay? I don’t know. So it’s one of those things where, I am not a lawyer. If this is a thing that you are concerned about, which I think it is - maybe I’m making a mountain out of a molehill here - but I think it is worth being concerned about if you’re a company at specific scale, and you do need to check with someone who is an on-the-clock lawyer, who can give you real advice and tell you where you’re at with it all. AMOS: Yeah, like if somebody sues my company, they’re gonna be real depressed with the amount they can actually get. So, I’m less concerned. ANNA: But if your tests, like you said, had a separate repo completely, then… CHRIS: Yeah, I think that, that is a way around it. ANNA: I mean, for companies at scale that are really using this heavily and - they have different concerns than a smaller scale. AMOS: That’s the problem with GPL, is it’s really had to say, ‘I’m utilizing it to implement something else. I’m not really adjusting the original software or inserting it into my software. But there’s this grey area with GPL, where it’s really hard with the wording to come up with, ‘is this in the software or not?’ And then most lawyers, unfortunately, they don’t really know either, unless you have somebody with a tech background. I would get like, an IP lawyer, who has a CompSci degree and have them look it over. CHRIS: Yeah. Check with someone who is knowledgeable with these things, because I’m not. And to me, I dunno, it’s boring. Like, it’s not interesting… Proper is a great tool, all things considered. And it does - the StateM stuff is the magical part of it. I still contend, that is where the real power is. The rest of it is fun, and is good, but nothing compares to being able to do the State Machine testing stuff. AMOS: So something got brought up to me recently, about property testing in general, was whether Elixir core should have a property testing - I want to call it a library, but it’s not a library once it’s in core - but, have property testing as part of core, like we have X unit as part of core. CHRIS: You mean adding StreamData? AMOS: Yeah, or whatever. Anything licensing wise that fits. But, does that belong in core, or not. And I’ve seen some major arguments about it. So I’d just like to get both of your takes on if that is a core things or if it should be external. I have my own opinions that I might pop in here and say - ANNA: May or may not share. AMOS: Yeah, I’ll share ‘em, but you guys can go first. I don’t want to muddy the waters. ANNA: Chris? CHRIS: Umm…. Well, so, my gut reaction is: I don’t understand the arguments to not add it unless you also follow that argument with X unit shouldn’t be part of core. And then you start adding like a host of other things. And that sort of, from an emotional standpoint, I can at least get behind. I can understand having that argument. I don’t understand how you can have an argument that is like… I think there are technical things in StreamData that still need to be worked on. Like, clearly it’s not added to core yet, which means they think it’s not ready to be added to core yet. That’s not to say StreamData is bad, but StreamData is still a work in progress, and I think that's fine. I can understand the argument that you want to keep the language small and you want to keep the library, or not library - but, you want to keep the package that is Elixir small. So like, you don’t bundle X unit, you don’t bundle StreamData, you don’t bundle, like, a ton of other things. Just don’t add any libraries at all to it, and make it this tiny little core of a language that does these very few things, has these very few primitives, and makes them really really good. And that person probably also wants types or something like that. And people have those types of opinions. And spiritually, I can get behind that opinion, in the sense that I understand why you would have that opinion. It’s not an opinion that I personally have, but at least I can identify with that opinion. The thing that I can’t get behind is like, ‘where are you - why are you drawing the line arbitrarily at StreamData, and not X unit?’ And I’m not saying that person or those arguments are saying that, but I think you either have to throw it all out, or you have to accept that this is a holistic package where you have all these tools available to people right out of the box, and these are the right ways of doing things. Does that make sense? ANNA: Totally. I mean, that’s kinda along the lines of what I was thinking, also, it sounds like. I mean, I don’t know what the core team’s plans are, but you kinda alluded to the fact that maybe it’s not part of it yet - things take work and time and energy to make them high quality before putting something into a language. So, I think, the fact that they really care about that and are paying attention to that is really important. And I think, the people who want a small package versus the people who are okay with things like X unit and StreamData, or want X unit and StreamData added in, as far as like, accessibility and ease of use, making it easier for people who are newer to get started and get set up using these tools. CHRIS: Yeah, I completely agree with that. Like, the accessibility of coming to a language and immediately having this pretty good set of tools right out of the box that forces you, or encourages you to do these really good practices. Like, write tests! Write tests. If you’re gonna write a library or write an application, write tests. The fact that that’s all baked into the experience is, to me, a huge part of what makes Elixir a fun language to work in. AMOS: And, out of all the testing tools I’ve ever used in any language, the ones that were built into the language, like Anna kind of alluded to, they were way easier to set up. Because the other testing tools, you had to figure out how to hook them in, and it wasn’t just part of the runtime system, kind of, is how the built in testing tools seem to be part of everything set up. So you don’t have to go through some complex configuration or jump through a bunch of hoops just to get it to hook into the system at the right time or anything like that. Did you ever try to unit test C? ANNA: *laughs* No, have you? AMOS: Yeah. ANNA: How did that go, Amos? AMOS: Um… I don’t do it anymore. CHRIS: You don’t unit test C or you don’t write C? AMOS: Uh.. I write C every once in a while. Not very often, though. I avoid it, if I can. But I barely really write tests for it directly. I try to write tests in some other language and run the C somewhere, contained. ANNA: And I think that’s like, a direct reflection. I think that’s really - illustrates well, like we just talked about. Like, if we want people to be writing tests because we think it’s important. Or we think it’s important to writing and chipping confident code that actually works, making it easier just makes it that much more likely that people will be able to understand it and will continue using and actually practicing it. AMOS: I had very different reasons, but I want it in there too. So, I kind of feel like, if it’s used to build the language, it should probably be a part of the language. You know, to a point. I’m not gonna add ‘make’ to the language because we have ‘make’ or whatever. But if you have to pull down a library that is written in that language to write that language, that seems really wrong to me. And I personally would love to see Elixir itself tested with property tests, and making it more solid, because I do think that property testing is a way to make way better software than just with example testing. And I love example testing, but just with the weird conner cases that I’ve seen in the property testing libraries that I’ve used or seen other people use, that have popped out as kind of amazing. So I want that in core. CHRIS: Yeah, I don’t… I’m trying to think through the downsides of adding StreamData to core, just to think through what the other side is, you know, to try to understand why people would not want this. I wanna know, so that’s actually - I would want to know, what are the arguments for not including it. I have some in my head, but I want to know - I’ve made my own headcanon about this person now, and why they don’t want StreamData, but it’d be good to actually hear real things. AMOS: You’ve said size of the package download, which is something that I’ve heard. Like, if I’m not gonna use it, I don’t want it there. If I’m not gonna write a webapp, I don’t want Phoenix to be pulled down automatically. And one of the other big ones, was, if you put it into the language and into the testing framework, then people coming to the language feel like they really have to use it, and know property testing before they can utilize the language. And that was the reason I was given - that it might push more people away instead of pulling people in, because they feel like ‘I really need to learn this first’ or ‘I need to be able to understand this before I can write good Elixir code’. ANNA: Huh, that’s interesting. CHRIS: Yeah… I’ll have to think about that one...maybe that’s a thing. AMOS: It’s somebody’s thing. ANNA: But I wonder why… That’s an interesting argument… Go ahead Chris CHRIS: No, I’m formulating a lot of thoughts… ANNA: I think it’s interesting in the sense that, if you look at any other language that ships with testing or - I mean, I think ease of setup or accessibility of the tools - I’m curious about this in the sense that, adding something makes people feel compelled to have to use it. AMOS: It didn’t work for X unit. CHRIS: I guess that’s probably a real thing that people do. I’ve worked on Rails forever, and there are plenty of things that I don’t ever use in Rails for a host of reasons that we don’t need to get into, but that I see people use because they’re there. So there’s probably some amount of that… those are not the reasons that I would - if you sat me down, Star Trek: Next Generation style, and I was Riker and had to put data on the stand and all that - sorry, is this reference landing at all, with anybody? AMOS: Oh, yeah, I got it. CHRIS: Okay, cool, so, like if you told me I had to go argue for why StreamData was not gonna be added to Elixir, here’s what I would cite: Once you put it in Elixir, it’s now locked to Elixir releases, which means bug fixes have to be included in Elixir releases. And I think that other tools that have been added to the language like the formatter have had to have point releases to fix things. We’ve had to have releases of Elixir that included a lot of formatter fixes. And that’s what happens when you add something to the core of the language - is now, you limit your ability to release new features because you have to release them alongside Elixir as a language. And that, I think, is a reasonable argument as to why to not include StreamData… I don’t know, like, I think you could probably reasonably argue, by having something in core, you necessarily limit the amount of options that people are going to want to use…. That’s not the right way to say that. You are gonna drive the adoption of a tool arbitrarily because it’s included - how many people do you know that don’t use X unit? There are other testers out there for Elixir. I don’t - I’ve never worked with anybody who used one. AMOS: I’ve seen a lot of code where they’re not using X Unit either. ANNA: Are they writing tests? AMOS: ...No. CHRIS: But my point is, like, far and away, the regular test runner for Elixir has got to be X Unit. Just, anecdotally. I have nothing to back that up but my own anecdotes, which is - we’re on the internet, so that’s as good as anything else… AMOS: What’s the X-spec? And it just gets - it gets a hard rap. CHRIS: I’ve never used these things, and I’m not here to say they’re good or bad or whatever - they’re probably great! People probably put a ton of love and attention into those libraries, and they’re probably awesome, but the community uses X Unit because it’s there, and because it’s built in. I think there is an argument to be made, that, by having StreamData, you might limit the amount of love and attention that some of these other tools get. That’s probably an argument that someone would make, and would be reasonable to make. I don’t know that that’s an argument that I’m going to make. But I - again, I would emotionally resonate with someone who would make that argument. I can see why someone would make that argument. ANNA: No, I don’t think we’re here saying one argument is more valid than another argument. Clearly, there are many different perspectives. It’ll be interesting to see the choice that is made. I think you’re right - I think there are pros and cons to both sides. I think it depends on what the goal is. Or which argument the Elixir core team finds is in line for their vision with Elixir. AMOS: And I wonder if there’s - there’s… There’s gotta be a way to have it in core, but have it as a separate releasable library so you can get the updates, like you were talking about. Like, Ruby has some things like that. They have some things that ship as part of the Ruby download, but they also can - you can upgrade them through Ruby Gems. Ruby Gems itself, for instance. CHRIS: Yeah, I don’t know enough about the internals to know if that’s possible or not. And I also - I wonder how much people would actually do that… You know, I think for my own - just like, I’ve been dodging around actually saying what my real opinion is, but I am not opposed to the inclusion of StreamData in Elixir. I think it is a really useful library, and it will help people learn about these topics that are important. At some level. If you’re working on a system that necessarily has the kind of complexity where you’re worried about this kind of thing, you need this kind of stand in for formal methods, and you need this sort of robustness you’re going to add to your system in order to validate that things actually work. And I think it’s gonna introduce people to that. You know, what people do with it is kinda up to them. I don’t think we can police that. But I’ll also say that - I dunno, I know I’m gonna regret saying this, but I wish that we could just use Proper. I wish that Elixir core can just use Proper, and I totally understand why they can’t, but it is a shame because there’s so much good work that goes into Proper, and it does so many things - so much research and so much time and attention has gone into that library, and it is a really really robust tool. And, yes, it has edge cases. And maybe the AI isn’t exactly what we would come up with as Elixir people. I think that turns people off sometimes - they look at it and think ‘this doesn’t look like the kind of Elixir that I write at all’. StreamData does. StreamData looks like an Elixir library. But do I wish, to some degree, that we can just unify around a tool like that and put all of our resources into it? Kinda, a little bit. Like I know I’m gonna catch some heat saying that, but I kinda do, just because it has that backstory to it. Does that mean we shouldn’t include StreamData into Elixir? I’m not here to argue that. I still think StreamData is a great tool, I still think people should use it - especially if they’re getting started - but, you know, I have my own use cases and my own things that I deal with, and I have emotions wrapped up in this sorta like any body. In a perfect world, I’d love it if we can just use Proper, but that doesn’t mean I think StreamData shouldn’t exist. AMOS: Overall, though, it sounds like we all three are for add thing that too… CHRIS: You didn’t actually give your opinion. AMOS: I did! What? CHRIS: No, you gave someone else’s opinion. ANNA: He gave his opinion. He thinks that if the language is built using a tool - CHRIS: Oh, okay, that was it. That was your whole thing. AMOS: Yep, that was it. And I was my language to be built with property testing, so… yes, bring it in. So since you guys haven’t been doing much of this - one of the other things I’ve been looking at is purely functional data structures. I, to tell you the truth, haven’t made it very far. I’ve looked at zippers and finger trees - haven’t implemented any of them, just reading papers. Reading papers is interesting, too, if you like that kind of thing. I really need to start getting in there and messing with them. So have you guys had any purely functional data structures experiences - I mean, outside of list. CHRIS: Did you pick up the Okasaki book? AMOS: No. What magical book is that? CHRIS: The Okasaki book, by Chris Okasaki, followed purely functional data structures - I forget the exact title - but it was sort of ‘the book’ that prove you could do fast and efficient data structures that are mutable in a purely functional style. And he showed all these ways that you could actually start to construct this stuff. And the book is based on, I believe either his thesis and his dissertation - I think it was academic research that he did. It’s a really short book all things considered, as far as text books go, and it is a great read, and it’s one that sits close to my desk. It is one that I pull out and reference all the time. All the implementations are done in SML - standard ML - and then there’s an appendix in the back with Haskell implementations. So, if you’re used to functional languages, and you’re willing to learn just a tiny bit about SML, which is worth doing anyway, then it’s a really good book. It makes tons of sense. Yeah, he just walks through all these interesting data structures. He walks through different ways to talk about time complexities, so you know, as opposed to using big O which is asymptotic time, he talks a lot about being able to use Ametureize time, which actually takes into account things like how often you’re going to get data. Using the statistical real world, where not every piece of data is accessed that often. He talks about Ametureize time, which is supposed to be a little bit closer to how the real world works. It’s a really great read. Ah, highly highly recommended. ANNA: A’ight. I just looked it up. I haven’t read it. But should we talk a little bit about that next time? ‘Cause that sounds really interesting. AMOS: Oh, I need to read it. You guys are gonna talk about it without me. ANNA: Oh, we can wait! I forgot. We can wait for you. That’ll give us a little bit more time to read it. AMOS: I’m gonna be in the middle of a desert. ANNA: That sounds fun! AMOS: Yeah, I’m excited about that. But… Uh… It’ll be nice, quiet time. Never been alone in my life, so it’ll be nice alone time in the desert. ANNA: I’m excited to hear about that. CHRIS: You should take a purely functional data structures book with you. ANNA: Yeah, there you go. It’ll keep you company. The stars are gonna be crazy too. That’s gonna be awesome. AMOS: Well, I kinda live in the middle of the country anyway. So… I live in the middle of the woods. I get to see all the stars. Most of them. ANNA: Well, that’s awesome. AMOS: So, one thing, though, that I noticed when looking at the p-purl- blah. Those things that we’re talking about. CHRIS: Purely. Functional. Data. Structures. AMOS: Thank you. PFDS. Is that some of the implementations, especially for some of the complexities and times, really rely on lazy evaluation. So… if - I guess we might want to define that. So lazy evaluation is where your functions and all their arguments and everything are not evaluated until they’re actually used. So if you had a function that took in two arguments and then inside of it had an ‘if’ and it doesn’t actually use one of those arguments - even if that argument is a function call - it won’t ever be evaluated unless it has to be. CHRIS: This is actually, uh, one of the reasons why - I almost ‘well actually’-ed you there. Sorry about that. AMOS: I thought the title of this episode was going to be Will Riker, but it’s going to be ‘Chris Well Actuallys’. CHRIS: That is one of the reasons there is Haskell implementations in the back of the Okasaki book, because they do have - especially when it comes to Ametureize time, which I think will be super fun to talk about. So I think we’ll put that on - we’ll put that as a piece of homework. Pick up the book. It’s not too expensive depending on where - what your local bookstore/Amazon/your favorite online retailer of books has - and, yeah, it’s worth having a copy if you’re doing this kind of stuff. AMOS: And we’ll get a link to it out there. ANNA: Oh, yeah, for sure. CHRIS: A’ight. We should button this up. It’s been fun, as always. AMOS: Anna’s gotta go. ANNA: Yeah, sorry, y’all. I have to run. We will miss you next week, Amos. Have fun in the desert. AMOS: I will. And hopefully the new microphone works out well. And your new microphone you’re using right now. Which is not the same as the new microphone you bought right? ANNA: No, this is the fancy Carbon 5 microphone. CHRIS: It is very fancy. I’m just sitting here staring at it. It is so fancy. AMOS: So pretty… ANNA: A’igh, y’all. Bye!