Sascha_Wolf:
Hey everybody and welcome to another episode of Elixir Mix. This week on the panel we have Alan Weimar,
Allen_Wyma:
Hello.
Sascha_Wolf:
Adi Angar,
Adi_Iyengar:
Hello.
Sascha_Wolf:
and me, Sosher Wolf. I'm kind of back. I've been away for a few weeks now and now I'm back. So actually we would have had a guest right now, but they got COVID, so they had to cancel short notice. So just before they hit with this record, but we were like, okay, what are we gonna talk about? And we realized that one thing we've never kind of done is just talk about what elixir things we do right now, day to day, boring kind of work things, right? Like what keeps us busy at night thinking about the elixir prophesies? Like just how am I using elixir right now at work? What's cool? What's annoying? What's something I've learned recently? So this is what we'll be doing. I hope you take a few things away for yourself when you listen to this. So, Alan, you just told us that you do like... basic boring air quotes stuff, but you also have been working with this Java guy in an Elixir Code base and there are some hurdles to be overcome, let's say that.
Allen_Wyma:
Yeah, he's just not used to the way, you know, functional programming, number one, with this kind of amenable data. Because I mean, if you're writing elixir, it's a little bit deceiving, right? You can say, you know, x equals and then later on you can do x equals again and you're actually kind of rebinding. You're not changing anything, right? And so like what I've seen him try to do recently was like, okay, how come if I do an if statement and I have like three lines of setting variables and after that things are, they're not changed. Right. And I had to show him how you can use a if statement and return something at the end. And you can change something. Well, kind of change, right? You're basically rebinding. And show him how you can make some very precise code, very readable code. It takes a lot of time. Like, I looked at his code, and I was like, yeah, this is very much procedural, like Java-esque. Lots of stuff, big function. And I showed
Sascha_Wolf:
Hehehe
Allen_Wyma:
him, yeah, he laughed. But I think we all did that at the beginning, at least. and then took us some time to get into the flow of how you write Elixir. And I showed him the pipe operator. I explained him how it works. And I showed him, why not try like this? Why don't you try making a data structure, like the con for when we have with Phoenix and plug
Sascha_Wolf:
Mm-hmm.
Allen_Wyma:
applications. And then I have it pipe through a bunch of functions. And those functions will describe what you're doing. And he's like, oh, that's amazing. I love that idea. And then like. I can tell he showed to somebody else because in a PR following then I saw code nearly identical to what the pseudocode that I wrote to him. So it's quite nice to see, you know, these ideas catching on, you know, and makes code so much more readable.
Sascha_Wolf:
Yeah, I think we've all seen that. I've also all done that. I mean, it's been a while since I started with Elixir, but I do remember that like the initial hurdle, especially when you come from a more mainstream language, let's say that, or more mainstream paradigm or complete the programming, then like this whole functional approach is like, oh, wait, what? But I want to change it here. Wait, why does this not work? So I'm wondering, was there anything in particular like you pointed him to, like a tool website, or were you just... sitting alongside, helping him figure things out. Sorry for cutting you off the audio, by the
Allen_Wyma:
No,
Sascha_Wolf:
way.
Allen_Wyma:
no, it's OK. I think what I first did was he showed me what he wanted to do. And then I think I just did a one line if statement, one line if else statement, and showed him how to set the variable like that. And then, yeah, I think he kind of understands, because he's been looking at Elixir code recently and doing some PR reviews. So I think he starts to get it. Yeah, I mean, I think, you know, he's been programming for a while, too. So it's not like it's all brand new to him. So I think he can kind of understand what's going on. He actually used to work with OCaml. I believe it was quite a while back.
Sascha_Wolf:
Oh, interesting.
Allen_Wyma:
So he has some functional. Was it Camel or OCaml? I think it was Camel actually. If that makes sense. I forget the difference of tuning too, but I'm
Sascha_Wolf:
There
Allen_Wyma:
pretty
Sascha_Wolf:
is
Allen_Wyma:
sure
Sascha_Wolf:
a
Allen_Wyma:
it
Sascha_Wolf:
language
Allen_Wyma:
was Camel
Sascha_Wolf:
called
Allen_Wyma:
actually.
Sascha_Wolf:
OCaml, so OCaml
Allen_Wyma:
Yeah, I know there's,
Sascha_Wolf:
is something
Allen_Wyma:
there's
Sascha_Wolf:
which
Allen_Wyma:
both,
Sascha_Wolf:
exists.
Allen_Wyma:
I believe.
Adi_Iyengar:
Camel's
Sascha_Wolf:
Is
Allen_Wyma:
So
Sascha_Wolf:
there
Allen_Wyma:
I
Adi_Iyengar:
Alderaan.
Allen_Wyma:
think
Sascha_Wolf:
both?
Allen_Wyma:
you, yeah, it's probably Camel, I think, cause he's a little bit older than me. And so he knows about pattern matching and stuff, right? So some of the ideas already caught on to him. Yeah, so it's quite interesting to see somebody struggling with this in terms of how and then when they finally get it, it's good. And actually, this has been probably one of the fastest people to get something that I've been trying to show things to. But yeah, that's kind of been what I've been doing. And another thing actually I've been also doing is upgrading a lot of old apps from Phoenix 1.6 to 1.7 and removing the views, which takes forever, and converting from EEX to HEEX and converting all the Phoenix html to HEEX style also. So that took me over a day just for one application, just converting all the templates. Took forever. Have you guys done
Adi_Iyengar:
But day
Allen_Wyma:
that?
Adi_Iyengar:
is pretty fast, dude.
Allen_Wyma:
Yeah, well, these are smaller applications, but still, it was painful. It's not easy, right? I was like, Oh my god. This is
Adi_Iyengar:
I mean, it's also like with
Allen_Wyma:
fun.
Adi_Iyengar:
Hex, you have to also limit your usage of the embedded stuff within the attributes and stuff. So it is not trivial at all. So I think it's impressive. I kind of want to touch on that thing again, defining things inside an if block and expecting it to be outside. It reminds me of like we talked about this thing. I just want to bring it up again in an organization that shall remain unnamed. people using process.get and process.put to solve
Sascha_Wolf:
Oh
Adi_Iyengar:
that.
Sascha_Wolf:
yeah, we talked about that.
Adi_Iyengar:
I loved
Sascha_Wolf:
I remember.
Adi_Iyengar:
it, I loved it.
Sascha_Wolf:
And there's always this point, sometimes in my career I see code where I'm like, why was there never the point where you thought, what am I doing? Right? You know what I mean?
Adi_Iyengar:
Yeah, yeah. I think it's generally I've seen it happen when someone who doesn't know Elixir much learns about something and they are the only person who knows Elixir in the team and others are
Sascha_Wolf:
Ah,
Adi_Iyengar:
learning
Sascha_Wolf:
yeah, okay.
Adi_Iyengar:
from that person, the pattern develops like that. Yeah, it's very, very common. I think one thing you guys talked about pointing, I need to give a shout out to this. Bruce State has something called the CRC pattern. Construct. reduce, compose, I think, or the other way around. But I think the point, well, yeah, construct, reduce, compose makes sense. So it didn't really honestly, I mean, to be honest, when I heard of it, it did not really vibe with me because I had been doing functional for a while. But I decided I didn't really understand the importance of teaching that to someone. But when I started mentoring people who think differently than I do, literally every person I've mentored and showed that too has really changed the way they start doing Alexa and use pipe operators. And that's kind of what Alan was saying, building that struct and piping it through. So I think CRC, if any beginners are listening to the podcast, check out Brewstate CRC. There's a couple articles he's written about that. And he has a couple other really cool ways of explaining certain. patterns as well. I think Bruce is amazing. He's amazing at explaining, simplifying complex things. He's amazing at that. And CRC is an example of that. So check out Groxio and check out CRC if you're new to Elixir, trying to find ways to abstract the learnings into digestible, catchy phrases.
Sascha_Wolf:
I'm actually curious on what something you, the both of you just cut on a like with upgrade to Phoenix 1.7 because the application we're currently building doesn't yet have a lot of API surface. So we haven't done that update yet. And just because there was not yet a really big need to, and the other applications, which are delivering business value, those don't really get touched anymore unless it's absolutely necessary, so you probably won't be updating those two Phoenix 1.7. And so. For everybody who's listening to this and maybe also in an Alexia job and they haven't done that upgrade yet, what is maybe something, because you just said one day it was fast, right? So what is something you've fairly took away from that, like some pitfalls or some annoyances? And maybe also then, what's nice about the 1.7 Phoenix and beyond?
Adi_Iyengar:
I guess for me, I think making components more universal, easier to use across all HTML was
Sascha_Wolf:
Mm-hmm.
Adi_Iyengar:
great. Something I actually really rely on, because we had a lot of dynamically generated links where part of the route was static, I wanted to make sure the route is working compile time. And that sigil-p thing. that they added compile
Sascha_Wolf:
Mm-hmm.
Adi_Iyengar:
time verification of route. That was huge. That was huge for upgrading. Again, I advise all startups. I literally helped upgrade all the applications to 1.7. So that caught actually a few errors as well that we didn't even know in code existed. So that was actually a pleasant experience. But there was no way it took a day for application. It took a lot longer.
Sascha_Wolf:
So what was so difficult about it?
Adi_Iyengar:
I think it's just tedious. It's not simple to extract, to change your views and extract functions, the view functions to components or other versions of helpers that you might want. It might also not always make sense to extract certain view functions to components. So you're making sure what really makes sense, where to define certain functions. And I think it also forced me to rethink what things should be components and what things should not be. So I think I probably took the longer approach to upgrading. I could have probably done it faster. But I was thinking that as an opportunity to learn. So I think that was huge. And also, making it a point to use the Sigil P also took a lot of
Sascha_Wolf:
Mm-hmm.
Adi_Iyengar:
time. It's not always straightforward to know where to use it. But again, we got advantages of using it.
Sascha_Wolf:
Is that also your experience, Adam?
Allen_Wyma:
Yeah, I mean, I basically am trying to keep up with the latest style, with what they're promoting. And yeah, definitely the Sigil P thing was a little bit painful. And sometimes I was like, well, what is my, what is the, what do you call that? Well, actually I kind of still like the path style more because you can still change the route and it won't matter. I mean, the only thing that Sigil P does is make sure that you have a proper path, right? So if you do change it, then you still have to go back and change all the Sigil P's. So I feel like. It's a little bit of a loss to have it. But I'm trying to keep an open mindset. I mean, the good thing is that you don't need to have a con. You don't need to have a socket. You don't need to have endpoint to make these things work. So I think that's a win. But it did take me a little bit of time to figure out how to do the full path URL. Do you know how to do that one actually? There's
Adi_Iyengar:
Yeah, the
Allen_Wyma:
a
Adi_Iyengar:
URL
Allen_Wyma:
URL
Adi_Iyengar:
function,
Allen_Wyma:
function.
Adi_Iyengar:
right? URL
Allen_Wyma:
Yeah,
Adi_Iyengar:
function,
Allen_Wyma:
yeah,
Adi_Iyengar:
yep.
Allen_Wyma:
it took me some time to figure that part out too.
Adi_Iyengar:
I think they had, they might have added it later, but they had it in the
Allen_Wyma:
Yeah.
Adi_Iyengar:
upgrade notes, I think. But yeah,
Allen_Wyma:
Oh, did they?
Adi_Iyengar:
it's easy to glance over it.
Allen_Wyma:
But I went looking in the docs. I couldn't find it. And I was like, I guess this is it. And then I have a test for that. And it worked out. So I was like, OK, cool. So I was a little bit surprised. I feel like maybe it's a little bit of a loss. I understand that you want to write that. And that makes sense. And I had this problem with other developers who were working on Phoenix code with me. And I was like, no, no, you got to do mixphoenix.phx. routes and you can see everything or you can just kind of guess it based on the name and the way things are named. So I feel like it's a win for beginners, but for the part that if you do change the route name in the router, that could cause quite a lot of changes you had to go back and make. But it's gonna, you know, you'll catch it right when you go to compile the app, I believe. So don't know. How do you feel?
Sascha_Wolf:
Yeah, I get what you're saying, but I also think, I mean, how often do you really change the route? Except for maybe the initial development phase. I guess it also depends on like if it's like a war for an HTML web application, yeah, then that might happen more regularly, right? But if it's like an API, I hope you don't change it too often. So,
Adi_Iyengar:
Well,
Sascha_Wolf:
yeah.
Adi_Iyengar:
I think references to routes is what he's talking about, right? Not really changing the routes, but if you, but I guess that might come from changing the routes too. I think for us, it really, I think the dynamic thing really, any links that are being generated dynamically, but the route itself is not dynamic, because we hide a lot of, how I write sidebars is like I have a way to do it, and I hide and show links based on what's there, right? There's a configuration, and that configuration, being correct is very important. And just getting a compile time warning is this, oh man, it was huge. It was huge. Because if you're building a complex application where your side many changes based on what page you're in, there's like hundreds of links.
Sascha_Wolf:
Mm-hmm.
Adi_Iyengar:
And I think two or three of them were wrong. And they were pretty important. So I don't know how the product was functioning without that. But at least it's got it.
Sascha_Wolf:
That's nice. That's nice. That sounds also very useful. Like I said, we haven't done that particular upgrade yet, so I'm curious to see how it goes. Should be relatively straightforward at our application at this point, because like I said, we don't have a lot of API surface.
Adi_Iyengar:
Yeah. One thing I used just the other day was first time was Live View Stream. Alan, have you tried that? So if your UI, you have a lot of components in the UI, you can stream updates as well without necessarily, you know, like if one handle info of your Live View is giving a lot of updates, or mount is giving a lot of updates, you can stream and let the page build. progressively. And that was very important in one of the applications. Actually, I can talk about it. It's like a real commercial application where they run like the clients can run thousands of simulations a second based on they can change, you know, oh, I want to change this property to have more square footage or whatever, right? They want to run a simulation
Sascha_Wolf:
Mm-hmm.
Adi_Iyengar:
and see profit and loss. And one click runs thousands of simulations. And Yes, the submissions on fast, but the data is a lot to load an HTML. It's nice to stream it and it works so good. Um, I, yeah, it must've been a lot of work to implement that.
Allen_Wyma:
Yeah, I did see that in the docs, but I haven't tried it yet. It's PhoenixLiveViewStream, right?
Adi_Iyengar:
Yeah. I literally just tried it yesterday, April 19.
Allen_Wyma:
Yeah, that's a brand new feature, I think. Yeah, I'm also starting to wonder when is Phoenix Live View going to be 1.0 at this point? It's been there's quite a lot of changes that keep coming, right? So I can see it never ever reaching that point.
Adi_Iyengar:
Yeah, I wonder that too. Is it JS? JS is not part of Live View, right? Or is
Sascha_Wolf:
It
Adi_Iyengar:
it
Sascha_Wolf:
is,
Adi_Iyengar:
part of?
Sascha_Wolf:
it is.
Adi_Iyengar:
It is.
Sascha_Wolf:
There is the browser side part which connects to the Phoenix socket and then that's all the live view shenanigans.
Adi_Iyengar:
Oh no no, I mean the JS module. They're trying to make the, like, they're trying to basically not make it so that we don't need alpine, right, all the JS dot functions. Is that part of LiveView or is that a separate package? I think if it is part of LiveView, that might be kind of like holding 1.0. They probably imagine LiveView to be like, oh, whatever CSS you want, we don't want petalstack marriage. You know, it should be self-sufficient. Minimum Java support. More, uh, I don't know. In it functions is something they could do like with X in it. Alpine like functions. I think once maybe they have all the high level Alpine function. I think then JS might be ready. And maybe then that's where live view might be 1.0.
Allen_Wyma:
a good hypothesis. I'm not too sure what what's going on. I still feel like they're they keep adding more functions. And also I'm starting to see a little bit more coupling than anything else. I don't know about you. But like, it seems like you can't do a lot of just like what they call the other dead the dead views, right so much. They seem to
Adi_Iyengar:
Yeah.
Allen_Wyma:
be steering away from that, which, which is, I'm open to that. But I'm just a little bit surprised because like the whole It's not even part of Phoenix template. It's a different one, right? It's all part of Live View, the HEEX stuff.
Adi_Iyengar:
they moved it to feelings but I might be remembering it wrong.
Allen_Wyma:
No, I don't. Maybe if something's changed, but that's not what I've seen. So I do like the HIC stuff. It is quite nice that you can get the compile time stuff, which is nice. But
Adi_Iyengar:
Yeah.
Allen_Wyma:
yeah, I mean. I don't know. I'm still and I'm still trying to work my way around these the new style we use to use, you know, whatever colon HTML. I like the new kind of view thing. I didn't know what those things are even called actually, did they have a name for those? They're not called views anymore, right? You know, you're looking a little bit confused. Do you know what I mean? So when you migrate an app from when Phoenix 1.6 to 1.7, Phoenix View has now been removed by default. Of course, you can add it back in. I removed a few to try to get back to the way Phoenix 1.7 stuff works
Adi_Iyengar:
Mm-hmm.
Allen_Wyma:
so that way I can be familiar with it. But now you move everything into controllers, which to me seems a little bit confusing.
Adi_Iyengar:
Right, I think they call them function components.
Allen_Wyma:
Is that what they call them now? Okay.
Adi_Iyengar:
Yeah, because
Allen_Wyma:
I don't know what to call it.
Adi_Iyengar:
yeah, unified function components. I think
Allen_Wyma:
Okay.
Adi_Iyengar:
that I mean both so you can like put them in controllers and call embed, right?
Allen_Wyma:
Well, I like the fact that we're kind of like back to I think you did Ruby on Rails before right? So do you remember Ruby on Rails where you can kind of say oh the format is JSON do this format is HTML do this. I feel like that's what we're kind of going back to which is interesting. You know what I mean? Because like you could say okay. you know, render this and then depending on the format, it'll choose JSON or HTML, which it seems like to be what we have now.
Adi_Iyengar:
RAIN.
Allen_Wyma:
I kind of like that style, to be honest. But this
Adi_Iyengar:
But I thought that was always there, depending on the.
Allen_Wyma:
I haven't seen it so clear before if that's what they had before.
Adi_Iyengar:
Because he
Allen_Wyma:
You
Adi_Iyengar:
would
Allen_Wyma:
still have two different pipelines, right?
Adi_Iyengar:
Oh, I see you're saying, so you put both in the same function.
Allen_Wyma:
I think you can.
Adi_Iyengar:
Okay, got it.
Allen_Wyma:
Maybe I'm wrong, but at least now they make the formats much more clear to me
Adi_Iyengar:
Interesting,
Allen_Wyma:
that you can
Adi_Iyengar:
I
Allen_Wyma:
have
Adi_Iyengar:
haven't
Allen_Wyma:
two.
Adi_Iyengar:
tried that yet.
Allen_Wyma:
That's what I thought I saw. Maybe I'm going crazy. I don't usually do a lot of it. Usually I use GraphQL, so I don't do a lot of the JSON API with it.
Adi_Iyengar:
So yeah, and I see what you're saying in Rails, they have like, based, you can match on format for, or the return type, HTML do this, JSON do this. Yep, I have not seen that in Phoenix set. That'd be interesting. And weird. So that's Phoenix upgrade. Sasha, what is new with known?
Sascha_Wolf:
Okay, I think it's... Is it using the right microphone at the right... Yeah, it's using everything, okay. Maybe just ask your question again at the end, and then we go from there, and then we... Wait, what is the time thingy? It's top right, can you tell me the time?
Allen_Wyma:
21... 20 now.
Sascha_Wolf:
2120 where's the chat? There's the chat. 21... Cut stuff out, technical difficulties, okay.
Adi_Iyengar:
Awesome, so
Sascha_Wolf:
F.
Adi_Iyengar:
that was a Phoenix upgrade related stuff. That's what Alan's been up to. Sasha, what has been up in Sasha World?
Sascha_Wolf:
Um, I mean, I've hinted at it a few times ago in the past, but, um, me transitioning to more of a, like a management position or some things that meet no, no red code anymore, or at least a whole lot less code. Uh, so depending on how long this will go on, I might at some point drop out of his podcast and make room for somebody who actually writes Elixir for a living. You know? Um, but what I've been very much involved in. is like architectural work and all discovery work. And also I've been dabbling a little bit with building and Discord bot, like on my personal side. And that is like, honestly, the last point in time where I've been writing some Elixir. And the thing there was, I'm not sure how applicable this is for everybody else listening, but I wanted to, basically I wanted to have like a system where the internal logic of the bot was not specifically tailored to being used by Discord, but honestly, at that point, any kind of chat application would have worked. What I wanted to do was apply a principle called imperative shell and functional core so that the core business logic of the bot was like, okay, a
Adi_Iyengar:
I've
Sascha_Wolf:
message
Adi_Iyengar:
heard of
Sascha_Wolf:
comes
Adi_Iyengar:
it.
Sascha_Wolf:
in. I wonder where, Adi! We talked about it before recording. But the idea kind of was, maybe I can give you just a little bit of what I wanted to build. So I wanted to build a lightweight application managing bot. Because I'm part of a Discord server on the moderation team where we screen people before joining for a few things. we are using like a weird mixture of multiple bots to kind of make that work. And it does the job, but it's a bit annoying, honestly. So I was thinking, hey, this is like, maybe like of a scope small enough. I always wanted to devil with this code, bots, why don't put this, right? So I was thinking, okay, like when a message comes in or like when a user presses a button, that's like when I kind of want to start an application. And then like the bot should be able to say, ask a few questions and like wait for the person to respond. And when they respond, ask the next question. And then after all the questions have been answered, ping somebody, hey, this application is kind of ready to be reviewed and to be followed up, right? That is kind of the gist of things. And the idea I had was, okay, honestly, in Discord land, all of those are threads and messages, of course, and buttons, blah, blah, blah. But like the core business logic is about, hey, I have an application, I want to open an application, I want to get a message, I get an answer, I want to send the next question. And that is where things got a bit weird and where I also went fully into bike shedding and I just built the weirdest possible things. It was fun, but it was not productive at all. Because I was like, okay, how do I encapsulate this? Okay, like a message comes in and now I kind of want to give it back the intent to open an application, which means to open a thread. But of course, like... I have then to wait for the thread to be opened before being able to send the first message. And then I start to talk to you, like how do I do this like in a gen stage pipeline? Because the library I was using was basically a gen stage pipeline for the whole, for all of the discord messages. And then like you end up, okay, now I need to kind of look at ordering because I mean, I don't want to do, like send the message first and then open the thread. That doesn't make any sense. Like how do I encapsulate all of this in like in a way that makes sense? And I'm sure there are good answers to that. Just that was the point where I was like, you know what, I'm just gonna read a book. I'm not going to do this right now. Then I never return to it. But yeah, that is what's been going on in Sashalan. I really found it frustrating, honestly, that there is no library out there, no thing which, I don't know, like the dust is... Maybe I'm weird, but maybe there's this whole, I want to transport events through my system and I want to have some ordering and I want to have certain guarantees, but there's nothing out there which offers that out of the box. Either it's something like GenState, which is very much tailored. And I mean, GenState is amazing, right? But it's very much tailored for high throughput and so on and so forth. And it doesn't... drops a few things like ordering. I could specifically say in the documentation, ordering something you need to take care of yourself. And I find it so frustrating that like these simpler things are not readily available. This for example, there's a library called EventBuzz, which is also like very popular on Hex, like it has a whole bunch of downloads, it has a whole bunch of stars on GitHub, but literally in the readme it says like, this is not really production ready. And I was like, okay, I guess I look elsewhere. And like, I don't know. I want, basically what I would love to see is like something like commanded, which is like cut up into more smaller parts where I can then pick and choose, where I can say, hey, this projection thing over there based on some events which are persisted, that sounds useful, give me just that. I don't want all of the commands stuff, that's too complicated for my use case. But there isn't, there just isn't. And I mean, at that point you're like asking yourself, maybe I should build it myself. But I mean, I came from this from, hey, I want to build a Discord bot for this Discord server. And now I'm talking about, hey, maybe I should build a smaller subset of Commanded, right? So I don't know. Yeah, I don't know. I mean, Adi, you said before, before I started rambling on the audio outside that like, application you've been working on, you also were frustrated at like some of the things that were imposed on top of you because of libraries. In this case, I think it was commanded.
Adi_Iyengar:
Yeah, yeah, yeah. Again, I think I do want to put a good disclaimer. It's an awesome library. And
Sascha_Wolf:
It
Adi_Iyengar:
great,
Sascha_Wolf:
is amazing, seriously.
Adi_Iyengar:
yeah. I mean, thanks to everyone who has built it, contributed, maintaining it. By no means, this is like a diss to them. No library is perfect, right? And this is where I think it is great if you want to build a simple application. completely even. So don't not think too much about it. It gives you everything out of the box. And I think that's what their kind of like customer segment, primary customer segment is, right? It's targeted towards those people. Now, where my current company is, we are operating at, I think, the most, the highest scale any Elixir application in production is operating on. No one is processing this many. events for like a better word per second every day consistently. I can guarantee that. And I think at that level, if everything is even source, the way commander enforces it, it just creates a lot of latency, a lot of bottleneck and you know unnecessary database transactions that you know, you know, might not be needed. So that's what some flexibility some more explicit Like some they are similar separating projections, you know, being able to just do simple projections through a subset of streams that come in. I'm not even called event, whatever, right? Some messages that come in, do simple projections by itself would be great, right? Instead of having to, yeah, instead of having to even source all of your data. that rely on each other. And anyway, it just creates a lot of unnecessary overhead to manage, especially when you get to a scale. And also when your application gets complex, right? When you need to add more data types, more relations to your schema, it unnecessarily complicates, you know, adding associations and stuff. And you have to find weird ways of dealing with potential lag and increased latency there. So, yeah. That's pretty much it. I did like where you were going with the whole simple way of managing producer consumer thing, like Genstage, Sasha. I'm a huge fan of that. The ordering, add a bottleneck. Add a couple of Gen service to manage ordering. I'm a fan of that. If you want to just process things, produce and consume things, and maintain order, use a gem server. If it's too slow, scale it and do a leader selection, right? Which is a lot simpler than commanding.
Sascha_Wolf:
Yeah, but it's at that point again, like I have to do all that and that is
Adi_Iyengar:
Yep.
Sascha_Wolf:
I'm not I mean, I'm rent I was just like, complaining on like a very high level, you know, because all of these libraries are doing amazing and they created what they are what they want to do what they're supposed to do. I just I feel there is a gap in like And the tools we have in Elixir, which are between this, hey, this is like super cool for like if you're high performance, right? Like you need to have a high throughput and use this. Obviously it takes away a lot of the complexity for doing specific things. And then there's like the other way, like, okay, do everything yourself with GenService, which are also, I mean, like we've talked a whole bunch on this show about how powerful the tools are, OTP provides you. But I feel there's a gap between that, where it's like this thing does. this library does this thing, this thing only in a robust way. And like, and you can use it in ways you decide, you know, um, because I think what you just talked about, Adi and where I'm on your page, um, is I also used command at the whole lot. And when, in the right scenario, it's an amazing tool, which takes a lot of work off your hands, but it's a, it's, I think the main issue I'm sometimes having with it, it's like, it's a framework like you. It dictates what kind of code you have to write and which way and then you plug that into the framework, right? And there's no, at least I don't know, no way to break out of it. And what I would love to see is like just having more of a collection of libraries like the Unix kind of approach, like a small things which do one thing well. And I feel like that is like where the gap kind of exists where it's like, hey, like I said, I don't want to be fully event sourced, but I want a thing which like which takes events from my database and puts them to subscribers and consumers and like allows me to do subs, uh, uh, projections easily, right? And basically what Command does, but only that, please only that. And then I want to think which, which like, for example, the whole, like what I love about Command, it is like how it manages the whole life, the whole life cycle of aggregates. Like it, it loads them from a database, it applies them. Then it, it just get this module in this, in this, uh, Let's just get this module and do your thing, return some things, and that's all managed inside of a process. Give me that, but only that, right? I don't know. That is where I feel the ecosystem maybe is not quite big enough yet to have libraries which fill out these smaller niches in a robust way. Because as I mentioned earlier, there is this Event Bus library, which is also super popular, and I'm pretty sure it is being used in production, but the author literally says in the readme, in big bold text, this is not production really. And yeah. Just frustrating
Adi_Iyengar:
Yep.
Sascha_Wolf:
sometimes.
Adi_Iyengar:
Yeah. I mean, I would be very curious to try Broadway with simple process groups for ordering. That's the only problem with Broadway,
Sascha_Wolf:
Mm.
Adi_Iyengar:
with event stuff. Aggregates will be hard. You'll probably write all the messages in a different store. But I think that's the only thing that Broadway is missing, aggregates and ordering, that you can get from Command. If you're going the simple, even source route. So I have used a little bit of PG2 module in Erlang to make sure all the distributed
Sascha_Wolf:
Mm-hmm. Mm-hmm.
Adi_Iyengar:
process, the order is maintained. I would be interested in trying that out. Yeah, Sasha gave you that idea, basically, today. So I appreciate that.
Sascha_Wolf:
It's also where I feel, for example, this event bus library again, I think it's a cool library, but it has what it does internally, it persists things in an ETS table. And that is where I feel there would be the opportunity to say, hey, this is just one way to persist things. By default, I offer this ETS adapter,
Adi_Iyengar:
Yeah.
Sascha_Wolf:
but you can build an adapter on your own. Give me the power, please. Sometimes I want to make the decision, hey, you know what, ETS is amazing and super fast. But for my particular use case, I just want to have to guarantee that it's persistent in a database. And yes, that can become a bottleneck, but in my specific scenario, I value the guarantee that it's safe into my database before it's delivered to my subscribers higher than the bottleneck I create. Let me make that choice, for fuck's sake.
Adi_Iyengar:
Yeah.
Sascha_Wolf:
But the alternative as well, I build it completely on my own. Maybe I use a registry, push things out. But then again, it's all on me. Like, ah, ah. And the same here, what do you say now with PG2? If you ever end up building something like that, Adi, give me the choice to say, I don't need PG2 here. Just
Adi_Iyengar:
Right, right,
Sascha_Wolf:
push it
Adi_Iyengar:
right,
Sascha_Wolf:
to this
Adi_Iyengar:
right.
Sascha_Wolf:
one process,
Adi_Iyengar:
You can
Sascha_Wolf:
please,
Adi_Iyengar:
use it
Sascha_Wolf:
right?
Adi_Iyengar:
on, yeah. It is having built and maintained an open source library for four years. It is very hard to make things extendable. And the whole adapter pattern makes sense at surface level. Just a lot more effort on the maintainer to keep that up. And I think that's so I totally sympathize with what they're saying, but I also sympathize with. people who create Command It and EventBest. But
Sascha_Wolf:
Yeah,
Adi_Iyengar:
I think
Sascha_Wolf:
I
Adi_Iyengar:
that's
Sascha_Wolf:
get
Adi_Iyengar:
where
Sascha_Wolf:
it.
Adi_Iyengar:
I think we need to create that demand for them, where it is worth it for them to do that, right?
Sascha_Wolf:
Yeah.
Adi_Iyengar:
There should be enough people and that all comes from, you know, they create, and what you said earlier, Sasha, like user base, right? What kind of people, who is using Command It? What are they using it for? Companies that have an alternative, have enough funds to, you know, build their own Command It.
Sascha_Wolf:
Yeah.
Adi_Iyengar:
Are they the ones generally? who are wanting this or smaller companies are wanting this journey. That's where, you know, contributing more to open source even by creating issues and up voting down voting things that if someone wants X feature up voted, that's also contribution to open source, you are saying that this is needed in the community.
Sascha_Wolf:
Yeah, yeah. I mean, honestly, I'm not really in a position to complain. I have actually computed, contributed to Comilite a few times. But the thing I just talked about, I could have also articulated and put into writing and opened an issue, right? Never done that. So who am I to complain right now? But just from really the naive engineer perspective, I want to build this little hobby project and I want to have this one thing, kind of what Genstage does, but it doesn't have to be this... big right, give me something smaller which does the same kind of job, let me make decisions that make sense for my particular use case, and don't... so I don't have to build all of this myself, right? And that is like where I'm like, eh, there's nothing there to fill that niche and I find it annoying. Yeah. Let's see. Maybe I actually will build it myself at some point, but it's also the area where I don't have a whole lot of experience. Like, I mean, I've worked for years now with Elixir and OTP, but like actually, like I said, with Commando, for example, that's with aggregates and processes. Like I've read through the source code and I think I grok it, but I haven't built something like that in production kind of quality. So. And the libraries I tried to build, I mean, what you just said earlier, I'm already with like open source libraries and allowing people to change and like plug things in, the libraries I tried to build are always super small because then I, first of all, I can finish them quickly. And second of all, there's just not much need for like extensibility at that point in time.
Adi_Iyengar:
Yeah.
Sascha_Wolf:
You just don't never need to cross that bridge. Alan, what about you? Like, what is, is there something like, like that's, like, does its story resonate with you? Does its frustration resonate with you?
Allen_Wyma:
I'm frustrated all the time. So
Sascha_Wolf:
Hahaha!
Allen_Wyma:
nearly every frustration bugs me. I mean, I was frustrated to have a conversation with a developer today about how testing has no benefit until later. I'm like, Really? Serious? You know how many times like I've avoided debugging code because I had tested code already. He's like, No, it's not true. I'm like, I've been doing this for nine years. You've been doing this for like one year. So I don't understand where you get this idea that where did the stigma come from that testing is like gonna like I understand like it takes time to write code to write test code. But at the same time, I feel like we save time and we have better designs once we have a test a beat right? I mean, how do you still have this conversation with with your developers?
Adi_Iyengar:
Yeah, I mean, as someone who tries to have 100% code coverage, everything. Yeah, it's always a struggle, always a push, right? I think it comes down to, I think Louis Pilfold, when we had him, right, the creative gleam, he said he is a huge fan of static checks. He's a huge fan of, you know, before running, deploying, building, whatever you want to call it, your application, if you can do checks, he's a fan of it. And typing is like the epitome of that. But testing is like the first layer of that, right? So like whatever you can add to your unit tests, your, yeah, any kind of checks, I think the better it is because other than, if you don't have that, you're relying on the ability of humans and humans make errors. And as a human who makes a lot of errors, I like, that's why I like. adding more tests and static checks. So I can feel, I am first of all, very pleasantly surprised, Alan, that you're frustrated about test coverage and stuff, because you're the ones, we used to, we used to butt heads kind of a bit on test coverage. So very happy to hear this, and I can totally feel that frustration.
Allen_Wyma:
Well, I don't strive for 100% test coverage. But I mean, like at least the logic, like testing the UI, I think, is negotiable to a certain extent. But testing, like working with APIs, especially if we're working with a financial client, it's got to send trades. And then number one thing is it has to be reliable. Like that, to me, is super important. And they're like, OK, well, the UI keeps changing. It's like, well, then don't test the UI. Just test. the logic code that talks
Adi_Iyengar:
Right.
Allen_Wyma:
to the API, at least, and you know you're handling
Adi_Iyengar:
Yeah,
Allen_Wyma:
everything properly. Because
Adi_Iyengar:
totally.
Allen_Wyma:
that's the one thing we've got to make sure we have. But yeah, I
Adi_Iyengar:
100%
Allen_Wyma:
mean, with language like Elixir, yeah, you don't really have the type checking necessarily, right? Because APIs can return all kinds of crazy shit. Like I've had weird API give me like UAT working, and then production not working for the same damn API call. And I tell them, and I say, really? Yeah, really. Oh. That's weird. We gotta check that out. Like, what are you... I don't know what to do with these guys.
Adi_Iyengar:
Yeah.
Allen_Wyma:
Yeah, I don't know how to handle stuff like that. That's one I'm still kind of debating with people about is the testing part.
Adi_Iyengar:
Yeah,
Allen_Wyma:
Yeah,
Adi_Iyengar:
I think it's-
Allen_Wyma:
and test coverage is another right? Sorry, this is something else that kind of came up in the same realm. So we're running the mix test cover and the default is 90%, which I think is already quite relatively low, right? So what I found in my in one of the teams I'm in is that they tend to try to keep the mix test coverage at 90%, rather than going above and beyond. So they use that 90% as like just to pass, you know, And I've had like product managers talk to me, hey, can we just like, let this one slide because we had to get this feature on. I'm like, really? They didn't even test the feature with any code. They just test it locally. And you want me to let this one slide? Like, you know, that you're starting, um, like that snowball effect, right? It's just going to get worse and worse.
Adi_Iyengar:
Totally. Yeah, dude, I totally agree. I think test coverage, as an advocate of test coverage for last few years, it's very, very hard. And this is where I think it's also, like I think great opportunity to grow as a senior engineering leader where you are trying to convince other stakeholders, right? Of why it's important and finding like middle ground. Like that's what that negotiation about, right? So I think number one thing that I try to do is go for 100% code coverage, but explicitly ignore things that are not tested. In that way, I think I've mentioned this multiple times in the podcast if people might be sick of me saying this, but in that way, if you have 90% code coverage, that means you push 10 new lines and you don't have one of those tested, it will still pass. But if you have 100% code coverage and explicitly ignore things and you push 10 new lines, all those 10 have to be tested, or you have to explicitly ignore. those lines, right? So that's the first thing. You're like, oh, you don't have to test everything. Let's explicitly ignore things. And if you find something that you cannot test, let's put that in ignore. And now the PMs come in. And having voted a startup that maintained how it was in CodeCurrents, I totally like literally, oh, we need this yesterday. We don't want to find a way to test it. OK, I'm going to do a little self-promotion too. I built this very small tool called Coveralls, Utils. I thought I'd add more features to it. But one of the features that it has, it has a magic comment that you can add coveralls ignore and add a due date to it. It's like, OK, we have this release going on today. In two months, we have a feeling that things will get better. So after two months, this ignore comment will be ignored by the CI, and the CI will break. So finding ways to add. You know. I think CI is the, if you find a way for your CI to break, that's the best thing, right? So like, okay, let's not test this right now, but I want to test it later. Let's make sure the CI breaks later. So I think that's like the compromise I try to find, but it is still a huge uphill battle being an advocate of test coverage, especially in a bigger team where you're not the head of engineering like I am right now. A lot of my coworkers, I think we are still not ready for 100% code coverage. I think a lot of them individually in their projects do strive for 100% code coverage, which is awesome. But I think we have ways to go for 100% code coverage. And we also have real world problems. The app is already built. It would take a lot of effort to find what files to ignore and set up coveralls and all that stuff. So I get all that, but it is frustrating.
Sascha_Wolf:
I have thoughts on that, but it's like this leaves the realm of what are we doing there today. Because something I've been thinking a lot about recently, and I think I also mentioned that a while ago, is that what we do when we build software is we optimize for success. Right? Like we try to make the thing work most of the time. And what you actually want to do, I feel, when you have a CI system is you want to optimize for failure. What I mean by that, I mean that success ought to be a byproduct of like your CI pipeline. So what you just laid out, for example, when it fails, in the best possible CI scenario, I would actually maybe expect that. this thing generates some warnings before that, right? Like,
Adi_Iyengar:
Yeah.
Sascha_Wolf:
hey, this due date is getting there. And those warnings are not just in the logs of your CI pipeline, which nobody fucking reads, but they actually maybe get commented on like your pull request, right? Like they get visible. A really amazing CI pipeline would give me all the information I need to fix the problem at hand without even having to look at the logs in the first place. And that is what I mean when I say optimize. failure. You know, like you optimize the failure scenarios and you make it as easy as possible to glean the relevant information from the failure. because honestly, I mean, I totally get why you're saying it's like a due date, but if that just rolls around with nobody, like everybody kind of forgot about it, right? And then the date comes around and I'm the ass head who knows to build the test because well, it's not only my poll request, which broke because of this due date being reached. I would be annoyed. I would honestly be annoyed.
Adi_Iyengar:
Well, put that in a separate periodic CI trigger.
Sascha_Wolf:
Okay, yeah, then fair enough. Fair enough. That makes sense. And I guess that that kind of goes into the direction of optimize for failure, right? Like where you where you catch those things in a separate system, like where you have to monitor the visible. Yeah, I but I feel the CI tools of today are not built with this idea in mind, like to make it easy to optimize for failure. Like, for example, like when a CI when a test case breaks, I still need to click on the thing, go to the log, see what broke the test cases. I mean, I can build things then to maybe put that into a comment on my GitHub issue, but it's not like the assumed thing you want to do. You know what I'm saying? Yeah.
Adi_Iyengar:
I mean, GitHub actions is pretty good. See
Sascha_Wolf:
Yeah,
Adi_Iyengar:
you,
Sascha_Wolf:
but
Adi_Iyengar:
Zad.
Sascha_Wolf:
even there, like I say, I run this test case and when the exit code is like, right, like it's an error exit code, and then I stop the execution there, but there's no easy way to be saying, hey, the output from this, like maybe, maybe take that and put it into a GitHub comment. I have to explicitly do that. I have to code that up and it's not the...
Adi_Iyengar:
It's a simple GitHub action to do that.
Sascha_Wolf:
Yeah, but I have to do it myself. It's not like they were, where...
Adi_Iyengar:
free lines.
Sascha_Wolf:
Yeah,
Adi_Iyengar:
But
Sascha_Wolf:
still.
Adi_Iyengar:
yeah, you're right. Yeah.
Sascha_Wolf:
I would love it if like... Like I see, I too came around the corner, which just says, sure, you can do that, right? Like, you can just run it and exit code and then look at the logs. But we also offer you like a thing to say, hey, run this command and like when it fails, grab something out of the output and make it to me available immediately. Like, come with this out of a box and offer me that. You know what I'm saying, right?
Adi_Iyengar:
Yeah, I think they probably hesitate to do that, because I think many teams might not want every CI build to add a bunch of comments to their GitHub pull request. And they might be, I don't know, they probably don't want to be intrusive. But I totally see what you're saying. I think one thing I really like what you said, Sasha, I think optimizing CI have a failure. And it being tied to the success of your product or your application. I think it's so important to understand that and so important that people learn as engineers, learn to update CI, feel comfortable to go into
Sascha_Wolf:
Mm-hmm.
Adi_Iyengar:
your CI configuration files, make changes, because it is more on the engineering side. People think of CI as like more DevOps-y or whatever. No, it's closer to the application side, closer to the application development side. because you know what things can break, not just from a unit test perspective, but from an application perspective, before even a Docker image is built. You know best. So yeah, super important. Like I made an effort, I think, I want to say 2018, I was being mentored by the CTO of the company and he literally told me, hey, can you spend two days just thinking about how can you make our CI better? I was like, what do you mean? Like just we just want to make CI better. completely open-ended. And that made such a big difference to me because in that, like, oh, shoot, two days of me just thinking about this, we just made it so much better. That means I should always think about it. Whenever a CI is running, I'm
Sascha_Wolf:
Yeah,
Adi_Iyengar:
like, hmm,
Sascha_Wolf:
yeah.
Adi_Iyengar:
what else can I do? Just spend five minutes thinking about that. And the more you tinker with CI configurations, the more you internalize how CI works and more ideas you'll have as you code and make things. So it's very important, I think, as an early mid-level engineer before you get mid-mid-level. Be comfortable changing the CI.
Sascha_Wolf:
Yeah, I agree. And I mean, I found it interesting what you just said, that they potentially didn't do that because people might have found it to be intrusive. Then I would ask, why is it intrusive though? And the answer to that is probably, oh, because then it posts a bunch of warnings every time. Like in my podcast, I was like, exactly. Right? I mean, if you had that from the get go without much effort, and that is, I think, the point I'm trying to make. If it's not much effort to do it, then more people are going to do it. And then if you, for example, in an application do it right off the door, well, you never accumulate 500 warnings because it is annoying. And those warnings are there for a reason. Usually. I mean, sometimes, sometimes the timestamps, these are false positives. And that is something that should be taken into account when like building these systems to give an option to say, Hey, this warning over there, seriously, just ignore it because that's just, I don't know, a library we're using. It's outdated. We don't have a There are valid use cases where you're saying, this is a warning to be ignored. But in general, if my CI pipeline tooling would be more, for example, like the Rust compiler, which says, hey, this is exactly the error you're having because of this over here, and this is probably what you were intending to do, and just make that available to me easily without me jumping through a number of hoops, oh, boy. Sign
Adi_Iyengar:
It's there
Sascha_Wolf:
me
Adi_Iyengar:
though.
Sascha_Wolf:
up.
Adi_Iyengar:
GitHub actions does that. If in GitHub actions the last command with exit code 1 is this file, this line, it adds comment to the
Sascha_Wolf:
Okay
Adi_Iyengar:
PR. Yeah, GitHub actions does that.
Sascha_Wolf:
I was not aware then, but yeah, that goes directly in the direction I'm talking about.
Adi_Iyengar:
Yeah, it doesn't do the, obviously the ability to like, grab things, change it and like interpret things and do it automatically needs more smartness, right? But GitHub, there's a specific GitHub action that allows it to do that too. I can put links to those in the show notes.
Sascha_Wolf:
Maybe we should do that. But yeah, that is something, because it's not quite a day to day, but it's
Adi_Iyengar:
Yep.
Sascha_Wolf:
another of the frustrations I sometimes have with
Adi_Iyengar:
I
Sascha_Wolf:
this
Adi_Iyengar:
totally
Sascha_Wolf:
job.
Adi_Iyengar:
agree. I think this is why I honestly feel GitHub Action is the best CI if you're using GitHub. It's the best CI. It's the Mac iOS, Mac OSX, sorry, argument, like, you know, same hardware, same software, like same Git repository, same CI. The reason why I said GitLab was the CI was so well integrated and now GitHub Actions is kind of in the similar category.
Sascha_Wolf:
Okay. I feel like everybody of us has talked about the things that are busy at work. So.
Adi_Iyengar:
Actually, I haven't talked about it, but I've talked so much today.
Sascha_Wolf:
Hahaha
Adi_Iyengar:
I think we can probably call it. Yeah.
Sascha_Wolf:
Yeah, we can wrap it up. It's getting late for Alan. He looks
Adi_Iyengar:
I would
Sascha_Wolf:
tired.
Adi_Iyengar:
also like to do a panelist episode in the future just about database, elixir-specific database optimizations, because I've been dealing with a lot of scale lately. And I think I could not find a podcast episode about that. So it'd be a cool one to do in the future if we don't have a guest.
Sascha_Wolf:
sounds interesting to me. Okay, then let us go to pics, I guess. So, Alan, so you don't fall asleep while we record. What are your pics for this week?
Allen_Wyma:
Yeah, I just have one pick. I recently beat Alan Wake and I started up on Alan Wake American Nightmare. If you've played that one or not.
Sascha_Wolf:
I have
Allen_Wyma:
So
Sascha_Wolf:
played
Allen_Wyma:
anyway,
Sascha_Wolf:
that
Allen_Wyma:
come
Sascha_Wolf:
and
Allen_Wyma:
up. Yeah.
Sascha_Wolf:
it was not like reviews back then were like meh but I personally enjoyed it a lot.
Allen_Wyma:
Yeah, you know what, I almost thought I beat it. But then I forgot that you have to do the same three missions three times. So I did it two times. And I was like, great, I'm gonna beat this because I stayed up late last night trying to beat it just to clear out my steam catalog. And now still got one more time. The only thing is you do the same three levels three times. But at least it's not exactly the same. Like there's a little bit of a twist. But yeah, it's interesting. If you like the first analog, I think it's kind of a filler until which I think is November this year. Adi, I think you're
Sascha_Wolf:
Wait,
Allen_Wyma:
a fan
Sascha_Wolf:
there's
Allen_Wyma:
of Alan
Sascha_Wolf:
an
Allen_Wyma:
Wake.
Sascha_Wolf:
Ellenwick too? I didn't know. Holy
Allen_Wyma:
Yeah,
Sascha_Wolf:
shit.
Allen_Wyma:
yeah, I think they just talked about it in last November at least, that they're gonna release it like last year, end of last year. Adi, you know more than me. Maybe you should say, you're like, I
Adi_Iyengar:
about
Allen_Wyma:
know.
Adi_Iyengar:
this game but it is you're right it is coming out.
Allen_Wyma:
Yeah. So yeah, I mean, it's kind of cool. Like, if you haven't played it, like, the interesting thing is that you use a flashlight to kill the darkness on the people around you, and then you shoot them with a gun. So it's definitely a spin on it. It does get a little bit annoying, but at the same time, yeah, it makes things challenging, so it's kind of fun. This one, if you played the first one, but not American Nightmare, American Nightmare does more guns, more action, I would say. So. Yeah, it's okay. It's a fun twist on it. So I think it's fun to check out if you like the first one.
Sascha_Wolf:
cool. Adio, what are your picks?
Adi_Iyengar:
Yeah, I got a video game too. As I mentioned last time, now that I don't work for a startup, I'm able to play a lot of video games on top of sleeping more. So I've been going through my list, and a lot of that had Naughty Dog games. I played The Last of Us finally a couple of weeks ago. And last week, I played Uncharted The Lost Legacy. I think it came out in 2017. It's a sequel to the game. Thieves End, which was a very popular Uncharted game. But I actually preferred The Lost Legacy, honestly. I think the storytelling was a little bit more immersive. I think, again, if you're playing Uncharted, you're playing it for the story. It's very immersive. It's a great backseat gamer game, too, if you like play with, like I play with my wife and she likes to watch. So this was more fun from a story perspective. More picturesque. It was really beautiful. And it's based in India, and having grown up in India, there aren't very many games that are based in India and made so beautifully. So yeah, it was nice to see familiar territory in video games. So yeah, I would definitely pick Uncharted, The Lost Legacy. Also, as I mentioned last time, and I had a couple of people reach out to me again, which is great. But I'm looking for a couple founding engineers. and my company is still hiring, my team is still hiring one engineer. So there's at least three engineering roles that, you know, you guys can reach out to me for Elixir. Two of them are founding engineers, obviously, it would be great to have founding engineering experience, but even if you don't, reach out.
Sascha_Wolf:
I would love an opportunity to work with you at some point, Ali. Not necessarily this time around, but at some point.
Adi_Iyengar:
Oh, I would love that, man.
Sascha_Wolf:
Yeah, I have kind of two picks. One is, if there's any of you listeners out there which have kids and like to video game, and like want to know what is like a good introduction into video games with kids, there's two games I can recommend. The very first we played is A Short Hike, and that is... as the name kind of suggests, it's about a little short hike to the top of a mountain. And it's in so far amazing that it's like it's a top down game, but like a little bit of 3D ish pixel art look. But there's no combat or anything. It's really just about you walk around there, talk to people, solve little puzzles and then get to the top of a mountain. It's reading. So like we will have to be the one which reads things out to your kids, probably. And
Adi_Iyengar:
This
Sascha_Wolf:
I'm
Adi_Iyengar:
is so
Sascha_Wolf:
not.
Adi_Iyengar:
epic, this looks so cool.
Sascha_Wolf:
It's super cute, also, like it's just a very wholesome game. It was the very first game I played with my son. That is just, there's no time limit, no anything. It's really a good start. It was five back then. And the second pick, same kind of idea for the whole, what to play with kids is Mario Odyssey, actually, Super Mario Odyssey, because it has a help mode. And what the help mode does is you get like twice as much health points, like usually a three, with a health mode you have six. And instead of like... being reset when you encounter an environmental hazard, like purple sludge or whatever, or falling down. You, like a little bubble comes and puts you where you were and you lose one health point. And you can also just stand still and wait and then Mario regenerates health points. So it's really a whole lot more approachable for kids. And there's also, there's always arrows. There's always arrows pointing you to where you have to go. So... That was actually the perfect segue into more challenging games. Because Mario Odyssey, as all of you probably know, there are enemies in there and so on and so forth. But with all of his support, with his help mode, my son was still able to kind of get into it slowly. And so now we're playing from Mario Odyssey. And he's six now. My daughter, which is three, just loves to watch this. Oh, he's like, oh, this is Mario, right? So
Adi_Iyengar:
That's
Sascha_Wolf:
yeah,
Adi_Iyengar:
so cool.
Sascha_Wolf:
it's a lot of fun. So those are like two games I can recommend highly to play with kids. And my second slash third pick is a board game I just enjoyed immensely recently. It's Root Court. Probably everybody who is into board games might have heard of it. It's very popular. But it's an asymmetric war board game, which like, no, keep listening, but it's, the theme is basically you play one of... one of the factions in the forest, like one of the cats, one of the birds, the other is resistance, which are the mice and the foxes and the rabbits, and the fourth faction is just the vagabond, which is just walking around and doing random shit. And all of those factions play completely differently, completely differently. And that's kind of a charm of it, because it's still very much balanced. There's not really one faction which is that much stronger than the others. They're all being able to manage. but still everybody plays their own little game on the same board trying to vie for control. And that's just a very fun time. So if you're into board games, also maybe a bit more complex board games, because this one is not super easy to grok, then I can't even recommend a root enough. And secondly, if you're into tabletop role-playing games, there's even a root tabletop role-playing game, which plays in the same universe. It's a Powerpuff the Apocalypse game, if that tells you anything. And the coolest thing about it, what I love is, They suggest that when you start a round of like a tabletop role-playing game, then to play a few rounds of Root before that, like two or three rounds, and you kind of jot down on which areas there were big battles, right? Like what were big conflicts and just take that as the background for the world you play in with your tabletop role-playing characters. And that's just such a neat little thing. I love it. So those are my picks this week. Very, very nerdy, I know.
Adi_Iyengar:
I just ordered root. It looks so good.
Sascha_Wolf:
Tell me how you like it. I absolutely adore it. It's a masterpiece of game design, seriously.
Adi_Iyengar:
Yeah, it looks awesome. The design looks awesome.
Sascha_Wolf:
I mean, it looks awesome, but like really the game design, like how these factions, they really feel distinct.
Adi_Iyengar:
I'm talking about.
Sascha_Wolf:
Yeah, it's
Adi_Iyengar:
The
Sascha_Wolf:
amazing.
Adi_Iyengar:
game design seems awesome.
Sascha_Wolf:
And there are a whole bunch of expansions with like new factions. I don't, from what I've been told, most of them are like up there at the same level of quality at the one of the base game. So yeah, amazing game, seriously. Yeah, those are my picks for this week.
Adi_Iyengar:
We should also make it like a regular fixture for you to pick kids friendly games, because it can also replace kids with girlfriend, wives, whatever, like it's an entry level, entry level games.
Sascha_Wolf:
Yeah, I have a few now. I've been playing with my kids. I mean, just like as a spoiler, like there's a teaser here, but really goes well on the Switch, especially there are like these hidden image, hidden objects kind of games on the Switch where like you just have to tap these little things. That just works well. And that is actually one of the things where the touch screen from the Switch is kind of nice, honestly. So yeah, that's something even my daughter, like, with three can play already. that, you know. So yeah, that works well. It's just nice because video games are something I enjoy immensely, so it's kind of nice now that I can start to share this hobby with my kids, you know.
Adi_Iyengar:
That's awesome.
Sascha_Wolf:
Okay folks, it was a lot of fun talking to you again and I'm happy to have been back after this longer break. And I hope all of you enjoyed listening to us rambling about stuff, I guess. And tune in next time when we have another episode of Elixir Mix. Bye!