Become a Creator today!Start creating today - Share your story with the world!
Start for free
00:00:00
00:00:01
#57 - Ray and Vijay welcome our first Rhyming Guest: Jeaye image

#57 - Ray and Vijay welcome our first Rhyming Guest: Jeaye

defn
Avatar
58 Plays6 years ago
Our next episode with Jeaye Wilkerson (https://jeaye.com) - a C++ programmer who turned into a Clojure programer and CTO of gaming startup.
Transcript

Playful Introductions and Humor

00:00:15
Speaker
Yeah, music. Come on, music, maestro. Which one? Dramatic piano? Yeah, definitely. Dramatic piano. We also have drums. Oh, well, that's too short though. Yeah, that's too quick. Yeah. We can have that at the end, maybe. Yeah. Well, this is good. This is good. This is good. Yeah. Yeah. Go ahead.
00:00:39
Speaker
Hey, I'm from Belgium. And my name is Ray. Oh, hey, I'm from San Francisco. And I'm Jay. Okay. Oh, fuck it. This is Vijay from the Netherlands. Cocksucker. Hello.
00:01:11
Speaker
We're a party pooper. Yeah. We've got the cocksucker motherfucker in there straight away because, you know. Yes. Yeah. I think we're going to start off hard with this one. We've gone soft for a couple of episodes, I think. Yeah. Okay. And I just put it in there because I know your mother's going to listen to this, Jay. Absolutely.
00:01:34
Speaker
That's no problem. You shouldn't have said that before. She's a grown woman. And she can form proper opinions about Vijay and Ray.

Enter 'Deaf and Episode 57' with Rhymes

00:01:47
Speaker
Yeah, we're putting all out there. We're definitely putting all out there. Yeah, of course. Okay. So welcome to Deaf and episode number 57. And this is the one, I think the first ever rhyming episode because I'm Vijay.
00:02:05
Speaker
And I'm Ray. And I'm Jay. Yeah. So VJ Ray Jay, Jay Ray VJ episode. Let's get started. Oh, I think we already started.

Musical Critique and Creative Process

00:02:19
Speaker
First of all, I think with the shitty music and our rap. Is that rap? I don't count that as a rap, to be honest, you know? It's rapping your ears in a way. Maybe it's more C rap, you know?
00:02:33
Speaker
Yeah, it's crap. There's a new genre of sounds. It's like grime, but it's shit. Look, every band, when they get started, they have some rough songs. We just need to iterate it. Yeah, I agree. I mean, there was some spirit there. I think there was something there. Yeah. Vijay, I think you could put a little more into it.
00:03:01
Speaker
I'm out of the band now already. Let's have another go at this. Come on. You're going to have a talk with me. Let's have another go. Before we make a start with the closure stuff, let's have a go at that song. Come on. And this time, mean it, Vijay. OK, come on. Ah, God.

Reattempting Introductions with Vijay

00:03:14
Speaker
OK, fine. So again, the same music. The same music. Yeah, let's do it. We're going to get made by the minute anyway. We're going to get a start at this time from the West Coast. Oh, I was going to throw Vijay. OK, no, we'll go.
00:03:29
Speaker
Because he's the one that's true. We'll go east to west, okay? We'll go east to west. Vijay, you're starting this time. Dude, if it is east to west, you should be starting because you're east to me. I live in the Netherlands. That's for the east in Belgium. Yes. Is it? Okay. Oh, fuck it. Okay, here we go.
00:03:59
Speaker
Hey, this is Vijay. My name is Ray. Okay. Well, Vijay, I think that was a much better. Yeah. So
00:04:27
Speaker
Maybe we could splice the two of those together and come up with something that's useful. I mean, that's going to be a horrible merge commit, that is. Let's be honest. Oh, that's the merge of nightmares. It really is. It's a three-way merge of horror. BJ, say something. Are you still alive after that? No.
00:04:56
Speaker
I think I took a lot out of them.

Jay's Programming Journey Begins

00:04:59
Speaker
Did it work? It worked. I don't know if it worked. The music seemed to stop, you know. Oh, okay. I don't know. Maybe this is probably like a small bit or something. Yeah, there was something weird on the DJ front there, but you know, I thought you were just cutting us off, you know. No, I think something happened with Zencaster. I think it couldn't tolerate our audience.
00:05:23
Speaker
I mean, that's a bit weird, isn't it? Because I thought we were we were approaching Zen there, you know, it was. Yeah. OK, let's you do the end. I mean, it was very, you know. J. It was good. Yeah, that was that was there was something spiritual there. Yeah. Ah. Thanks, right. Well, thank you. So I think that's all we have for this episode, I think.
00:05:54
Speaker
It's been an absolute pleasure. I mean, you know, we've achieved enlightenment. What more goes? Closure. I like how you're trying to put some sanity into this, Jay. We're like, oh, go closer. Oh, okay. Come on. We'll talk about closure later. I hope that when I achieve, I hope that when I achieve enlightenment, uh, my hair grows back and, uh, it's like niches. Um, because.
00:06:20
Speaker
Because like how can you have enlightenment without without that's true. That's true. I think that when you look at these Buddhist monks, they're probably doing the same thing. Like they're making their wishes on. Yeah. So they can have the real hair like that. That's true. And I think they're starting with a clean slate.
00:06:41
Speaker
both like physically and, and like metaphysically. No, I mean, that's the, that's the Zen story, right? I mean, you can't fill the cup when it is full. So you need to empty your cup before you go to the Zen master. So it makes sense. So you need to shave your head first and then grow back into rich hickies. Give up all your possessions that includes your hair. Right. Yeah. And also your old programming languages and ways of doing things. Absolutely. Absolutely.
00:07:08
Speaker
Yeah, so excellent transition. So let's get started. So what did you give up J in programming languages to come to closure and why? Sure, yeah, so I started with I started with just basic and I have no idea why just basic was a free version of Liberty basic. I don't know. I don't know why I used it, but it was. It was a good way to get started. I was writing like text based games.
00:07:37
Speaker
And then that went into like dark basic, cause I wanted to do like 3d games. I was just big into games. And then from there, I mean, that was like six months in or something. I was like, well, I was on mine. I was like, what do people write when they're really serious about games? You know, like they want to make like the best games. And the answer to that was C plus plus. I was like, okay. So I jumped right in to C plus plus and, uh, or the next,
00:08:04
Speaker
several years basically just did a lot of C++ and was all about it. And the thing is C++ is a massive language. People don't realize, I think, just how big C++ is. I think you have a lot of people who call themselves C++ programmers because they can write, I mean, and in some sense they are, but they can write C++ and it compiles and it runs and it does what they want.
00:08:32
Speaker
there are, I mean, they're probably using a tiny like fraction of the whole language. And I've spent several years using C++, but there are still entire parts of the static library that I've just never really even thoroughly used. So anyway. So that's pretty much similar to Rich Hickey's journey, right? Because he was also a C++ programmer and he wrote a couple of papers in C++ and libraries and whatnot.
00:08:58
Speaker
Yeah. Right. Exactly. But I am, I mean, I'm not, I'm not trying my comparisons. This is our show. Were you enamored with the standard template libraries, Jay? Right. So actually it's not the standard template library, it's the standard library.
00:09:21
Speaker
which is standard library was based on the standard template library. So people call it the STL, but it's the standard lib. STL was something that came prior and then the standard lib was built based on
00:09:33
Speaker
the STL, which is also not to be confused with STL, who's a person who actually works on, I think, Microsoft's version of the standard library. It's like this. A request from one of the cast here. What's going on? Anyway. Welcome to C++ podcast episode. Yeah, so. That's what I will say. Yeah, yeah, yes, yes, yes, it did. And anyway, I was really big into it. And I
00:10:00
Speaker
Yeah, like I think most of my GitHub repos would probably be in C++ or around C++. And I mean, I think including most of my popular, like my more popular
00:10:12
Speaker
and successful projects have all been around C++. And I was really interested in trying to squeeze, I am arriving somewhere with Closure here. I was really interested in trying to squeeze as much as I could out of the language, out of C++. Just before we go on, Ajay, just interrupt you for one second. Was this all in service of some hobby, or was this when you started work, or what was the context of this learning?
00:10:41
Speaker
Uh, yeah, yeah. So, well, when I started learning C++, I was in, I was still in high school. Right. And then.
00:10:55
Speaker
Like I was really fortunate to be, I grew up in like a really, really small town. There were 50 people in my entire graduating class. And I was fortunate to be like shipped off to another school, like on a bus, like three days a week, because it was a bigger school and they actually had an information systems technology class. And I would go there and most of the people there would like look up
00:11:21
Speaker
erection on Wikipedia and Snicker all day long. I told my teacher, I want to learn C++, I want to write games, I want to learn OpenGL. She was like, okay, do it. We will forego the whole typical curriculum of what I typically put people through if you're progressing and you're getting better. That was amazing.

Journey to San Francisco and Financial Struggles

00:11:47
Speaker
That was a really nurturing environment for me to just
00:11:52
Speaker
learn everything, fuck up in so many ways. I realized that when I look back now, the code that I was running then, this is really cool.
00:12:02
Speaker
The code that I was running then, because I didn't really understand, even though I was running C++ syntactically, I didn't really understand the control flow of functions and unwinding the stack. And so what I would do is I would get into some functions. And when I was ready to come back, I'd call main again. And so I would reenter main. And then obviously, if you reenter main, you don't want to enter a loop. So I would keep some global states that I would mutate.
00:12:31
Speaker
So that when I re-intermain, it puts me into a different path. You were writing a virtual machine. Yeah. And then every now and then the stack would blow and then you restart.
00:12:43
Speaker
and such is the engine of reality. So that was really great. And then I went to school specifically to study game development, and that was all in C++. So when I- Was there a school that did that? Oh yeah, there are a few. So this one I went to is called Full Sail University. It's in central Florida. And if you're dedicated, I think it's a great school.
00:13:13
Speaker
Um, I didn't actually finish, uh, because I was, I was doing open source work, uh, all the while and I was offered a job before I finished and was like, okay, I don't want to finish school. Um, and I probably didn't have the money to finish school anyway. Um, because it was full sales, not cheap in America and yeah, in America, exactly. So I took the job offer, which was like terrible salary, but was amazing for me. Um, but full sale was really cool because they try to.
00:13:43
Speaker
They try to make it as real life as possible in the game industry. And so you'll be in the middle of like a game project and then they'll spin a wheel of misfortune, they call it, which is like, oh, you need to, the product manager has decided that you need to add localization to your game or
00:14:05
Speaker
you need to write a development blog or something like that. Then the other thing was the school, it's open like 24-7 literally, and you have classes like eight hours a day. You'll have like four-hour lecture, four-hour lab, but there are all sorts of hours. You have like a 3 a.m. class and their idea is that
00:14:30
Speaker
You just go nonstop like this, like 24 seven for two years straight, like with no summer break basically. And you get a four year degree. Why don't you get anything like this? When you type Florida man goes to school or something like, you know, whenever you type Florida man in Google, there is nothing that shows up like this. Like people going to school at 3 AM. It's crazy. Yeah. It was, it was good. Yeah. And I, um,
00:14:56
Speaker
a buddy of mine told me about it. And he was like, yeah, I want to go here. That's, I'm certain about this. And I just sort of like hitched onto his dream. Nice. And, uh, and, uh, then, then that, that a network. Yeah. But anyway, so yeah, I got teaching you that by the way, was it, was it like, uh, was it like physics engines or was it like gameplay or design or, you know, everything? Yeah. All of the above man. So you start off with, um,
00:15:26
Speaker
We actually, like the first class, you don't actually start off with C++. You start off with Lua, which used to be scheme. But those, those suckers, they didn't want the parental, I don't know. They went, they went to Lua.
00:15:41
Speaker
And anyway, so you start off with Lua to just sort of get your feet wet with some programming. And then they jump you into C++ right away. And then you stay in C++ for the entire thing. But you start off with writing some text-based games, enter a random number between 1 and 10. Did you guess the right number sort of thing?
00:16:03
Speaker
And then you move into graphics programming, and then you have classes on multi-threading, you have classes specifically on DirectX, you have classes on how to use certain game engines, and also the 3D content pipeline for what you'll actually expect to have if you go into a game studio that's using Unreal Engine or Unity. So that way you can understand
00:16:30
Speaker
Well, how do the artists make 3D models? What are vertices? How are triangles, you know, how are triangles formed and how are models built from triangles? Like how are they unwrapped?
00:16:43
Speaker
and how do UVs map to them to texture things, how do normals work, everything like that. So you get to understand that side of things so that when you're working with the artists, you can be useful and you can understand what they're doing. Yeah. Did you get some hardware kind of stuff as well, like all the graphics cards and those kinds of things so that you could be optimizing for that kind of stuff?
00:17:12
Speaker
Sure. Uh, not really. I think it was mainly, it was mainly software oriented. Everyone, like everyone had a.
00:17:24
Speaker
a Windows laptop. I was the only one in my class that had a Linux laptop that was dual booting Windows and using Git. Everyone is just learning the program on their Windows GPU. There wasn't really anything that went super low level. It was mainly that and then just
00:17:52
Speaker
learning to work together in teams to actually ship a game, and having to deal with the issues of being assigned with random teammates. One of you has to make the animation system. You have to make it from scratch, like 3D-skeletal animation system. The other one needs to make the sprite-based... I can't think of the... Like, emission, exactly.
00:18:20
Speaker
Anyway, one of you has to do that, then the other one has to build some sort of UI system that scales properly. So it was a whole lot of that, just sort of rinse and repeat, make it more and more complicated. And now you've got networking, then you've got threading, et cetera, until you finally get to your final project, which I didn't get to.
00:18:43
Speaker
So it was a whole lot of that.

Embracing Functional Programming at Tinyco

00:18:45
Speaker
And all the while I was doing open source game engine development for the most part. I was really interested in sort of low level, make a game engine, optimize every single aspect of it, try to parallelize as much of it as possible. And I was doing that. It was all on GitHub.
00:19:06
Speaker
some recruiter found me and was like, hey, how about you come over to San Francisco and work for us in this game company. And I actually had a buddy of mine
00:19:20
Speaker
I used to hang out with, who was also at Full Sail. He went and interviewed at the same place and he came back and he didn't get the job, but he told me everything about their interview process. He said, okay, so their coding test is Conway's Game of Life. You need to be able to write that. I'm like, what is this? I don't know what Conway's Game of Life is. Then I look it up and obviously,
00:19:46
Speaker
I mean, everyone has to know that. So if you don't know what it is, and you're listening to this, go, go figure it out. But I wrote the Conway scheme of life over and over and over and over again. And I did concert versions, I did graphical versions of it. And then I went, I went to my interview. And, and I was like, all right, so what am I going to be coding today? And they're like, well, have you ever heard of Conway scheme of life? And I was like, Oh, never. I was like, well, I said,
00:20:14
Speaker
I have heard of them and they're like, okay, so we're going to have you program that. And I was like, okay. And so, and so I did it and, and I got the job. You just glided through. Yeah. Very, very well done. Very well done. I did. And, and I got the job. I lucked out actually, I think that the head of engineering was from Maine as well, which is where I was right. Um,
00:20:43
Speaker
And there are only like five or so people left in Maine, like the rest of them have gone somewhere else. But I happened to have one there who's out of engineering. And so he's like, oh, I heard you from Maine. And he's like this brilliant, brilliant guy who was asking me terrible questions or like terribly difficult questions that I know for a fact I didn't get right. But I think because I had that in, I got the job. So I was like, I had that in, and then I knew the coding tests.
00:21:12
Speaker
And because those two things lined up, I ended up getting a job. And then from there, no degree, getting paid shit, but, uh, and I had absolutely no money. Uh, like when I came out, um, I know we have arrived at closure yet, but this is, this is fine. We don't need time. Exactly. When, when I, when I came out, I had, I had no money.
00:21:36
Speaker
And they, this company that I was hired at Timeco, they put me up with someone else who was also just hired. And we, we ended up being roommates together.

Joining OK Let's Play and Tech Stack Decisions

00:21:49
Speaker
And his dad basically like gave me a loan to get, to get some, to get some like furniture and stuff. And so to be able to like pay rent, I couldn't pay anything. I had no,
00:22:05
Speaker
I had no lights in my room. I had no bed. I had the pillow and the blanket that I took from the airplane from my flight over from Maine. And I slept with that for like two weeks until I got like my first paycheck. And then at that point I got a mattress and then for the longest time I still didn't have lights in my room.
00:22:29
Speaker
Eventually I paid everyone back and started, you know, started saving some money. And then, uh, it was, it was a rough start. Dick Whittington story, you know? Yeah, it was, uh, money was available, was, was also like in full sales. I was running super low on cash.
00:22:48
Speaker
So like the whole job offer thing was so nicely timed. I had a buddy of mine from IRC I was hanging out on. I still hang out on free node several years or a decade later. But like one buddy of mine I was getting to know.
00:23:05
Speaker
sort of knew the state that I was in and would buy me like pizza, would order me pizza and ship it to my, uh, to the house that I was staying at. Cause he knew I just didn't have the money to, uh, to buy much. So yeah, I was, it was through everyone else's generosity that I was able to finally make the San Francisco and, uh, prove myself as a, as a developer. Perfect.
00:23:30
Speaker
I don't know, but anyway, I think we have peaked. I don't know where to go from here. Okay. It's all downhill from here. So well, you know, we still, we still have closure. Yes, exactly. Well, I think the good thing is that it isn't a kind of midnight cowboy story, you know, cause that would have been really, I don't even think I want to ask.
00:23:50
Speaker
Oh, Midnight Cowboy. It's Dustin Hoffman, John Voight film from the sort of 70s where, yeah, small town guy goes to the big city and it doesn't end well. Oh, okay. Ooh. Well, he's here on the podcast. Right. This worked out all right. So I stayed at Tinyco for a while and I was getting really into
00:24:15
Speaker
C++, specifically template metaprogramming. The reason was I wanted to try to squeeze as much out of the compiler as I could. The thing about template metaprogramming is, I think if you put a 100 C++ devs that you just take randomly in a room, you take them randomly from, I would say probably not even the game development industry, but probably just any industry using C++. Take 100 of them, you put them in a room. I would think that maybe five or fewer
00:24:44
Speaker
are going to be comfortable writing template metaprograms, or talking about type traits, or finnae, which is substitution failure is not an error, and the patterns that these terrible acronyms that comes out of C++ like RAII.
00:25:05
Speaker
I was getting really into that and I was like, that was my job security as well. Because I was writing C++ that nobody else in the company felt comfortable with. And there's like, oh, there's an issue with this thing. Okay, we'll need to have Jay look into it. He's doing this other thing right now. Let's add it to his queue. And honestly, that was great because that's like,
00:25:30
Speaker
You know establish myself there but i hit a point where i was trying to get more type safety i was trying to get more.
00:25:40
Speaker
just sort of safety in general. Like the reason I was doing these template metaprogramming was I wanted, I wanted the API's that I was making to be as tight, rich as possible. So that, um, so that hopefully we fuck up less because we had hundreds of thousands of lines of C++ code in just the game engine alone kind of had their own game engine.
00:26:04
Speaker
that they built in-house. And then you had like 100,000 lines of code for the games each that were built on top of that. It's a lot of code and a lot of things would go wrong. And so I was trying to do that to squeeze as much out of C++ as I could. And I was moving towards something and the C++ compiler was fighting
00:26:28
Speaker
And I didn't know what I was moving toward, but I knew ultimately that C++ wasn't going to offer it like to me. And that I, I had basically squeezed the last drips out of it that I could, and I had to look somewhere else. And so I started looking into Rust, which was super new at the time. And I did some.
00:26:49
Speaker
I made a game engine in Rust that it took Quake Live maps and Quake 3 maps, and then using separating axis theorem, it voxelized them. And then the idea was to have a Quake 3 game with voxelized destructible maps. And so I was doing all that in Rust. It was way too early in Rust, because not only was the language changing so much, literally every week,
00:27:16
Speaker
but the libraries were too as a result. It's like, okay, this one windowing library completely changed its API three times since I was working on this engine. It's the same thing for the OpenGL library and it's the same thing for this and that. Ultimately, it just really wore me down. But I think it was a good taste of something that offered more than C++ in terms of
00:27:46
Speaker
in terms of data management, in terms of the expression. So Rust has pattern matching that C++ just doesn't compete with. And I think better approaches to concurrency, both parallel and otherwise. Vijay, I know you said that you've been looking into Rust as well. So I know what I'm talking about with a lot of this.
00:28:15
Speaker
So I was looking into that, but it still wasn't a far enough departure from what I wanted, but I didn't know what I wanted. And so I just sort of started researching some work and I found out that what I wanted was functional programming.
00:28:30
Speaker
I had answers like, boom, that was added to my vocabulary. And then all of a sudden, and then all of a sudden, I realized I don't know shit. And there's so much more for me to take in. And I was I was like, all right, so I got to pick up a functional language. And we had one loony
00:28:51
Speaker
in Tiny Co. who's a really smart guy. I say loony affectionately. We had one loony who was all about Haskell. He was constantly going on about how everything we're writing in C++ was crap and they needed to be Haskell. I didn't understand really. I was just like, okay, he's a loony. Then he eventually just
00:29:15
Speaker
couldn't take it anymore. And then he left. And I think I hope for his sake, he's running Haskell these days. Or maybe he's, or maybe he's forgotten the types and he's, he's in joint closure. But, but so, so there was that guy and I was like, okay, so I know, I know Haskell and I know one loony who's into that. And I looked at that and I was just like, I can't do this. Like,
00:29:45
Speaker
I'm not good. I'm not smart enough. I'm just not good enough. I don't know. This thing's beyond. Um, and, and I was like, if this is what functional programming is, it's not for me. Um, because I need to be able to just, I just need to be able to write some fucking code and make it work. And like, I was still writing game engines. Uh, I like writing operating system kernels. I like writing kind of low level things.
00:30:10
Speaker
But I want to be able to do it in a way that is as safe as possible. Anyway, so I came across closure, and I was like, OK, all right, so this is functional. But I can just write imperative code, too. It doesn't feel, because it's not declared, or at least it doesn't have to be declared. You can just get in and say def in main print line.
00:30:38
Speaker
And that becomes really easy. And then it's like, OK, now I can just start doing some mutation if I want. And absolutely. Did you re-enter main as well? No, I did not. By then, I had broken that habit. But thanks for checking. That's a shame, actually, because I think it would have been nice. It would have been fun to do. Right. Not with closures. Not with closure stack issues.
00:31:07
Speaker
I mean, you know, you would have been, you would have got the worst, especially when spec came out, you know, one nine, you would have got like the, your, your error messages would have been like the talk of the town. Yeah. Yeah, exactly. But that's a big departure, right? Coming from C++ and then thinking about types and everything and then, you know, low level code and then switching to JVM enclosure. So I was off. Was it a culture shock? It was, it was.
00:31:37
Speaker
I don't know how I made it through because the thing is that I didn't know what I was doing. I was just like, this is a language I'm going to try to write something in and I had no idea what I was doing. And so the thing is that to make it even worse, what I had done was I hit that point with C++ and I was looking into these other languages.
00:31:59
Speaker
And I didn't find anything that I really liked. And so I had decided I'm going to make my own language. I have these ideas of what I have in my head and these things that I really don't like with these other languages. I'm going to make my own and I'm just going to address all my concerns. I don't care if other people don't like it. This is for me. And so that started several years ago.
00:32:20
Speaker
I originally wrote it in C++ and it was a nightmare to maintain and everything like that. It was fast to compile the actual code. It wasn't fast to compile the compiler, but it was a pain. As I started looking more into Closure and I progressed a bit beyond doing foreclosure challenges and asking Closure Gulf questions in the FreeNode Closure channel, it's so funny.
00:32:50
Speaker
Closure is a unique programming language because it's the only one that I've used where, and throughout the assignment, it's primarily C++, but I've used a lot of other languages as well, just for things here and there. But it's the only one I've used where if you ask a question in the FreeNote channel for that language of
00:33:13
Speaker
How do I write this? How do I do this one thing? You end up with 30 minutes of everyone in the channel contributing like different examples of how to optimize, not performance, but instead like laziness or expressiveness or something like that. And there was so much of that, but it was really helpful because I would just watch like someone be like, oh, how do I do this map?
00:33:41
Speaker
with an index, and then someone would be like, oh, use map index. And then someone else would be like, oh, use list comprehension. The other one's like, oh, use a reduce, and do it like this. The other one's like, oh, what about transducers? Or something like that. And then I'm just like, oh, I'm taking. Yeah, yeah, yeah, yeah. And then I'm taking all this in. So I was taking all this in, but I hadn't made anything useful with it. And so what I did was I rewrote the compiler for that language I was making.
00:34:10
Speaker
With closure and it was absolutely terrible. I did such a bad job But it was but it was helpful and I ended up rewriting that compiler again in closure just having learned
00:34:27
Speaker
like how to keep an AST as one big map and then how to transform that thing in place without mutation. Because compilers can absolutely just be a pipeline of data transformations. But when you come from C++, you don't think of them as objects and hierarchies and whatnot. So I just didn't have the right mindset. And anyway, so I...
00:34:54
Speaker
I had gone to Singapore for a while, I came back, and I was doing mostly C++ there, a lot of C sharp actually as well, and I came back and I went back to C++ programming, but I told myself at that point, I had been writing C++ professionally for five years or so, I told myself, this is my last C++ job.
00:35:18
Speaker
I'm going to take this job because I need a job right now. I need some income. My wife and I needed to come back from Singapore to San Francisco, and we just wanted some stability. But I said, I'm going to look for a functional programming job, and as soon as I find a good one,
00:35:38
Speaker
I'm going to leave C++ behind and I'm going to move on. For the next year, I spent time looking for the right job. Also, one thing that I was really into was educating people about C++. The thing is, I was the C++ guy that everyone went to. Even then, I still admit there are so many parts of C++ I didn't know, but still where I was working, I was a C++ guy.
00:36:07
Speaker
But ironically, I was the one telling everyone not to use C++. Let me teach you C++. OK, don't use C++. So that was the conclusion. Absolutely. And so my parting gift to them was the last talk I would give talks about metaprogramming. I would give talks about closure, actually, which wasn't taken that well, I think.
00:36:36
Speaker
I actually did Conway's game of life in enclosure and in C++, and I compared the two. And at one point, I had some object-oriented, very imperative method in C++. And then I had shown the analogous version that used a list comprehension. And this was probably a mistake, a just.
00:37:02
Speaker
And and some and some because that's it's a simple enough thing once you understand higher order functions and how it's used. But when you first see it and then you have someone like explain it to you in the context of the new language, you're like, what? And then someone asked me who's a smart guy whom I respect. He asked me like, how can
00:37:25
Speaker
How can you debug this? How is this useful? And I was like, on the contrary, I can run this shit in the REPL, man. This is pure damn. I can figure this shit out. I can unit test this. I can lock it away entirely from the side effects.
00:37:44
Speaker
I can reason about this. I don't need to debug it in the same way that I would need to debug this massive if else if block that I have in C++ that's doing some mutation. But I think it's hard to sell that argument. But it's an interesting question, isn't it? It's a very interesting question when you're kind of in that imperative mindset.
00:38:08
Speaker
You know, because you, you know, and I think to some extent there was a little bit of that enclosure as well, but we can maybe come to that a bit later. But I always think I better, I definitely felt that way when I first started learning closure as well, you know, that how do I get into these, how do I get into these pipelines to debug them? How do I get inside of them? And, you know,
00:38:28
Speaker
The penny eventually drops that you don't do that. Yeah, for the most part. So that was tough. But the last thing I gave that was a talk, including with a cheat sheet, which is on GitHub, about value categories in C++, which is one of the most complex aspects of the language dealing with R values and L values and geo values and PR values and X values.
00:38:56
Speaker
And it all has to deal with the lifetimes of objects in C++, which is something that Rust handles for you with the bar checker. But it's something that you can have a lot of code in C++ that will compile and will run probably some of the time, but is actually undefined behavior.
00:39:14
Speaker
and will probably result in crashes. And so that was sort of my last gift that I was trying to offer to the C++ community that was also like, here's a helpful thing to help you write C++ better, but also- Don't play C++, man. But yeah, so the job that I found was that I was offered
00:39:40
Speaker
I was offered the co-founder of CTO status at the start. And I had complete control over what we were going to do with the tech. And I said, we're going to write closure. And so that is OK, let's play, which is where I work now. And we've built, we've patented and built an application, basically, or a service that allows gamers to bet real money on their own gameplay, their own results.

Tech Stack Details and Architecture at OK Let's Play

00:40:09
Speaker
in online competitive skill-based games. So right now we're live with Rocket League. So if you want to bet real money on a 1v1 in Rocket League, we collect the results instantaneously and automatically. We handle the escrow of the funds, we handle like the KYC email element, everything like that, so that players can trust that they're going to get their money. And you just go on there, you find an opponent,
00:40:36
Speaker
You play your game, you collect your winnings. And we've done all of this in Closure. And what is the stack, by the way? So, yeah. So, on the backend, Closure, like your typical Closure server, Closure ring, and I think, are we using anything else that's very nice? We built our own in-house system for managing backend effects, which is actually influenced by Reframe. Okay.
00:41:06
Speaker
And so you define effects in the same way that you define events in reframe. So you brought the front-end way of doing things into the back-end. OK. Yeah. Yeah. And it's really neat. And then the whole thing's brought together in a chain system. So you define a chain in the same way that you define an event in reframe. And each link in the chain is a function that returns a pure function that returns a map of effects.
00:41:34
Speaker
It can also pass data from one link to the next link. It can stage effects to be run ultimately once a link commits. And that's a really neat system that we built. But for the most part, that's just a standard closure setup on the back end. The front end, we're using closure script with reframe. And is there anything else
00:42:01
Speaker
I would call out to expound as well, because that's obviously a great bit of work. But then the other thing is, for the whole thing, we have everything wrapped in orchestra. And this was, so we started writing closure. And this was like, OK, let's play. It was my first closure, like full time, getting paid to do this sort of thing. And I started writing this back end.
00:42:31
Speaker
and in this front-end, and we get to the point where we have a couple of thousand lines of code, which does a lot in closure, just a couple of thousand lines of code in C++, that's one feature. Then all of a sudden, I'm like, what's the shape of this? I don't know. I get into some function and I'm like, wait, what keys are in this now? We had bad habits of
00:42:58
Speaker
of not fully qualifying all of our keywords. We have bad habits of not always conforming shapes to be consistent. Sometimes this is a partial this thing and then sometimes it's a bold thing. I was like, this is no good. A spec came out and I was like, okay, this is good. I started looking into spec.
00:43:24
Speaker
I was looking at a spec and we started using spec everywhere. I've read through that spec guide so many times. Every time I got to the spec gen, like the generative stuff, I was like, this is useless. I have no need for this. I think I've used it a few times and every single time I'd be just fine about it. Then there was this other thing, the instrumentation side of things. I was like,
00:43:54
Speaker
Oh shit. We can like hook these functions to automatically check the specs. Why, why are we doing this? Why isn't everyone doing this? And then, and then I used it and then I was like, wait, it's only checking the return values. I was like, but I have all these arguments. I want to check those. And then I did some further looking into it and I was like, they used to do that. When the instrumentation was first added, they were, they were instrumenting,
00:44:22
Speaker
the functions to check the arguments, to check the FN spec and the return value. But they removed it, I believe, for performance reasons. Which is bullshit. I've been doing this for three years now, on the front end and the back end, and the performance change I have measured is negative.
00:44:43
Speaker
But compared to because you're used to C++ level of quote-unquote speed, right? And so Do you how do you compare that with? Close your code and then did you ever feel like oh, I should have written it in C++ because it could have been faster Sure No, okay. No, I've I've I honestly I've never I've never felt that I
00:45:12
Speaker
Because that's one of the claims that C++ people make or probably Rust people make as well. It's going to be super fast and way faster than the JVM or Garbage Collected Languages, for example. Sure. It will be. It absolutely will be. I think on the, if you're writing a game or a game engine, I think it's hard to argue the case there, but back in services seems a bit more. Yeah, then they should be comparable. Yeah.
00:45:39
Speaker
Okay, so for our frontend with Closure Script, I've looked into what it would be using Rust with WebAssembly. I've looked into what it would be using PeerScript. And I've looked into sort of as many of the functional or type safe options that I found.
00:46:03
Speaker
Everything that we're doing on the front end is just data, like with React. Our views are just big vectors, data. And everything that we're doing, like with ReFrame especially, allows us to just build everything in terms of data. And there is nothing, there's no language that I've used that transforms data the way that it approaches. And so there are no, right now anyway, that I know of, there are no languages that I think I would choose on the front end instead. On the back end,
00:46:31
Speaker
We have one service that's written in Haskell. It's dealing with our money and it's basically our money service. And there's a really great Haskell library that handles money exactly the way that we want it to.
00:46:55
Speaker
And we didn't, we were really concerned about fucking something up when it came to the money.
00:47:04
Speaker
with different currency types. And basically, that just seemed like it was going to be worth it. Now, we have several different services. We don't use microservices, but we do have different services that are all just sort of dockerized. So it's easy enough to just spin up something in a different language and put it on to ECS. And they all talk with each other with HTTP. OK. Yep.
00:47:28
Speaker
And so that was obviously like they need to use JSON. Like most of them use Eden, but with that said, I have been writing a couple of servers recently in Rust. And that's because
00:47:47
Speaker
Uh, their game service and I need them to be as small as possible and as fast as possible. And so like right now, one of the servers I've written is, um, is for, for a game that we're making, uh, it's.
00:48:01
Speaker
It runs with a stress test on and hundreds of megabytes of JSON IO. It runs on a tenth of a CPU under 16 megabytes of memory in a Docker container.
00:48:18
Speaker
And so under 16 megabytes of memory during a stress test, in contrast to our min heap size for our closure services is 256. That's because of the JVM. And so that's huge. So all this closure you're writing, do you write it in Emacs or some other shit?
00:48:38
Speaker
So I'm glad that we got here. I'm glad that we got here. It's inevitable. I use Vim, and I have used Vim for... You're not pleasing anyone here, Jay. That's okay, guys, because I'm the guest, right?
00:48:56
Speaker
And just like the customer is always right, the guest is always right. So I use them and... You have never heard this podcast before? I've heard several and I knew this was coming. So that's episode number 57. Thank you for listening. Take him to the green room now.
00:49:16
Speaker
Let's get the music going again. No, no, no, hear me. I've tried Emacs a few times. I'm joking. Come on, Jay. And I've tried Space Max too. But there are some very big differences to my workflow. So first off, I love the modal editing so much and it's so ingrained in everything I do.
00:49:37
Speaker
And also, just the HJKO movement is so ingrained in what I do that my window manager does that. I use i3, Tylen window manager on Linux. I have Vim plugin for Firefox. My music player does it. My fucking PDF player does it. Everything I have is Vim oriented. And your car,

Debate on REPL and Programming Workflows

00:49:59
Speaker
obviously. Yeah, well, I'm in San Francisco, so fortunately I don't need to have a car. But it would be... It would be HJKO.
00:50:07
Speaker
I would exit the car by hitting WQ.
00:50:15
Speaker
So I know that that can carry over to Emacs, and I've tried that. But the biggest difference is that, for me, a text editor is like the analogy that I imagine is if I'm a field worker, like I'm on the move a lot, I'm going to different places, Emacs is a desktop computer, and Vim is a laptop computer with like radars and shit coming out of it, right?
00:50:42
Speaker
I can, or not radars, but like antennas. That's what I want to say. Um, you're like a James Bond of editors, basically. Yeah. Like that. Like I want something that I can spin up on the go anywhere that is customized for me. Um, and Emacs is like a van that you would have to bring with you. Um, and, and you can't like, you can have a lot going on in that van. That van can do everything for you, but unless that van can go where you want to go,
00:51:10
Speaker
That's not going to work and so the biggest thing for me is like, yeah, I honestly don't think you should get into vans with strange people like VJ, you know, especially if they're running email. I mean, let me, let me, uh, this is a teachable moment, as I say.
00:51:26
Speaker
or evangelizing moment. I think Emacs is like the time portal sort of shit. So usually, I agree with you. When you want to get onto any machine, the VIA is there and it makes sense. But usually, I just edit the files using Tramp.
00:51:44
Speaker
on the max by going to the server so i think it's it it's it's more about you know the kind of workflow that you're used to and then and then perfect it or not perfect but you get used to it over the years and it's for me i mean i tried uh i was trying because we had um
00:52:01
Speaker
Kalva Peter on the on the show and then I was giving it a try like we scored and then the first thing that I did is there is a space max emulation for VS code because all these shortcuts are built into your fingers, you know, it makes sense and that so I think it's it's the the Workflow that that you have and and right you can take it everywhere the biggest thing I think is that if someone is
00:52:29
Speaker
If someone is writing code as much as I do or we do, they need to have an advance here. And if they don't, if they're still using their mouse to move around or something like that, then it's just not efficient.
00:52:47
Speaker
You need to fully invest yourself, in my opinion, in some sort of editing tooling, because it is the means of your, of your whole fucking career. Do a good job with it. And, and so what like then me, Max, whatever this close source, but I've never actually noticed this before, but your name is V I J. I know.
00:53:15
Speaker
Yeah. Yeah. So you're betraying your own name. Really? No, that means I know this and I'm going to start calling you. I'm going to start calling you VIJ from now on. Yeah. You should just to really, just to really shut you up. You should. It's too bad. You couldn't bring the improved version. Maybe that's me. Actually, I should just stuck it in my name. Yeah, you should confuse people on the internet. I think you should be Wim J and I should be VJ.
00:53:46
Speaker
But I think that the first editor I used back in the university, I mean, we had this, what do you call like dumb terminals connected to the Unix somewhere. Like you only have the dumb terminal thing and that had the old VI and it was fucking horrible. So that's even worse actually. But I don't know. I mean, to be honest, but I, I used VI when I, when I, I used it for the beginning of my career as well and kept going with it for 20 years. So I mean,
00:54:14
Speaker
No idea does its thing. It's okay. But I think the problem I had, you know, you were talking about like Windows, the problem before Linux became popular, Windows became popular and I kind of, you know, we had to use Windows on the front end and we always used VI on the back end. But you kind of lost the muscle memory a little bit, you know, which was a shame because I loved VI, you know, I read the manual 100 times, you know.
00:54:41
Speaker
knew all of the interrupt with the operating system and stuff like that. So I did all my own kind of bindings and macros and all the settings. And the nice thing is, like you say, it's always on every machine, you know, whenever you log into something, it's there. So, you know. And do you use a five player or something or with the VI foreclosure stuff? Oh, yeah. Yeah. So I have never had a good experience with artists. Um, and I mean, uh, there was Tim Popo, I mean, he makes amazing things.
00:55:11
Speaker
Um, but that just never, never worked well for me. It wasn't until, um, Olico, uh, whose name is Ollie Oliver, I think, uh, he made, um, uh, conjure.
00:55:26
Speaker
and then subsequently propel to use P REPL. That's been the best experience I've had with them and integrating into a REPL. It works really well and I have no complaints for it on our backend. I haven't had it working well with Fig Wheel on our front end.
00:55:48
Speaker
But we have hot reload. And for the most part, I just use that for everything on the frontend anyway. I have somewhat of an adversarial relationship with closure. And I disagree with a lot of the ways that people do things with closure. And the REPL was one of them. It took me
00:56:13
Speaker
It took me a really long time to come around to the Repel and I still don't think I evangelize it nearly as much as a lot of these other people do because I don't think it's as useful as a lot of these other people say.
00:56:31
Speaker
On the back end, when I do have conjure, it has been helpful to just hook into some functions and say, OK, I just want to evaluate this. And I'm going to make a comment block and do some code in there. But I have tests. I could write a test to do that as well. For the most part, I use a line like auto test, auto refresh. So I can save my.
00:56:58
Speaker
I save my file and it reruns my tests and I can add some metadata to say refresh only this test and it'll just rerun that one. And I mean, I can use that sort of like, I guess it's, I guess it's TDD, but not really. Cause it's kind of, you're not writing all your tests first and then, uh, and then catching up, you're just kind of doing them together. Um, but like that is like the, the, the.
00:57:21
Speaker
the process that I use. And I don't think you really need much of a grapple for that. But that's a blasphemy. It is total blasphemy. Fuck you. Since you mentioned you want to fight, so let's do it. It's good to have a bit of adversarial stuff. I like this on this podcast and we need to fight.
00:57:47
Speaker
So I love the REPL. I mean, I think we need the REPL everywhere and it's underplayed. And I use the REPL all the time, day in, day out. Let me get my popcorn. The thing I wouldn't do, the thing I don't like is all this REPL reloaded shit. Because I don't like all these frameworks that make the REPL presume to make the REPL useful. Because it's already useful. You don't need all this reloaded stuff going on. If you really need to restart the REPL, restart the REPL. No problem.
00:58:16
Speaker
But for the most part, I think it's, you know, it's, it's fantastic. You know, maybe it's because I don't, I don't really invest. I write the tests right towards the end. You know, I don't write the tests as I go along. Um, I don't like to do that because that kind of inhibits the fluidity of the programming. Um, cause I feel like tests are a kind of commitment to a particular shape or a particular approach, you know?
00:58:47
Speaker
For example, in our backend, the way that we write tests, we have a lot of macros to just spin up all the things that we want. The way that we write tests is really all just, at this point, it's so defined that it's easy to just jump in and add another one. And my concern with the REPL, in contrast with that, is that everything I do in the REPL is ephemeral.
00:59:08
Speaker
This is true. I think that it depends what you're working.
00:59:16
Speaker
Like, so unless I'm just doing a one-off, like, I need to issue something to Mongo or Postgres, or I need to do a query or something, unless I'm doing a one-off thing where I just want the result of that one thing,
00:59:33
Speaker
I don't actually use it to verify, okay, this is working as I expect it to, or something like that, for the most part. Why not though? Because that's the point. Yeah, that's the point of tests too. How are you programming anything? That's the point of tests too. To prove that they work and to prove that they continue to work. In my opinion, it's a duplicate effort.
01:00:03
Speaker
Either you're duplicating your efforts or one of those is suffering, um, your tests or your, or your REPL experience. But why, but are you assuming that the REPL is you're typing into the REPL rather than shipping code from your editor? Because you write your program as you're writing your program, you evaluate it in the REPL. That's how you do it. No tests required. That doesn't quite work. Uh, if, if you need.
01:00:31
Speaker
a connection to, if you need a connection to a database, if you need a connection to this or that, then what you're going to end up doing is not just saying, oh, I want to evaluate this. You're going to write a little comment block that sets up everything that you need, a little fixture for you. And then you're going to write your, your code inside of there. And what you have there is the test. Well, I guess, but if you just reload your namespace, you'll get the, you'll reconnect to a database. It's no problem. Are you connecting to your database as an effect at the top level of your namespace?
01:01:02
Speaker
Sometimes, not very often. Yeah, it's like we don't do that. It's always... But normally you should pass your database in as a parameter to your function. Right, right, right. Which would mean you need to set that up in order to evaluate your function to begin with, which would mean you need some sort of fixture. So if we focus on that, I think we're always going to go in circles because I do disagree with you. However, to find more common ground,
01:01:32
Speaker
I will say that I would agree with you more if I'm working on something that does not have some sort of databases or external connections or something like that. Yeah, I mean, to be honest, I don't often use a database. OK. Yeah, basically everything that we do on the back of this is doing something with some sort of Redis or Mongo or Postgres or some API or something like that.
01:02:01
Speaker
I would say that there have been the best experiences I have, the best experiences I have had with VIM conjure have been writing just purely data-oriented code with no effects, no setup necessary. And I can, as you said, just write some code, send it to the REPL, see that it all works, and say, great.
01:02:28
Speaker
and then worry about the test there. So I can agree with you there, but I don't think it's as, for me, it's not as profound as it seems to be to you or to a lot of other people.
01:02:43
Speaker
So what is your, I mean, how do you architect your database then? What's it, it's interesting. It's an interesting, because I think sometimes these, um, you know, these kind of like, uh, repl things or like, whether you're using it effectively or not is a kind of, it's a kind of like, whether or not your, your architecture is kind of repl oriented, let's say, you know, whether it's like oriented towards that style of development or not.
01:03:07
Speaker
Whereas maybe you have different ambitions for your architecture or different goals or different ways of setting

Database Architecture and Functional Programming

01:03:15
Speaker
things up. So I'm happy to find common ground as well. So if that's not a priority for you, then it doesn't matter. Do what works. Sure. Yeah, I just don't see how the REPL has anything to do with
01:03:37
Speaker
How I design the database. Like I'm not going to, I wouldn't design. No, but your constant need to connect to it and take state from it. You know, that's the problem. That's really what you're talking to, isn't it? What you're saying is I have this sort of a set of shared global state somewhere and constantly connecting to and sucking from feeding too. And that's, that's kind of like a peculiar architecture for me, you know, that you essentially have externalized all of your global state.
01:04:05
Speaker
where you've got a language that has a lot of controls for that. So why are you doing that? Interesting. Interesting. Yeah. I'm going to think more about this. Obviously, the state needs to be somewhere. We are talking about mutable state. And so it needs to be somewhere probably in one place.
01:04:32
Speaker
But so we use our database and our transactions as bindings. We don't use them as something that we pass into every function. I don't see a point in that. But it's still something that needs to be set up. I feel like I can have a good answer to this, but I don't right now.
01:04:59
Speaker
You know, that one of the, one of the things about, um, uh, one of the things about reframe that they're trying to talk about is like this, um, side effects, but also the other thing they talk about is co-effects. And that's, that's what you, that's what you kind of avoid when you, if you, if you, if you pass database, if you pass your database into every function rather than these bindings, then you, you, you actually have that, that you get rid of the co-effects.
01:05:26
Speaker
In other words, you don't have to make a lot of assumptions about the world outside of your functions. Then you can test things more cleanly.
01:05:36
Speaker
having to worry about this big ball that you're pulling from mysterious players and dealing with kind of randomly. I think that's the conclusion I come to from a kind of architectural perspective. Isn't that making your code more and more tedious? For every function you're passing, it makes sense because it's more like making the functions
01:06:03
Speaker
completely pure in a way that your function is only operating on the parameters and not dependent on anything else. But every function then that is operating on this, then it kind of becomes a bit too much. Well, because what happens is that you end up like this functional shell kind of approach, where you definitely pass the databases into some functions.
01:06:28
Speaker
Yeah, but that doesn't get passed all the way down you know that's the point is that you just what you then do is you you pluck some state from that database and then you don't process next layer you don't pass the database all the way down that that's that's where i feel like we're. Kind of an odds with yeah i think i have five.
01:06:46
Speaker
I've gone through like two rounds of this in one of the applications that I'm working on like first having this this model like okay I'm going to pass DB everywhere and then because there is this query layer and then there is business logic layer that doesn't know the database but only operates on the on the maps.
01:07:02
Speaker
And then at some point I was like, oh, screw this. I have to pass this TB everywhere. And then that became tedious. And then at some point I moved it to, I mean, similar to the one that previously Ohm and other people, like the top level that is deaf once, and then I have something as a global state that I can pass around, like the app state sort of thing. I think there should be some sort of a balance between them, right? And sometimes it just goes,
01:07:28
Speaker
like too much. And there are too many functions with DB everywhere. Well, that's what reframe looks like. If you if you write reframe, and you do that, Jay, so you know what it looks like, then yeah. Well, I have some I have a really big gripe with reframe, actually. Just got them database everywhere.
01:07:48
Speaker
Yeah, but the thing about the thing about our database is and then the way that we interact with it is because we use this reframe style approach. All we have is a qualified keyword that represents an effect somewhere. You're returning a map saying I want to go run this effect. Just like in reframe you have some effect that you need to run. You return a map that says you need to run it. You don't know.
01:08:15
Speaker
how it's set up or anything like that, or what it's connected to necessarily. You just need to know there is an effect that is represented by this pure data, this declarative way of saying what I'm going to do. And then all the nitty gritty shit happens behind the scenes. I think that this is a very good way of when you look at
01:08:39
Speaker
One of the things that as functional programmers we try to do is separate the effects, push them as far away as you can, and just focus on the pure data transformations and your business logic. I think that given that we've done that first class, exactly how we handle the nitty gritty of that database when it's pushed all the way to the side,
01:09:07
Speaker
It doesn't matter. It's not a big concern to me. But the thing about reframe, actually, the big issue that I have is that
01:09:14
Speaker
every, um, or one of the biggest issues is everything is, everything is forward. So this is, this is going to be a series podcast. C++. Now you need to come, you need to end it by telling us. Okay. Yeah. Yeah. Right. Rust. Yeah. C++ is shit. Closure is shit. Uh, everything sucks except for Rickshake is fair. Uh,
01:09:43
Speaker
We just need to come to terms with this. But no, this is serious though. The thing about reframe is every event goes forward. So you need to know when you dispatch an event, you're coupled with that event. And so it is no different from a function call, except it's just using a different syntax, right?
01:10:09
Speaker
As a result, uh, what you end up with is asynchronous. That's the problem. Um, I disagree with you there because I think there's still a better way to do it. Um, you, you end up, it can be asynchronous and still be better, I think. Um, Oh yeah. But, but, but anytime you put an event on the reframe queue, it's an asynchronous function call is my point. This is true. Yeah. And you're right there. Uh, the, for me,
01:10:34
Speaker
The better way to do it is to reverse the coupling. So let's say my app is focused. When my app is focused, I want to see if a chat window is open. And if the chat window is open, then I want to mark the latest messages as red. This is an actual problem that we had where, given the reframe design, I have some handler for the app that's been focused.
01:11:03
Speaker
And then that needs to dispatch some shit like, OK, chat, go mark your stuff as red if you're visible. That is awful. To me, having to know about chat in the handler that deals with things being focused, or even if you try to separate it one layer or add some indirection there, still, that's handling the focus needs to be dispatching to something that knows about chat. That's a problem.
01:11:32
Speaker
Now, if you invert it, then what you end up with is rather than one-to-one events, you end up with one-to-many events. So what you get is there's a handler that says the app was just focused. Now, rather than dispatching an event, what I use is the different terminology of it emits an event. Now, it emits something, which is just a signal. Now, anyone, anywhere,
01:12:00
Speaker
can subscribe to that. So the chat system would say, I'm interested in when the app has been focused because I want to update the red status for these messages. To me, that is a much better architecture, but it is entirely prohibited by the design of reframe because you don't have these one-to-many events.
01:12:23
Speaker
Now, you can implement that in reframe yourself, but it's not... Well, just one second. You can have multiple subscribers to an event in reframe. That's out of the box. So it's no problem there. Let me think about how I want to wear this.
01:12:47
Speaker
You're really full of shit, Ray. You're allowed to say it, you know? I mean, I'm actually correct, but I can still be wrong. So the thing is that when you think about these things, you have to change the way that you're thinking about your, about your reframe events then, because if you think of them as asynchronous function calls, then that's absolutely not the way that this can work.
01:13:12
Speaker
But my point is that let's say you do this focus effect on some component that's focused. You can emit an event like you say that says, okay, something got focused and this is its name. And then you can have a subscriber and that subscriber can filter based on those events and you can have a hundred subscribers. And what are you doing? Are you doing that with interceptors? Just subscribers, just standard reframed subscriptions.
01:13:42
Speaker
Subscriptions are different. Subscriptions are the bridge between the event layer, the model layer, and the view layer. I'm going to say that I don't understand what you're saying, and I don't think that there's just a way to arbitrarily subscribe to something. When you dispatch something, you are dispatching the name of a function to go call. You can have interceptors to intercept those.
01:14:09
Speaker
But that's not a one-to-many. That's a, I'm going to be a man in the middle for this one very coupled event. Subscriptions are just a way of providing data from the AppDB to the view, which is, as far as I'm concerned, entirely separate from that. I don't understand how you're saying that can work. It could just be that I'm missing it.
01:14:35
Speaker
Or I'm just, I'm behind, I don't know. But either way, it's the way I've used it in the past is that, you know, you do these subscriptions, but you know, maybe I'm doing it wrong.
01:14:47
Speaker
I could be holding it wrong, that's for sure. So you're using this for, so this is for a chat application that you built for the gaming stuff that you have. That's the front end mostly. We use reframe for the entire front end. And so that's, we're on mobile and desktop and web and it's all just called your script and react. And we use reframe for the whole thing. But mobile as in mobile app or just a mobile web thing?
01:15:16
Speaker
It is a mobile app that it's called a hybrid app. It's a native app that loads up a web view basically, and then uses Cordova to talk between two. It's not React Native, but Cordova. No, it's not React Native. The main reason is although React Native is similar to React, they are too dissimilar to, I think, comfortably share code bases with something that is React.
01:15:44
Speaker
And there is React Native for web, but...
01:15:49
Speaker
All of that can be avoided if you just use a hybrid app. How much of code sharing that you have between Closure Script and Closure, is there common libraries in CLGSC somewhere that you use in both places? Our whole front-end is Closure Script and then our whole back-end is Closure, except for that one Haskell service. We do have a common code base, which is primarily just filled with specs.
01:16:18
Speaker
because as one of the things I mentioned was we just spec everything and that's because we for both the front end and the back end we're using orchestra for everything and there isn't that much like there are some helpers that are shared but there isn't that much that's shared but the thing about orchestra I want to come back to that
01:16:40
Speaker
Maybe you can give us a kind of like, for the people that don't know what orchestra is, Jay, maybe you can give people a kind of five minute introduction to

Orchestra Library for Data Consistency

01:16:48
Speaker
it. Cause I think it's pretty special, you know? So I think you've done a great job there. So it would be good to give people like a level up on just a five minutes on what the background there is.
01:16:58
Speaker
Thanks, Ryan. So orchestra is a closure library that uses spec and instruments your functions by basically hooking your functions so that whenever you call them,
01:17:17
Speaker
automatically all of your inputs and outputs have their specs validated. That means that assuming that you have spec'd out, not even all of your system, but a good portion of your system, you'll know because you'll get a spec assertion failure whenever you make a function call and some data is not in the shape that you expect it to be. You'll know right then rather than later when you get a meal somewhere and you're wondering what the hell happened.
01:17:46
Speaker
Now, orchestra works with closure and closure script, and there have been some concerns raised that the performance of this instrumentation is worthy of not running it in your everyday development or in production. Yeah, I mean, I've had people say, you can't even do this in everyday development. It's absolute bullshit. You can. In the measuring I've done,
01:18:16
Speaker
it was like, I think three or 4% of our startup time for our app during development is instrumentation. And to know that every single event that we're dispatching, in the case of Reframe, because we spec all of our events, to know that every single one of those has the exact shape that it's supposed to be is absolutely worth 4% of our load time to me.
01:18:45
Speaker
Orchestra also provides a macro to wrap deafens in a C-style way where you get to say the name of an argument and then follow it with the spec for that argument in line, and also specify the return spec. It's called deafenspec. So we use that, and then we use macros around reframe events as well to use the same syntax for our reframe events.
01:19:10
Speaker
But I recommend that anyone who's doing closure, who's already using spec, who wants to have more confidence in their system, give orchestra a shot. Because you hook it in, you call the instrument, any functions that you already have instrumented are just going to be automatically checked. If something's bad based on the specs, the invariance that you're asserting based on defining your specs, if anything's bad, you're going to know.
01:19:37
Speaker
And you wouldn't otherwise know unless you manually assert all of that stuff, which is just not feasible. Yeah. And so maybe a completely different question. So how long did it take for you guys to bootstrap your, because I'm assuming this is, okay, let's place a completely new startup, right?

Growth and Challenges at OK Let's Play

01:19:56
Speaker
Like there is zero code and then now that is all the services now. Yeah. So how long did it take and how many people are working on it in Closure code base right now?
01:20:05
Speaker
Sure. So we've been working full-time on Okelet's Play for about two years. Okay. That's pretty young. Yeah, pretty young. I was doing some part-time work before that, but full-time for about two years. Right now, we have
01:20:23
Speaker
five or six people in the company total. And then we have two software engineers who work with me, one focused on the front end, one focused on the back end. And then I just sort of go wherever I need to go. And yeah, it's, oh, I'll talk about that. I thought that I was surprised because I thought that hiring closure developers
01:20:52
Speaker
would be, like, I knew it was going to be harder because there just aren't that many closure developers. But I thought that by the nature of them being closure developers, that they would just be great.
01:21:04
Speaker
But we've actually had a really tough time hiring really good devs. We've had a really low success rate in our closure devs. And that was a huge surprise to me. Because I think that most people, you have to be a certain type of person to make it to closure even.
01:21:23
Speaker
to have enough interest to learn the language and then to stick with it and then try to find a job with it. So that was a really big surprise for me. I don't know why that is. But is it the people that you didn't hire, any people that you hired?
01:21:41
Speaker
Were they already closure programmers or were there something like, okay, you're okay with having C++ people and you can get rid of C++ from their brain by brainwashing them into closure? They were already closure devs. I think of the handful of closure devs that we brought on, we kept like people who already knew
01:22:03
Speaker
Yeah, because I mean, he's really, really, really, really great. But the other one that we have right now.
01:22:16
Speaker
was a C++ dev, like another game dev C++ and C sharp. And I just knew like he's a really solid dev, closure's not gonna be a problem. And so then I just had to sell him on being okay with his mind being blown for the first month. But it was actually, it was really fun to see him struggle through that. And like,
01:22:41
Speaker
He has a map and he wants to update some stuff, or he has a list of maps and he wants to turn it into one map. He wants to reduce it into one map. Just seeing him be like, I know what I need to do, but I don't know how to do it. And we do a lot of calls and I'd just be like, oh, this is so cool.
01:23:03
Speaker
But I mean, when I did that, as I said, I didn't have anyone to help me through it. So what did you put it down to though, Jay? Is it because people like, um, are a bit, maybe it's a thing and are you hiring in San Francisco or are you doing remote hiring? Uh, we, uh, we are fully remote. Yeah. So, um, we actually, two of us are in San Francisco,
01:23:28
Speaker
but one of us is in Brazil. Just to look back to the question that I was asking, from C++ to Closure, there is a significant paradigm shift. For me, I feel like because I did a lot of Scala before, I got used to Closure and then when I'm doing Rust, I feel like, if I call something, I get a different type and there is no
01:23:58
Speaker
you know, common data structures to deal with. I mean, because you also have experience with both Rust and enclosure. So how do you see the transition to Rust then? I mean, if you're working on Rust code. Sure.
01:24:13
Speaker
Well, I was just talking to someone on IRC yesterday, actually, because I was in the Rust pre-node channel. And I said something, he's like, oh, aren't you the guy who made that Q3 thing?

Transitioning from C++ to Rust

01:24:27
Speaker
And I was like, yeah, yeah, I'm popular. Like, one guy recognizes me on pre-node. But I was telling him, like, eh.
01:24:36
Speaker
But I was like, you know, I am. And he's like, oh, I thought you went back to C++. I was like, I did. And I was telling him like, yeah, back five or six years ago when I was writing Rust for Q3, I was really bad at Rust because I had a C++ brain. And everything that I was thinking of was just in terms of C++. And now that I'm writing Rust, I feel like I'm really bad at Rust still because I have a closure brain.
01:25:02
Speaker
And the thing is that now that I've done closures so much, at least my closure, like the closure the way that I want to do it, it's adversarial closure. I think of things in terms of data, right? And everything is as much as possible anyway.
01:25:26
Speaker
it's just declarative data pipelines. And a lot of the, like, when we're discussing features at OQL, let's play with the other devs, we'll just share jists of maps. And like, that's the feature that we're talking about. So, okay, the data will look like this. And then like the transformations you need to do, those are kind of implied just by knowing how the features go over.

Exhaustive Pattern Matching in Rust

01:25:51
Speaker
And so,
01:25:53
Speaker
doing that with Rust is really fucking difficult. You can't because how do you have a heterogeneous map? In general, you don't. And the other thing is like,
01:26:07
Speaker
What I found in this game server that I'm still working on now is I started using a lot of Rust enums for a sort of like, it can be this, or it can be this, or it can be this, and it can have these different shapes. But each time you match on one of them, it needs to be exhaustive, which is exhausting. Yes.
01:26:30
Speaker
So it is really nice to be able to write that and struggle with the barrel checker until it compiles and then be like, yes, and then it runs and it works and you don't need to worry about it.
01:26:52
Speaker
And I would consider using Rust for some of our services on the backend, just due to the performance, due to the memory profile, everything

Comparing Rust and Clojure

01:27:01
Speaker
like that. But for anything that we're doing with data, I just wouldn't do it. And honestly, it's the same thing with Haskell.
01:27:09
Speaker
I just wouldn't do it. For those languages that focus on the types, to me, it's just not worth it. We have some services that are just focused on moving data through WebSockets from Mongo to our front-end, for example, which is basically our own firebase, except it has a better permission system and it scales horizontally.
01:27:31
Speaker
That's just data. It's just moving data. And we need to handle different shapes of data. We need to be able to do it in a very fluid and flexible and what's the word that I want agile way. And to do that in such a strongly static type language,
01:27:53
Speaker
I just don't think makes sense. I just don't think it's a good choice. Yeah, I think time wise and also investment wise, I mean, there is too much design work that you need to do to make it as flexible as what you can do with closure. And I think that's the challenge that I see now. I mean, I had the similar kind of thing on Scala versus Closure when I was doing both, when I was working on that one.
01:28:18
Speaker
But at least they both are in JVM. So I don't have to deal with this borrow checking and memory and shit. But now I'm kind of juggling between Clojure and Rust. And I'm like, OK, these are completely different way of thinking. And yeah, it's a bit of a- Isn't it the way I think about it for these kind of law-level languages, like C and Rust and stuff like that. And these are the things.
01:28:40
Speaker
is that it's all to do with the, and I think Jay's kind of saying it as well, is it's the problem space. If the problem space is kind of well defined, and you know that there's a certain set of types coming in going out, well, do you need all the flexibility that closure gives you when you can actually, you know, you know the problem,

Network Services and Language Limitations

01:29:00
Speaker
It's not going to change that much. For a lot of network services, things are like that. They're fairly simple. Just take a packet in, give a packet out. The share is not going to change that much. You don't need the fluidity. In that case, I think these low-level languages, like Rust, can offer a lot of value. But there are many services where it just doesn't make sense if you have to look to other kinds of APIs.
01:29:24
Speaker
this kind of stuff where things are evolving, where things are changing quite a lot, where you need that agility that you're talking about. But it's very difficult to make it kind of like a very simple line in the sand.
01:29:40
Speaker
But also it's the tooling because one of the things that i totally miss if i'm writing enclosure you know you get used to repel and then there is a function and then you just run it and then check it what else you want to do and then move on. Not if you're jay you can't do that i mean you have to run the whole program and then there is no way i can just test one i mean you can write tests and whatnot but
01:30:02
Speaker
But it's a different mode of writing code, I think. And once you get used to this organic way of developing code with function by function and then running it and then moving on, that doesn't work there. And then there is different priorities, different way of writing code. Yeah, totally. I completely agree with you there, Ray. I think that if you do have a finite amount of really
01:30:33
Speaker
really well-known data shapes. If your domain is finite and well-known, then something like Haskell with servant, where you can just define the whole thing with types, or I'm using Rust with actix, which basically does the same thing.

Validation in Rust vs Clojure

01:30:52
Speaker
I just define an endpoint function that says,
01:30:56
Speaker
This takes in Jason of some generic struct type that I have defined as serializable. It handles the whole like, well, if I can properly de-serialize the Jason into this struct type, then I'll call the function. Otherwise, we'll give you a 400.
01:31:14
Speaker
And that can be really nice. You don't need to worry about it. And the thing is, you know, as soon as you get into that endpoint function, you have valid data. Whereas with Clojure, we need to do a lot more of that validation ourselves. Fortunately, we have spec, but still it's rough. But I think it's, well, it's almost 90 minutes. So I think this would mean that we need to take you to the Rust podcast for the next episode. This is an exit song soon. Okay.
01:31:45
Speaker
Oh, dear. No, we're not gonna. So I was just thinking, I think the adversarial closure that you're going to write, I think we should name it like opener. Instead of closure, it's going to be opener. Yeah. That'd be like amazing. Shutter, I think. Shutter is better. I want to say a little bit about this, guys. Yeah, yeah.
01:32:08
Speaker
It's called idiolus, idio as in idiom, meaning like quirky, because it's my list. And it's very peculiar, it's very particular to my tastes. But what I basically want is, the other thing I really disagree with Closure about is the JBM. Coming from game development, like operating system development,

Wishing for an Ideal Language

01:32:30
Speaker
I don't want the JVM. I want persistent immutable data structures. That's great. Mac rows, those are great. But let me compile it to native code. Let me compile it to native code. The other thing is, let me have it be dynamically typed to start with. Let me write the most closurey looking code to start with and have it compiled to like C minus minus or LLVM or something like that.
01:32:57
Speaker
Don't you think that the growl stuff will get you there eventually? Kind of. Maybe. I'm hoping so. But here's the thing. What I really want to do is then once you define specs for your data, basically like spec, except once you define specs for data, that changes what the compiler knows about them. And all of a sudden, that's not a boxed object anymore. Now I know the type of that.
01:33:21
Speaker
now I can better track that, now I can better optimize that. You can write your data, you can write your whole fucking program to be dynamically typed, get it working, and then lock it down with specs. By doing so, you optimize it as well. I don't see why this can't exist. I don't know a single language which works this way, but it's exactly how I want a language to work. I think you're right in terms of where it could go.
01:33:50
Speaker
I think obviously spec itself is still somewhat in a fair fight. It's a long gestation period. Right. It can't be specced exactly because it can't be predicative. It has to be something that is static. No, but anyway. Yeah. Well, yeah, it's an interesting idea. I think, you know, this concept of
01:34:13
Speaker
essentially being able to, to think about the binding forms and then event, you know, essentially kind of like find it all down. I think, I think the, uh, you know, one could argue that that's kind of what the JIT does, but, you know, but like you say, it does it, it does it at runtime. It does it a bit later on. And by the sound of things, you'd rather have that early information early or that early rather than later.
01:34:38
Speaker
I think the downside of not going with the VM, because the history of lisp is littered with like, you know, idiot lisps, if you like, you know, you could call it like, you know, short for idiot, actually, but I had figured that the people who write that would be called idiots.

Benefits of Hosted Languages

01:34:58
Speaker
I'm prepared for that one.
01:35:01
Speaker
Sorry? I'm prepared for that one. No, I'm joking. The reason I say it is because the reason that people say that closure is a success or that the reason why a hosted language is winning is because you get access to all of the other ecosystem material. The question is whether or not you get any value out of that.
01:35:28
Speaker
And I think probably for the whole Closure community, the win is probably outweighs the loss, but per use case, maybe it's not worth it. Right. I think that if you look at any library that is cross-platform, as in cross-host, so ClosureScript and Closure CLR and Closure JVM, it's basically just going to be pure Closure. And you can get a lot done with just that. The other thing is that if you are compiling to native code,
01:35:58
Speaker
You can interface with just about anything through the CABI. And you can do that with basically no overhead. And Grawl has shown so much what you can do with that. So I think that you're absolutely right. There have been so many attempts. The other thing is that I'm not going to say that my language is going to be special or better
01:36:26
Speaker
than anyone else's in any way. I just hope that when I have enough time to finish it, that it's going to change. No, no, no, no. Fuck the world. Just like my VIM environment. Welcome to definite. Just like my VIM environment, it's made from me. An idealist would be made from me. Yeah. Makes sense. Yeah. It's an interesting project, I think. I think it's
01:36:56
Speaker
in terms of, like you say, the ability to explore ideas and, you know, just to kind of like see where, how far a particular idea can go. I think you're, I mean, everyone's free to do this stuff, you know, why not? Yeah. So, yeah.

Contributions to the Clojure Community

01:37:11
Speaker
And just one, one, before we kind of wrap up a little bit, I do want to say something that I've been impressed by Jay. I mean, I like orchestra, but the thing I kind of knew you, knew you for before orchestra was actually your blogging.
01:37:23
Speaker
I think you're doing a good service to the closure community there, actually, by the amount of blogging you do. Often find little answers. If I'm looking for something, I'll often go to your blog and you'll give a good, long explanation of how things work. I think you've taken some time out there and I really appreciate that. Thank you. Thank you, Ray. I haven't done it in
01:37:49
Speaker
a year or so, which is because of the startup. But I really appreciate the kind words. That's fair enough. But the contributions you've made in the past have been really, really good. So I think we lost to you. Awesome. So it's time to wrap up then. It's been beyond 90 minutes. I hope we have covered, I think, enough, just enough ground.
01:38:13
Speaker
We might have to cut the sun out from the beginning. It's actually in the thing. I need to check.
01:38:20
Speaker
Probably. Oh man, come on. We did two versions of it. We're going to have at least one of them. I agree. You can't rely on computers, as you know, so fucking hell. We might have to do this whole thing again. Yeah, exactly. I think I need to redo this. It's going to be like Broadway show, you know, you just do the same play again and again and again. And then we're going to sing this stuff. Yeah. And we're going to grow to hate each other.
01:38:44
Speaker
Don't we already? I mean, at least we and I, we do. And for serial relationship. Welcome to the club. Relationship, calling a relationship is a bit of a stretch, but yeah, we are acquaintances. We're okay. But anyway.

Wrapping Up and Guest Appreciation

01:39:03
Speaker
So thanks a lot Jay for joining the joining our silly little podcast and you know talking about all the serious shit and it's really nice to know that you know how you progress through I mean having such difficulty in that now you know making a successful career out of it.
01:39:19
Speaker
And obviously, you know, becoming a CD over a startup must be extremely exhausting and also exciting, I would guess. And, you know, getting to do that enclosure and, yeah, I mean, I'll excuse you for a VI, but anyway, I mean, the rest of the stuff seems to be okay. Yeah, yeah, it's, it's, you're right on all those points. Thanks for having me on. Really editorializing at the end here, Matt, you know.
01:39:57
Speaker
He would have been great if it wasn't for VR. 9 out of 10. After 90 years or so, that is something that we're going to write down on your... what do you call that? The thingy that... stone or whatever? Tombstone. Tombstone. Where's stone? He wasn't really a user. Okay. Thanks, man. I think thanks for all the... no information and hopefully I think you'll continue with adversarial closure and maybe...
01:40:10
Speaker
Your life seems to have been worth it. Except for the mini part. But we'll leave that out of the eulogy.
01:40:26
Speaker
Come back again to talk about this stuff again. That would be great. Thanks so much guys for having me. Thank you. It's been an absolute pleasure. That's it from us. Bye bye.
01:41:03
Speaker
Mmm