Amos: Welcome to Elixir Outlaws, the hallway track of the Elixir community. Chris: I don't know if we've talked since Thanksgiving. Did we record a show after Thanksgiving? Amos: We recorded with Andrew. Chris: Yeah, that's right. That's right. Yeah. Amos: Yeah, but we didn't get to talk very much. Chris: We didn't do any shucking and jiving. New Speaker: That's right. Right after Thanksgiving, I actually got a little sick this last Monday. I woke up in the morning and took my son to school and I could still taste Chinese food from the night before, even though I had brushed my teeth the night before and that morning, and I started feeling sick to my stomach and I laid down and I woke up at 5:30 PM. Still like feeling terrible. So I think I got a little, I didn't, I don't know. I never really got sick. I felt like I had a little bit of a fever. It felt sick to my stomach, but just kind of slept through all of it. I've been slowly recovering since then. Chris: We had to take my son to the emergency room. On Thanksgiving day. Amos: Oh, no! Why? Chris: Like, we don't have any family close by. I mean, and I don't know if you've met me, but we definitely don't have any friends. Speaker 3: That's, that's the young kids thing. You got to find other people with kids at the same age or they just don't get it. When you have to cancel all the time. Chris: Alice was feeling sick. So we were, we were going to meet up with friends, but we couldn't go and do anything because we didn't want to go get like infected infect, anybody else or anything like that. That's the best part about being sick. Well, and we have a two week old at the time. Oh yeah, that's true. And so Andrew was dealing with the baby and I was in there trying to cook food. And then all of a sudden, I just hear this massive thump. Like I thought the TV fell off the wall or somebody knocked over like a bookshelf or something. And then just a lot of screaming. And I ran downstairs and my three-year-old was on the floor. I was like, what happened? And my daughter was like, he fell off the couch. Amos: So he was jumping on the couch. Chris: Translation they were playing battle as they described it. And she pushed him off the couch. Amos: Perfect. Chris: But he landed on his head. And so it, he split his head open, like on the back of his head. So we had to go get stitches. He was losing it, but we still managed to cook all Thanksgiving dinner. Amos: Wow. You guys are troopers. Chris: I mean, what else are we going to do at that point? That's true. He just laid there with the rest of the day in pain. We were like, we're really sorry, kid. We don't know. We don't have anything for you. Amos: I'm sure you have a headache. Chris: Yeah. Just kept an eye on him and then made food all day. Amos: Yeah. How many stitches did he end up with? Chris: I think five. Oh man. I think five man. I don't remember. It was a lot of stitches. Amos: Head wounds, no matter how small they are bleed a lot. Chris: Yeah. It was a sight. It was an interesting ordeal. Amos: Well, that's, that's fun. So then a couple of days after Thanksgiving, you started doing the Advent of Code stuff, right? Chris: Yeah, I've been doing advent of co I do that. This is about where I quit every year busy, but I like Advent of Code. Amos: It is pretty cool. The guy who does that puts in quite a bit of time. I did it one year about or five days in this year I was planning on doing it. And then wasn't feeling well, the first, the first two days I couldn't do right away. And then the third day I was exhausted and now I just feel overwhelmed. Like I need to go back and do those, but then catch up is, feels overwhelming. Chris: If you miss a single one. It does feel like it's real hard to catch up depending on where you're at. You know, I think there are the right amount of difficult, I would say right there, the correct difficulty level, at least for me where I'm at right now. Cause I think at this point I've spent somewhere between 15 minutes and an hour-ish on each one. Amos: Oh yeah. That's not bad. Chris: That's the right amount of time, but they've forced me to think about stuff. And a lot of cases when I spend more time it's because I'm trying to optimize a solution or take a ON squared algorithm down to an ON algorithm or something like that. Amos: I noticed that when I did it before, was that a lot of them can be solved very easily with a bad algorithm. Chris: That's the thing. A lot of them can be solved expediently, but they run really slow because a lot of the solutions are like, we'll just loop over this thing three times and find the thing that you need or you know, whatever. And they give you really big inputs. So if you've got a slow algorithm, you notice it. Amos: I also like that it has, uh, a storyline with it. I think it keeps it interesting. Chris: It's a very cute story. Amos: Right. And every year there's a different one. So it's really nice. But the like the oil or problems are pretty fun to go do sometimes. But because they're just some math problems after a little while I get really bored. Chris: Yeah. I've had those recommended and obviously I'm familiar with them, but I've never done those. Amos: A lot of them it's like, you can write an algorithm that will go over this giant list of things and come up with an answer and it'll take three days. Or if you go look up sequences and series, you have a little like X squared minus one will give you the exact same answer and you don't need to cycle through the list. So I don't know a lot of those come down to very simple problems. If you are willing to put in the time to look up the math versus just trying to algorithm your way through it. Chris: Yeah. I've been watching the live streams that José has been doing, and those are really fun. I've never really gotten into Twitch, no judgment against people who get into Twitch. I don't watch sports either. You know, I don't even really watch TV that much, but the Twitch thing, I think I'm about three to four years too old to get Twitch and like just instinctively get it. Amos: Did you just say you're old? Chris: No, I just mean that. I think I missed the, I think I missed the window by about that amount of time. Like it wasn't, it was a short, it's a small amount of time, but it's, you know, three to four years is enough to where it feels just a little bit weird, but watching José too, it's been really fun and I get it now. I'm like, oh right. Yeah. I totally understand why this would be appealing because you're kind of like just having this weird unidirectional, but not conversation with like chat. It's weird. Amos: I like Twitch for things like that, the whole watching people play video games is not up my alley, but I have some friends that worked there or do work there? And they watch video games on there and they're my age or older. Chris: Do you never do that though? Do you ever go over to a friend's house and play a game and just it'd be a one player game, but you would just sit and talk to each other while somebody played. Amos: Oh yeah. Chris: I think it's more or less the same. Amos: Except for less social. Right. I'm at my friend's house. I can go grab a sandwich or take over for a little bit or, or actually like have a conversation with him where on Twitch, I really can't. Chris: I don't know if I agree with that because I think it's social in a totally different way because like chat is often talking to themselves. Like they're talking on their own. Amos: That's true. They're being social well, watching you play a video game, it's more like, it's more like three friends go over to, uh, to a friend's house. And then they all talk in the background while he plays a game. Chris: We're well out of our depth and also completely correct for podcasts, which is where two white dudes talking about a thing we don't really understand and then explaining it to people. But like. Amos: And it's very Elixir and or Erlang on topic, right? Yeah, exactly. I forgot. We were going to talk about something day. Was it like a Christmas wishlist or something? Chris: That was the main topic that we discussed. I did the homework. I don't know if you did the homework. We should explain the home. We should explain the idea. Amos: I'm going to say this first. I didn't write anything down, but I have some things in my head, but some of them they're like a pie in the sky, never going to happen. Wishlist. Some things maybe at the beginning of Elixir could have been changed, but probably will never be now. Chris: That is okay. Here's my rubric. Here's how we sorta set the stage. We thought it would be fun to come up with a list of just things that we'd like to see in Elixir or in the community. And I want to make very clear that, you know, for me, at least a lot of these things have been discussed before and tossed out for whatever reason. And in a lot of cases, like they're really good reasons. There's a reason these things didn't end up, but there's still things that I, you know, for me it's like, oh, I wish that that would happen. I want to also make this really clear. They're not criticisms and they're not feature requests. Like, Hey please, somebody go do this. It's more like, this would be really cool. And these are things that I might work on. Or like I might personally build a library to do, or in some cases they're things I'm already working on. And then the final thing, I didn't specify this for anybody else for this thing I did, which is I wanted to kind of come up with stuff that I feel like people maybe aren't talking about in the same way that if you're like, Hey, name your five favorite albums that nobody's heard about. Like, it's cheating to say In the Airplane Over the Sea, like you're not allowed to, you're not allowed to use the indie album that everybody's heard of. Amos: I've never heard of it. Um, I'm too old. Chris: I'll send, I'll send you a link later, but yeah, you're not allowed to pick the thing that everybody knows. Like you can't say like, oh, the thing I wish was in Elixir is a better type system. Like it's like, okay, everybody's said that that's not interesting or, oh, it'd be really cool. If releases were built in the mix, it's like, no, that doesn't. Amos: One of my top ones here. You're going to be like, everybody wants that. Chris: That's fine. That's for you. That was a me personal thing. I don't want to bring up the stuff that everybody's already brought up. Amos: You thought way more about this than I did. Chris: Because I do the homework. The show is better when we prepare that. Amos: That's true. Chris: So you start. Amos: So I start, okay. Thing. These are in no particular order, just, just to be clear, any of these that we give, well, maybe you might give yours in an order, but mine are in no particular order. So I've been working with IO module a lot cause I'm billing a shell lately. And I really wish that like IO dot Getz could take in an option for the type that it returns. Cause it returns car data, which means that it can be a car list. It can be a string or it can be a list of lists of strings or car lists. And it depends on IO.SetOPs - :IO.SetOPs that the actual Erang you can set that to be binary, which will give you strings. Or I think the default is actually a car list and that's like a global setting for the IO for the specific process you're in. So it would be nice if I could just pass in an option at the IO.Gets itself. But then, you know, Erling has a hidden call. It's get past, I think, or get past w I don't remember. It's not actually documented, but it's in the IO module that will allow you to do like a password field in the shell so that it doesn't display the output of what's being typed. So it wouldn't work with that. It would work with IO Getz, but it wouldn't work with the hidden one. Just kind of frustrating. So maybe, maybe also an IO get password or an IO gets with visible. False would be super cool. Some options to pass in at the call site instead of some crazy global. Chris: That has to be possible now, because Hex does that, like when you push a Hex package, you have to put your password in or whatever. And it had already hides the output. I wonder what it's doing. Amos: Well, they might be using that. Or somebody was saying, there's like a trick going on where they actually just backspace the output, as soon as you put it in and then they ignore the backspaces in the input or something. I don't know. It would also be cool if I could do a, get for a single character without having the user have to hit a return. Let's, let's add that in. I just added that these are just like IO changes all together because in doing the shell, you know, sometimes you want to have like 'hit y' to continue or something like that or in, for next, and you don't want them to have to hit return every time or even show them the output. And so it'd be nice if I could just do a single character, there is a way to say, get me a character, but it still doesn't actually do anything until you hit return, which can be really frusterating. Chris: I feel like there's something for that. I feel like you're, there's probably some way to do that. Amos: I found some stuff online that is like, write a port or a niff to actually handle it. Chris: That's that is a, that's a living. You could, you could choose to do that. Amos: Maybe I should make a library that has that Porter and if built into there. Yeah. I do think that the, um, IO gets with an option to be visible or not. It's probably something that could easily be put into core. If somebody made the suggestion. Chris: Seems to me like a reasonable thing, caveat it with, I have no idea what repercussions that could have. Amos: Yeah. I don't either. I haven't dug in and looked at that, but I basically locally have a function that, that, and it just either calls out to IO dot Goetz or colon IO dot, whatever. I think it's get past, I don't remember off the look that up. So yeah, there's lots of hidden gems in Erling too, that are not documented. If you want to go read the code, thanks to Michael Schmidt for pointing that function out to me, which he found by reading code, Chris: You know, how there's always money in the banana stand. There's always more functions in Erlang. There's always some other thing. Amos: That as a good reference. That's kind of a deep reference. Chris: I don't feel like that's a deep refernce. Amos: I think so. I think it's not one of the ones that everybody's going to reach to for that. Chris: Yeah. Andrew showed me the other day that there's a, there's a balanced tree module in Erlang. I didn't know about that. Amos: It's tree module. I didn't either. I'm writing this down that just like exists. It'll balance a tree for you. Chris: You know, it's like how diagraph is like, built in. Amos: Don't tell anybody, but there's also an array module. Chris: I'm going to take that and I'm going to hop on it like a segue and, and talk about one of my things, which is I really would like to revisit the topic of bringing vectors or having a decent, uh, vector implementation in Elixir. And I don't mean an arry, although the Erlang array, I actually don't know how the Erlang array is implemented under the hood, but what I'm hoping for is the equivalent of closures vectors. So what's the difference between a vector and an array. So specifically the way we need to do it in elixir is to base them on ASHRAE map tries as is everything these days camped. Yeah. The Hampton's always the answer. I think it would be really interesting because I actually think generally speaking, I don't know. I think lists are kind of a garbage data structure. They're fine in certain cases, but they really start to fall down when you have a lot of stuff in them, right. When doing searching is bad, they're really inefficient. They don't give you a lot of power vectors solve a lot of those problems, especially on mutable, structural sharing vectors, like close your house. And there's actually a, I think this was before the forum, even there's like an old mailing list thread. That's probably like two or three years old now about better support for vectors and arrays and elixir. And that thread is in my mind, not super useful. I think a lot of people didn't understand what the original poster was asking for because they were coming from a closure background and saying vectors are really useful. And that the zeitgeists of Elixir who was on the mailing list at the time was basically saying, we don't need those. We have lists it's better. You don't, you don't know anything about functional programming with immutable data to this person. And the person like correspondingly was not super nice in their responses. And then it really more devolved into an argument about, I don't like you in the way you're talking to me. So I'm going to reject your proposal out of hand. It didn't go well. In any case, their main, actual real argument was that if you supported eraser vectors, how would you pattern match on them? And it would be kind of surprising to be able to pattern match on lists, but not be able to pattern match on vectors. Let's say when vectors in lists are seemingly analogous in terms of what you may or may not use them for. But I think at this point we have plenty of evidence to support that. Not every new interesting data structure needs to be able to be pattern matched, like map sets. I use maps that's all the time and there's really no good way to do pattern matching on map sets. I actually think there's a pretty compelling case to have access to vectors because they're much more efficient. They've got a lot of interesting properties in the way that they can compose. I don't know that that needs to be a core thing. And I don't know that we need to just support a res, although maybe I'm wrong about that. I'm essentially going to build a library to do that. That's on my list. Amos: On Twitch? Chris: Oh yeah. I'll stream it on Twitch. Amos: Maybe, maybe do property tests. Maybe we'll get to our property testing thing. Chris: That's not on my list. I don't see that on the wishlist. So yeah, that's the thing I want to take a look at at some of that. Amos: Point. That would be pretty interesting. I just want to say now that we brought up Twitch thing again, is that I think José doing the Advent of Code on Twitch is really awesome and good for the community. And I know Mikal has, has done some, some stuff like that too. I think that having that out there, first of all, makes those guys more approachable to people in the community and it makes the community more inviting. I think it would be awesome if more people were there doing that - streaming them coding. I think it also shows that, you know, it's, it's not like they sit there and they just have all the answers immediately either, which also makes other people feel way more comfortable whenever they're sitting there staring at a problem and thinking, I don't even know. So, so I'll add that to my wishlist. More people showing off code on Twitch - unpracticed code, just go in and do it, letting it ride. It's one thing if you've implemented that thing 15 times, and then you go on Twitch and you're like, Hey, check out how fast I can do this. How smart I am. Chris: It's gotta be pretty high pressure to get on there. And then one half to think about the problem to have to read, chat and interact with chat and then three actually come up with a solution all at the same time. Yeah. Amos: Yeah. It's like live coding at a conference. Chris: But it's like even worse of an idea. Amos: People get to hear your kids, your son's screaming. Cause your daughter's shoved him off the couch. Chris: She felt so bad for that. She was so protective of him for the rest of the day. Amos: I was going to ask if she babied him. Oh yeah, it was bad. Can I bring you a drink? Would you like something to eat? When he Chris: Got home, he was like super worn out. At one point, once he finally woke up a couple of hours later, they were going downstairs and she was trying to help him get downstairs. And as they're walking downstairs, he's like, Hey, um, can you not push me off the couch next time? She just turned and looked at me and he looked back at him and then looked back at me and just started crying. It was heartbreaking. Amos: So he wasn't trying to - Chris: No, not at all. He was serious. Poor guy. Amos: Oh, that's bad. It was bad. I feel for him. So next on my list, I know there would be concessions if we had this, but I would really love to be able to call a past in function without dot prepraed. Chris: Oh man. That's a deep cut. That's going way back. Amos: You know, I really okay. So this is, and I run into every once in a while and it's just slightly to me, but I also really like having parentheses optional. And I know if you did that with parentheses being optional, it's really hard to then pass a function because then that function would be the only type that wouldn't have parentheses he's optional. And so you would have to make prentheses required basically. I don't know which one I would like or dislike more. Chris: I haven't thought about that one in a long time. Cause I've just internalized it at this point. I haven't considered that in awhile. Amos: Here's the reason why - you ready? Chris: Hit me with it. Amos: I really, this is actually on my list somewhere else, but I think it almost requires the first one. Chris: This is a twofer is what you're saying. We need this first. Amos: It doesn't actually require it. I guess. It doesn't. It's just, when I'm working in that area, I think about it, lay it on me. I would really like a simpler way to compose functions. I would like to be able to say, define a function as this function, plus that function without worrying about anything else. Chris: You've been doing Haskell is what this comes down to. Speaker 3: Is that what that does? Chris: I've looked at your Haskell code and it's just all point free dots frigging everywhere. Amos: I don't mean to I'm just like I ran into the compose operator and was like, whoa, mind blown using this. I'm going to make sure I figure this out. Chris: You're deep into Haskell at this point, except you're not deep enough to realize like how completely unreadable it is for anyone who wasn't. You just wait till you learn about all the other symbols that you can use. Just wait till you find the lens package in Haskell. I saw somebody who had dollar sign - dollar sign just means evaluate the right side before the left side compositions happen in the opposite direction of what you think that they do in Haskell. So you use the dollar sign to break that so you can read it without putting prints around everything. So Amos: Yeah, I've run into a few places where I'm like, dang it. If I could just add that function to that function simply. And it's not like it's hard to do that. Chris: Creating patrials. This is the thing that I wish was a little bit easier composing those partials is the thing that I wish was a little bit easier, but I mean, it's, it's hard. You need so many other supporting things to be able to do that. Or at least like the ergonomics of that start to necessitate like auto occurring and you start to need these other ergonomics things Amos: And they have trade offs too. Chris: Yeah. I don't know. I mean blame the Beam. I think for that one, you gotta care about Arity. That's how, you know, you're screwed because you have to care about Arity. The fact that you have to care about Arity at all, it means that you're, you're already a long way from that path. Amos: Oh, you mean in Beam, you have to care about Arity and like Haskell you don't because every functional, it takes one argument. Chris: Yes. Even functions that look like they take five, but I take your point. It would be nice to be able to do some more partial application of stuff. It'd be interesting to see how you would do that and how you would make it ergonomic. Amos: I tried to sit down and come up with a syntax that I could build that would make it simpler that I could just make a library, maybe some macros or, or something. And I just couldn't come up with anything that I liked. Chris: That's the thing is the ergonomics of it are what is important. It's like, you can have it, but if it's not ergonomic, then it's not any better to use it because you haven't improved anything just because you can like arbitrarily compose partial functions together doesn't mean that it looks nice reads any better or conveys any more information to the end user at all. Basically your idea is dumb. No, I, I think, I think, um, it would be really, really interesting to figure out a nice way to do that. Actually. Does any of that Witchcraft library support any of that stuff? I haven't looked at that, but that seems like a thing that would be built in. Amos: I'm not sure. I think, I mean it, witchcraft is algebraic data types. Chris: This is like a whole suite of libraries that they've built. Amos: Right. They have a Alge, I think, which is implementations of algebraic data types. Witchcraft is like a toolbox for building algebraic data types. Chris: I wanted to say that they had partial application stuff in there. Yeah. That's worth looking into, because if anybody's got it, it's probably in that and has it in like an ergonomically useful way. It's probably that set of labs. There's some Amos: Really neat stuff in that witchcraft and. Chris: And it's, and it's, well-designed from a user interface standpoint. Like it looks nice. Amos: It does look nice. I've seen quite a few monad type libraries out there that I didn't think read very well, but I think that the witchcraft one does and a lot of that is they've implemented operators and everything like that. Kind of all over the place. Speaking of the monad library, um, I think I, I told you this on our chat the other day that I finally know what a monad is. Chris: You wrapped yourself In the burrito. Amos: Yeah. I didn't even realize that. I, I finally knew what it was, but I suggested maybe monad, Chris: You were sitting there eating, you know, all of a sudden smacked the Cholula out of somebody else's hands you're like, wait a minute, I've got it. Eat this burrito, hold the phone. Amos: Don't eat any more tacos. Your stuff just falls out, put it in a burrito. I just Chris: I'm just magine you sitting there eating a burrito. I mean, it's all a mental picture in my head, dude. Have you ever really thought about these burritos though? Like it's like money man. Like what is money? Like if you really looked at your hand, look good. This burrito, it's like a monad. Amos: I, I never talked about it like a burrito, the person I was suggesting to use it too. It was very funny too. Cause I started telling him about it and I was like, okay. So we just got into this type of discussion. It was like some types and product types. And, and then he's, he goes, you know, I have a masters in physics, right? Like I, I get what you're talking about. And then I brought up the maybe mode and he was like, well wait. And I was like, cause I really think you could use a, maybe monad here. And a lot of it was, I think that, you know, there's a lot of bare maps and tuples and stuff. And I think a lot of times, if we sit back and think about our data and actually create well-formed data structures, that's where we started talking that the code could be a lot cleaner because what did Andrew say in chat the other day, Andrew summer said, data's greater than functions and functions are greater than macros. And I kind of have a tendency to agree there. I think we can write a lot less code if we, if we have the proper data and data obstructions. And so then I ran into a section and I was like, so we should put a, maybe monad in here. I think it would help out a lot. And as soon as I said it, I thought, holy crap, I know what a monad it is. Chris: It turns out, if you just osmosis that long enough, it does seep in. Eventually I'm proud of you. Uh, you know, this is a, this is a whole, this is a moment in time. Amos: The thing is I get, I get hung up on looking at like the bind type signature and the fact that it has to be associative. And I just stare at that and stare at it. And I'm like, I don't - what? I usually end up taking the type variables and real types in there. Like if I rewrite it and I say, okay, it takes a, maybe of a string, then it's a lot easier for me to follow that when I'm looking at it takes a monad out of a and a function that of, and returns a monad out of B Chris: Yeah. It's almost as though the types don't really convey anything meaningful about your domain or your problem that you're trying to solve. Amos: Yeah. And that's this, this true man, which means I should use more specific types. Yeah. You Chris: Can, you can infer from that, whatever you want to infer from that Amos: Type aliases, speaking of type variables. I also wish that we had type variables for our type specs. Speaker 4: What do you mean? Amos: Oh, like, uh, um, well, let's go back to the maybe monad. What if I could do a maybe, Hey, wait, what? Oh, I know that my app type can do that, but I can't use it in my app spec. Correct. I can't say maybe have a, the spec actually has say maybe string. It can't say maybe a you can have a type variable in your spouse. Chris: I want you to explain to me how you would ever parameterize the type of a function like that. Like a concrete function, other than just making it any. Amos: I know, I know that's the problem. Chris: But the problem is that what you just asked for is nonsensical. What I probably Amos: Actually need is like a, it's like a, some type and pass that. Instead of saying, instead of saying maybe a, I need to say maybe my some type, because I know that everything under here can take in that one of those types of - so some type for, for people that don't know is like a second or like my type is integer or string. So some type is also another thing that osmosis into my head. So I started sounding, sounding more pompous. Chris: But to be clear, you can have a type that takes, uh, a different type as an argument. That's the thing you can send you that just, I know, you know, this or at least to pretending to now to save face. Amos: It's the, it's the, the spec part. I was like, man, it would be really cool to say this function can take, but then it's just any - you're right, at that point. It's just any so, and if you could say that types meant that it implemented a specific behavior. Yeah. Yeah. Chris: That would be interesting. That would definitely be interesting. Amos: Instead of having to build your own some type of everything that implements that behavior. Chris: Yeah. That would definitely be interesting. Amos: There might be a way to actually jam that in there. Somehow if, whenever you say that you implement a specific behavior or protocol, it would have to be something that would change the, like your type would have to be the name of your behavior dot T and then everything. It would automatically have to go back through your code at compile time and look at everything that has that type and then generate that signature as a, some type might be pretty good. Chris: Yeah. I don't know. I can't, I'm not, I'm not ready to invent a type algebra, uh, with the power of my voice. Amos: All right. So, so what do you have? I've talked enough. Chris: I'll say, um, that's normally my job, sir, job security. I'm the one who talks too much on this show. You're ripping me off. I got an interesting one and then I got an easy one. Which one do you want? And then I got some wackadoo stuff here at the end. Amos: Let's go with the easy one so that we can just get past it. Then go to the interesting one where we, so that we can get through more. Chris: So this is the easy one is I wish that, um, the majority of functions on Edam and stream took an identity function as a default function. So like you didn't sort of like, it was just identity was the default, which wouldn't work for all functions, but I think it would be super convenient and useful for a lot of them. Amos: There are a lot of them that do right. D-Dupe... Chris: I guess, is what, um, some of them do, some of them don't I, and I wish more of them did. And I think that there was a, there was an old mailing list thread, but I couldn't find it. I didn't look that hard, uh, about that. And it never took off. So that, and that might be something that I'd go work on. I don't know that there's a reason to not, uh, maybe there is, there might, there might definitely be, but, uh, I haven't been able to think of one, someone much smarter than me can analyze that poll, that poll request and let me know why, why it's a bad idea and yes, I get that you can do pretzel pretzel one, and that's the same thing as identity, but I don't know. I think there's some power Amos: It's, it's actually pretzel pretzel one is it's way more readable than I. No, I'm kidding. I'm kidding. Chris: Anyway, I think that would be a really useful thing. Amos: Yeah, I call it, uh, I think there for a while I had it in my head because of maths from Ruby, it was the lonely operator. Chris: What do you call the question mark? Cause like, because exclamation points, bang, what do you call it? A question mark. Amos: Crooked ang. I've I've heard a before. I've called it "a" when it's like at the end of a function. So instead of saying like, uh, is biggest question, mark, I'll say "biggest a". But yeah, the pretzel - Mats, I think, called it the lonely operator. Cause he said it looked like a little kid sitting down, looking at the floor. Chris: What? Amos: Yeah, look at it here right now. Let's find one. Chris: What fonts though? I mean, that's the real question. Amos: I don't know. Chris: Oh my gosh, I get it. I totally get it. Yeah. That's like, that's like his leg, like he's, he's looking at his iPhone. Amos: He's criss cross applesauce. Chris: That's his arms - his arm or, or her arm. That's their arm. That's that's their arm looking at a phone. That's amazing. Hang on. I got to try this in San Francisco or whatever it is. Oh, it doesn't look nearly. I would never have gotten that from my terminal font. A feara mono. Amos: I don't know that I've seen fear amano. Chris: Feara mono is what feara code is based off of. Mono is the monospace version of feara from Firefox or Mozilla. Amos: So, so it has ligatures? Chris: The ligatures are fear code only. Amos: Okay. I like the ligatures. Chris: Whatever. Yeah, sure. To each their own. Amos: After you get used to looking at them. Chris: I don't know. I don't dig it, but it's, you know, I get the appeal. Yeah. It doesn't look right. Uh, it doesn't look right with fear mottomono. Definitely. I wonder what Minlow looks like. Amos: So there you go. Everybody out there - Chris: I'm not calling it that, but that is interesting. Amos: Don't don't like feara code, try feara mano. Or if you love ligatures and you're on feara mono, switch to fear code. And if you haven't tried either check them out. Chris: Fonts are important. Getting the right font. That's crucial. Amos: I'm not too obsessed with it, but every once in a while I wait for other people to kind of curate that for me and suggest three or four of them. And when I get a bunch of new suggestions, then I'll go look at them and see if I like them better than what I'm currently using. But I know people who spend hours digging through fonts to find the right one. I have more things to do. New Speaker: I'm looking at iterm two, like most of the day. So there's only, there's a, there's a very small like window in which I can move to make that look nicer. There's just only so many things you can do to make an actual seventies era technology look a little bit better. So, you know, it's a small window in terms of improvements that you could make. It's the fonts is all basically a font and, and picking what version of solarized dark you like is the only choice that you really get to make. Amos: So I have to ask a question. About your terminal. Transparent or not? Chris: No, no, what are you... no. Amos: Okay. Yeah. I don't like it either, but I've programmed with people that have a transparent console and then they have a web batch behind it with text on it. And I just can't read anything at that point. How do you...? Chris: That is um, that's that's total clown shoes. Amos: I had one guy tell me that you just have to focus your eyes at the right distance. It's the same distance. Chris: No, I don't. That, that is terrifying. Amos: It was like, uh, you know, you, I don't know how old you are. Do you remember the, uh, they just like a scrambled TV image, but it's like a 3d image. If you look at it. Yeah. They were in the mall. When I was a kid, Speaker 3: There was a store that sold those in the mall. That seems appropriate. It was across, it was across the way from the Buckle Amos: It's a schooner. It's not a schooner. It's a sailboat Chris: Stare at those things for far too long till they finally worked. There was all the tricks about you had to click, you had to cross your eyes. It was like, people had just discovered computers and computers could make art. And they were like, look, what we can do now, this is going to be the way of the future. Amos: And then soon as it would pop in and you would be able to see it, you'd get excited and it'd disappear. Chris: But I had it. I had it. The thing is, is you can also lie. Cause, cause you can be like, oh yeah, I see. It's like, it's like going to a wine tasting. Right. I just swirled. I just swirled around the wine in there. Like, this has has a lot, there's a lot happening in this glass. Do you just taste those notes? Look good. There's so many notes. I just, there's a lot of complexity, a lot happening in this glass. That's how you can do with those pictures. Usually the picture like, oh yeah. It's amazing. It's beautiful. You're just, meanwhile, you're just staring at like red and orange and yellow, like blobs. Like I totally see the horse with the monkey on its back. Yeah, absolutely. Amos: You brought up wine tasting. So I've got to tell you the story you're gonna Chris: Okay. You know, at some point we have to pop the stack back down to Elixir, but yes, go ahead. I'll allow it. Amos: Well, you, you, you went to, you went to school in Arkansas. So I was in, um, something Springs, Arkansas right up by the Missouri border. I can't think of - Eureka Springs? Is that what it's called? And uh, we went to this winery there. I'm not going to name it and went to a tasting and it was one of those tastings that you have to pay for. I'm like, whatever. So we, we sit around this table and there's another table of people that we don't know. Um, my wife and I are there with another couple that we do know. And this lady goes through all these, these wines and they're all mediocre tasting. Like they're really not good. Chris: Right? I mean, sure. You're at a winery in Arkansas. So yes, not that, I mean nothing against, there's lots of, there's lots of very nice things in Arkansas. You got the, you got the Ozarks, you know, all that kind of stuff. It was very, very lovely. Um, not known as the temperature to grow world-class wine grapes in. Amos: But I lived in a wine town in Missouri and we actually had some pretty decent wines now that there were a lot of wineries in a lot of different wines before you find decent ones. But there, there were a few. So we get to one. And first of all, my friend is really way more into wine than me. So at some point she says, I love this. When you put it in the refrigerator and get it cold to where it's almost frozen, that's what it's best. And it was like a red wine and he's like, that's supposed to be kinda near room temperature really. And then the last wine, here's the thing that you're gonna think is funny. She talked for five to 10 minutes about how it's her favorite wine ever. And then she pours a class and we pick it up and you smell it. And it smells like grey water and the people at the table next to us, I watched them only one of them would even try it. And their face was like a grimace. And then everybody at my table poured it into my glass. And I tried it three times because I was convinced that there was something wasn't quite right. Like, like she's talking about how this is her favorite wine. It tasted like gray water. So Arkansas gray water wine. It's her, her favorite? Chris: People, people like people what they like. Amos: I'll send you a bottle. Chris: Right, you ready for my more wackadoo one? Amos: Yeah. My story was not near as funny if you weren't there. Chris: I'll take your word for it. Um, so, here's the one that I think would be really interesting and I don't think there's any way we'll ever get this. This is like at minimum, like an Elixir 2 thing. Like there's no way to do this, but it would be super interesting. I wish that keys in maps, you could use them as functions. So if you have a map and you have the key, you could arbitrarily use that key as a function. Like, like you could say enum.map, the list of data structures. And then the function that you pass in is just the key. Amos: So your list of data structures would be like a list of structure maps and you pass in the key that you want to pull out and nothing else. Chris: Right. And I have no idea how you'd make that work correctly with like string keys. You know, I, I got an, I have not, I have not solved the problems of what you would need to do to make that work in Elixir, but that's the thing that you can do in closure. And it's awesome. It's really, really convenient. Amos: I do'nt know how hard that would be really. I mean, if you can match on the type, you put a guard clause in saying it's not a function. Then you just start. Then you just create a function that, that treats it as a map and use or anything that can handle it. Chris: So that's the thing is, is like, I think, yeah, there's, there's a bunch of questions I have about how you would do that. But the cool thing is, is then you could take all of the access stuff, like get in, put in update in which I don't know. I don't actually see those used that often. I use those all the time and I don't, I don't see people. That's probably my own experience, but I don't see people use those a bunch, but they're great. But the cool thing then is that what you're passing into that isn't just like the path to wherever you want to go it's functions so you can compose them however you want. Amos: Get in can take functions in place of keys. Chris: But what I, what I mean is at that point, you there's, no, this kind of goes back to your idea about like, well, if we could partially apply things that would be really cool or like, like compose functions, like then you open up this ability to start like composing, um, those pipelines as, as functions. Cause it's just a list of functions that you're composing together. Does that make sense? Like, because the keys themselves to like do access are just functions. Then you can pass them arbitrarily around as functions and you can start to like get a little bit more power out of them. The inverse of this is also a thing you can do in Closure, which is that you can pass a data structure as the function to a map. So if you're like mapping, let's say you have a, in our world, like a map of with string keys and those string keys, the values for all the string keys are numbers. You can do map and then pass. And then as the function, you can pass the data structure. Amos: Almost like being able to use what, like ENewMen2 a little bit, except for like over a huge list of them. So if I could have, if I could have ENewMen2 take in one map and give it another map that has a set of keys in it and it automatically pulled out and populate just to that second map. Right? So are you saying if I have a list that has maps that have keys A, B, and C - Chris: You, you don't have a list of maps. You have a singular map and it has ABC and D and ABC and D correspond like the values corresponding to those keys is a integer. You can do in - Elixir terms, be able to do Enum.map. And then you pass the list in. And the list is the list of keys, which are again, remember functions, functions themselves. So you would have a list of keys. So you would have a list of string, ABC and D. And then as the function you want to apply to that list, you could pass the map itself. The output would be, um, just a list of the numbers - of the values, but because you can just pass the data structure as the function, uh, it opens up this ability to do a lot of interesting composition. Amos: That's pretty cool. So it reminds me of map.take only the, the arguments are swapped. Chris: It's similar ish, but yeah. It, because you can sort of compose them arbitrarily cause they're just functions. It's a little bit different. So I don't know. I have no idea how you would make that work in Elixir. And it's not something that it's like, it's, it's more an interesting thought to me of what would it look, what would it looks or look like if you could do that kind of stuff. That's and I have no idea how you would actually solve for that, but it's interesting. And then you have all these problems with atoms and whatever else. So that would, that'd be a different thing. Amos: It gets really hard because your maps can have all kinds of crazy keys. Chris: There is probably no realistic reasonable way to do it. Amos: I'm gonna make a map where all my keys are functions just passing out functions. Is the key. Chris: Let me see, what do I got on here? What's good. Um, I, I know that this will never happen at this point. It doesn't seem like it'll ever happen. I still really wish there was a compare, uh, comparison protocol so that you could implement comparisons for any arbitrary data structures. Uh, I don't know how to do that and make it work well with the beam and with Elixir. Uh, but that would be interesting. We interesting to find a solution to that. What else is here? Oh, okay. So here's, here's a good one. I really, what I, something, I hope something I hope people do in the coming year. I really hope that library authors start supporting telemetry. And I know telemetry is still early and still being worked on and kind of baked, but I really hope people adopt that as a standard, uh, for doing metrics because at least for me, we spend a very large amount of time trying to wrangle metrics out of all these libraries. Um, and it's very tricky and it's very difficult and, and it may not be important to everybody, but it's certainly very, very important to us. Like we have to have that kind of stuff. And so I would love it if more people were supporting, um, and telemetry is a good standard for that. So it'd be nice if people were supporting that as like a standard, because then it's like, you can just hook into that kind of stuff and, and be good to go. Amos: Yeah. I'd be pretty happy with that. I think it's not just you - metrics are, are really useful in tracking down issues or just seeing how users behave, all kinds of stuff. You can get lots of data, especially if you're a big data geek that likes to just sit in and look at spreadsheets and stuff, and you can pull all of that. You can come up with just about every answer to any question you have. Chris: I mean, we've talked about this before, but metrics are how you learn that there are problems with your system. You know, monitoring, looking at those metrics tells you that there are problems with your system. That's your first line of defense. Amos: No, exceptions are! Chris: Then, you know, all the rest of it like logs, which I don't really believe in, but other people like logs more than I do. Amos: You don't, you don't believe in logs? Chris: I mean, I believe, I believe in them in the sense that like, I believe that they are real things, but I don't believe in putting a bunch of time into them. Amos: I hear you can build rafts out of logs. Chris: You can build a raft out of logs. It turns out that's the only way to build a raft. It turns out if your raft has no logs, it's not a raft. It's an interesting, it's interesting how that works, you know, tracing and other APM type stuff is all real like that observability kind of tools. Like if logs are a part of your observability, that's really useful for you. Um, then, then keep, you know, keep on keeping on. I'm not gonna stop. I'm not gonna stop you obviously, but that sort of tracing that observability is like the next, the next stuff, which actually helps you diagnose why the thing is going wrong. But yeah, the getting just raw metrics out of a lot of the libraries that are out there would be very, very nice. So I hope to see people embrace that. Amos: You heard it here first. Chris: I don't know about first, but sure you have anything else. Should we end on platitudes here or other real things? Amos: This is more of a pipe dream - as much as of a wishlist. Um, I wished every time somebody called process dot get and process dot set, it would send them an email. Whoever, whoever typed it should get an email that says, Hey, this happened. So I think, you know, globals for the most part are pain in any language. And then when you add globals to the process level in a language where, you know, sometimes when you're two modules down from a gen server, three modules, or you have a module that can be used in multiple processes, it's really hard to know what process.set process.get you're actually calling because they're, they're global to the process, not global to your application or see, this is, this is the, the other thing with Erling and Elixir OTP. That kills me not, I don't mean your application. I mean your entire project. How about that? It's not global to your project, but sometimes people think it is. Or even if they mean to use it as the process, I would much rather you pass the data around otherwise. Why would gen server past the stated they would just say, Hey, we we've saved it to the process. Process dot set process that get inside your gin servers. I really just wish everybody would stop using it unless they have a really, really good reason. And you should have to convince 50 people. Chris: Or receive an email. Amos: Or receive an email every time it gets called by it gets called by your system. Chris: That's not a big problem at all. I just, you know, set up spam filtering and good to go. Amos: But from a different email address and different subject line, each time Chris: Underestimate my ability to write rights filters. Amos: Oh, the problem is it's always signed by prince of Nigeria or some other random - Chris: Can I hit you with a life, a life hack real quick. Yes. You can create a filter that filters out anything, any email that has the word unsubscribe in it and send it straight to spam. There you go. Life hack. Amos: The other one is when you get an email that has an unsubscribe link, go ahead and click it because you probably don't want it. Chris: All right. It's my, my actual last thing is actually something I'm actively working on and I'm working on it in, uh, with the help of, uh, friends of friends of the show, uh, Jeff Wise and, uh, Ben Marks. But we we've really been needing a way to do dynamic runtime level configuration. Um, and then also be able to have that configuration change live without having to like kick over the server or whatever. And also, but also without, you know, the other bit is like, if, you know, let's say you're pulling, let's say you're pulling you're, you're hitting the system.getM to pull an environment variable or something like that. You don't want to do that in like the critical path of the requests. That's just giant like massively wasteful to do that right in the path of the request. So we need a way to like store it, but then live update it when environment variables, change, stuff like that. And we're trying to build it in such a way that you could have those change based on changes in detected in EtCD or fault or whatever. So we're building this thing called vapor, which I started a long time ago is like a thought experiment that is, uh, and, and that we're putting a bunch of effort into that so that you can actually specify sort of dynamic configure app application level configuration, like is this, this is going to handle a lot of stuff that Distillery is really good at, and it's not gonna replace a lot of things that are out there for people necessarily. But, uh, it's definitely something interesting, uh, something we've needed for a long time. So maybe people will check that out and we're going to continue to do that. And I hope that it's a way to help. Maybe more people move away from things like application.gov for all the things that's on my list of things to, I guess that's more like, it's not really a wishlist, but it's more like, it's just a list list. It's like on my to-do list. So we're working on that. Hopefully people find that useful. Amos: I think it would be useful. I've been in a few places on projects, um, where I've overwritten parts of the project so that I could do runtime configuration because there are almost every hex package out there is decent compile time configuration. And it's sometimes you want it to be able to change at run time. Or if you have users that log in, you want them to be able to configure their own way of interacting with X service. Like maybe they use their own. Chris: Or you need to do fail over, or you need to change the URL of, you know, the downstream API that you're hitting, or like hit a new load balancer or whatever. Like there's all kinds of these, these there's these scenarios where you want to be able to dial that stuff in automatically. And the choices are basically you build it bespoke for yourself, which we've done in the past, or you hit the system for every request, which isn't good, or you have something universal that you can just tap into. And that's, that's the kind of goal that we're trying to do, which is what we're trying to achieve Amos: Or redeploy just so you can change... Chris: That's not tenable. Come on. Amos: I just wanna say, uh, um, I've made it through a third of the Getting Things Done book. Chris: Yeah, it looks really good. Amos: The book is good. I really should probably concentrate on one book at a time so I can just finish it. Chris: Have you read the rest of Purely Functional Data Structures. How's that going? Amos: Nope. No, it's on the, it's on the shelf because I thought I should read Getting Things Done first, but then I got sucked into four other books. Chris: That's the, that's the problem with things like getting things done is you don't have have enough time to read it. Amos: I'm, I'm getting on it. I'm getting on it. Sit down and read almost all of section one, two nights ago before I got there three nights ago before I got sick. Chris: It's in certain ways it is not aged well. Um, but I think the core, the core, the core premise is pretty good. Amos: It seems like the ideas so far are pretty Chris: You probably don't need any of chapter one, which effectively makes the argument, that knowledge work is a thing and that knowledge is different. Yeah. You probably don't need that chapter. Yeah. You can probably skip that chapter, I would say. But, uh, yeah, the book is the looks pretty good. Amos: We have, we have one last thing on the agenda. Chris: First of all, wait a minute, we have an agenda. There's been a lot of shock. There's been a lot of shucking and jiving in this, in this episode, we're all over the place. It's been a long day. It's a big week. These are trying times. Amos: Right now, this agenda is put together at the last irresponsible moment. Chris: It's so last minute that I don't, I was unaware of its existence. Well, it just got created. Amos: You know, we, we hit a thousand followers in Twitter and the folks that have extra cards, you know, they have generously donated cards to give away and they actually ship it straight from them. So that's pretty awesome. We've, we've shipped to two users so far. Our thousandth follower on Twitter, Jay Joel, I think his name. I, I'm not sure if I might be messing that up, uh, it might be somebody completely different. And, uh, Jeremy Boggs from the show with José. So we've got to figure out how to give away another pack of cards because those Elixir cards are super awesome to have and, and mess around with. They are really good.And if you can get a pack for free, like why not? Right. They're super duper fun, but warning, you'll want to buy the rest of them. Once you have a pack. New Speaker: