Speaker 1: Hey folks, welcome back to another episode of JavaScript Jabber.
Speaker 2: This week on our panel, we have a j O'Neil.
Speaker 3: Yo yo yo coming at you live from a broken
Speaker 3: Stater No, sorry, not stater solenoid.
Speaker 4: Okay.
Speaker 2: We also have Steve Edwards.
Speaker 5: Yo coming at you. Just one yo for me from
Speaker 5: Claudy and Cool Portland.
Speaker 1: I'm Charles Maxwood from Top End Devs. And this week
Speaker 1: we have a special guest that is Stephen Haberman.
Speaker 2: Steven, do you want to introduce yourself? I don't think
Speaker 2: we've had you on before.
Speaker 6: Yeah, sure, I will do a singular yo as well,
Speaker 6: coming from Omaha, Nebraska and yeah, yeah, really appreciate you
Speaker 6: having me on. In terms of intros right now, I'm
Speaker 6: a back end you know, team lead type in engineer
Speaker 6: at home Bound. You mentioned construction, so we're talking about Joyce,
Speaker 6: our joystore m home Bounds, a residential construction startup. So
Speaker 6: we besides just building SaaS software, well that's kind of
Speaker 6: the record. We don't build sas software. We're built software
Speaker 6: for the back end up. The main thing our company
Speaker 6: is built Home is build construction resident shams. And yeah
Speaker 6: that's me.
Speaker 1: Yeah, So you talked about the Joyce or m Yeah,
Speaker 1: I think you emailed me about it, and that's how
Speaker 1: how I found it. Anyway, I'm just wondering as we
Speaker 1: get into this, first of all, what problem does it solve?
Speaker 2: Then maybe that's tied up in why you built it.
Speaker 6: Yeah, sure, no, that's a great question. And so where
Speaker 6: where choice came from was a few years ago. We
Speaker 6: were setting up to build our back end stack. You know,
Speaker 6: we're a typescript shop. We do a lot of touch
Speaker 6: script on the front end, react very standards sort of stuff,
Speaker 6: and wanted to do various standard stuff on the back
Speaker 6: end as well, and we picked graph QL as are
Speaker 6: you know, layer in between at the time, which bastually
Speaker 6: still enjoy I know, you know that can be some
Speaker 6: that can be a tangent for later. But so we
Speaker 6: started off writing our graph QL back end in type
Speaker 6: script and you know, went to go pick an orm
Speaker 6: because that's kind of what you do when you do
Speaker 6: these things. This is probably twenty nineteen or so. And
Speaker 6: one of the things that we ran into just right
Speaker 6: away was just pervasive M plus ones and a graph
Speaker 6: QL and back end. So you know, graph CUOL is
Speaker 6: not like your typical endpoints right where in the typical
Speaker 6: web endpoint, you know, slash authors or whatever, you know
Speaker 6: exactly what your endpoint is going to do, so you
Speaker 6: can do one big query kind of upfront to you know,
Speaker 6: preload your data as much as you can and then
Speaker 6: let your logic run, you know, afterwards. But graph ql
Speaker 6: has such a dynamic you know, there is no single endpoint.
Speaker 6: Every quarter is so dynamic that you know, the engineer
Speaker 6: can't just upfront write the exact you know, preload or
Speaker 6: query or whatnot that it's going to magically load the
Speaker 6: data in a perform a way. So we've been using
Speaker 6: another ORM or two at the time, but we're just
Speaker 6: really struggling with M plus ones and so that was
Speaker 6: really joyce first claim to fame is that we had
Speaker 6: started out doing some co generation from the schema and
Speaker 6: that sort of thing, which is very standard now in
Speaker 6: a lot of ORMs. But yeah, we're just wanted to
Speaker 6: fundamentally solve M plus ones and so we started out
Speaker 6: putting Joyce on top of the Facebook data loader project,
Speaker 6: which uses this little you know, that event loop tic
Speaker 6: trick if you guys are familiar with that, to you know,
Speaker 6: if you know the N plus one problem, right, if
Speaker 6: I've got an author and I'm gonna read some books,
Speaker 6: and then the books I'm gonna read the book reviews,
Speaker 6: it's really easy for as you go down your object
Speaker 6: graph to like make a query for every single books, reviews,
Speaker 6: over and over and over and over over right and
Speaker 6: plus one, I guess. You know, let me know. If
Speaker 6: you want me to go slower through the N plus
Speaker 6: one problem.
Speaker 5: Well, yeah, I'm gonna say, I'll give it a real
Speaker 5: quick definition. I wanted to get into that quick before
Speaker 5: we love too far. So basically, if you have, you know,
Speaker 5: your books and author problems, the N plus one problem is.
Speaker 4: Where you do it.
Speaker 5: You know, a query for how would you put it?
Speaker 2: An author?
Speaker 5: So if you have an author that has multiple books,
Speaker 5: you're doing a query for every book, right, give me
Speaker 5: this author in this book, this author and this book,
Speaker 5: this author in this book. Whereas if to solve that problem,
Speaker 5: you can do one big query, give me this author
Speaker 5: and all their books, you know, in one query altogether
Speaker 5: all the book I d's I guess. So that's the
Speaker 5: basic N plus one. I'm sure there's better explanations.
Speaker 4: But that's that's what I have.
Speaker 6: Yeah, And it's really easy to happen to happen. So
Speaker 6: Joyce is an entity based r M. So it is
Speaker 6: very inspired by like Ruby and active record and some
Speaker 6: of the other og entity or ms. You know, if
Speaker 6: you go all the way back to you know, Og
Speaker 6: hybridn ate and Java hybridnade back in the day and
Speaker 6: those sort of things. But there's pros and cons of
Speaker 6: an entity or m type approach where you know, you
Speaker 6: think of your I really like to think of a
Speaker 6: database schema as a graph and a connected graph and
Speaker 6: that sort of thing. But if you think of them
Speaker 6: as objects, it's really easy, which is kind of the
Speaker 6: slippery slope of a leaky abstraction, right, because if you
Speaker 6: think of your entities as objects, which is what entity
Speaker 6: or ms do, it's really easy for programmers to accidentally
Speaker 6: write four loops that cause database queries, right, because if
Speaker 6: you have an author object and you're like, oh, I'm
Speaker 6: just gonna ask for the books, you know, one of
Speaker 6: the things that entity based or ms do is is
Speaker 6: they do this lazy loading of like, oh, you don't
Speaker 6: have the books, so go get those for you, which
Speaker 6: seems really nice. But as soon as you do that
Speaker 6: in a for loop, now you've you've got an M
Speaker 6: plus one, and that's been a problem in or MS,
Speaker 6: just like fundamentally forever. You know, as soon as you
Speaker 6: start doing and what's what's annoying is when it's it's
Speaker 6: more obvious when it's in the small. You know, if
Speaker 6: you've got an endpoint and you're right in your one
Speaker 6: endpoint file and you've right there in the code, you've
Speaker 6: got a for loop, You're like, well, I loaded the
Speaker 6: authors and then within that I'm loading the books. It's
Speaker 6: very obvious within this file that I need to you know,
Speaker 6: hoist my data loading up out of more my fore loop.
Speaker 6: But what's kind of insiduous about entity based or MS
Speaker 6: is is when you start running side effects and other
Speaker 6: drive business logic. Like you know, entity or ms. They
Speaker 6: like to put methods inside the author class to do
Speaker 6: some business logic or have an author life cycle hook
Speaker 6: or or these sort of things. And as soon as
Speaker 6: some of those side effects start, you know accidentally or
Speaker 6: sort of what's the emergent behavior being called in a loop?
Speaker 6: Now you know, you're back to an N plus one.
Speaker 6: And what was maybe interesting about graph QL was just
Speaker 6: like how quickly that happened, right, So like if you're
Speaker 6: in a rails back end, you can go, you know,
Speaker 6: two or three years and you know, fight your you know,
Speaker 6: you have your every two weeks and plus one that
Speaker 6: somebody goes and you know, figures out a production where
Speaker 6: it's happening and tries to magically hoist the data loading
Speaker 6: up to the top of the endpoint. And and that's
Speaker 6: just kind of a cost of doing business in a
Speaker 6: big rails back end. And but you can kind of
Speaker 6: get away with it, you know, until you your scale
Speaker 6: is too big or whatnot. And maybe what's unique, and
Speaker 6: maybe I think why graph ql has maybe not been
Speaker 6: as popular as it could have been is just how
Speaker 6: easy that is to happen. It happens right away in
Speaker 6: graph ql. And so that was really what Joyce set
Speaker 6: up to solve, was we wanted to make a back
Speaker 6: graph ko background back end that didn't suck, to go
Speaker 6: right right, and we leaned on this Facebook data loader,
Speaker 6: which did actually come out of the graph ql community.
Speaker 6: It's it's you know, we're sitting on shoulders of giants
Speaker 6: and those sort of things. But maybe what's unique about
Speaker 6: Joyce is the data loader pattern had been around for
Speaker 6: a long time, but engineers were generally expected to integrate
Speaker 6: it by hand, right, you go into this graph QL
Speaker 6: resolver and do your data loader logic or then you
Speaker 6: know there's i know, the graph quol frameworks like the
Speaker 6: fastifies and we're curious and those were of things that
Speaker 6: you know, they have the data loader pattern built into it,
Speaker 6: but you as the engineer had to go make use
Speaker 6: of it, and that's his boiler plate and nobody does it,
Speaker 6: and it's it's kind of annoying. So Joyce claimed the
Speaker 6: thing was that it's like every operation asterisks, there's one
Speaker 6: or two that don't, especially like paginated it's very hard
Speaker 6: to do passionated autobashion. But otherwise, like every operation and
Speaker 6: joyed auto batches through data loader. So if you asked
Speaker 6: for an author and you accidentally out ask for an
Speaker 6: author and a loop and you asked for fifty, that's
Speaker 6: you know, one sequel call if you accidentally or not
Speaker 6: and accidentally, you know, on purpose, load a bunch of
Speaker 6: books in a for loop, or a bunch of books
Speaker 6: in a life cycle event, or a bunch of you know,
Speaker 6: in a graph QL NaSTA graph col resolver. Basically, every
Speaker 6: operation enjoiced goes through a data liiver for free and
Speaker 6: gets auto batched, and yeah, that's what got us started
Speaker 6: down the path.
Speaker 3: How are you doing that? Do you do you await
Speaker 3: at the end. I'm actually looking for an example on
Speaker 3: your website, you see if I if I can see
Speaker 3: what this looks like. But I'm imagining you must not
Speaker 3: await in the loop because the data obviously isn't there
Speaker 3: if you're waiting for it to batch, So you must
Speaker 3: await at the end of the loop or something like that,
Speaker 3: or or you're putting it in a callback or something
Speaker 3: that some sort of handler rather than a promise.
Speaker 6: Yep, we had some good docs. Let's see if you
Speaker 6: go to goals and then avoiding mplus ones over on
Speaker 6: the OCCA probably describes it pretty well, really soulfully. And
Speaker 6: I mean the wrinkle is that we we sit on
Speaker 6: top of nodes promises. Promises are really amazing because they
Speaker 6: because they're on the event loop and you you always
Speaker 6: have to await them, which which it's ironic because in
Speaker 6: like twenty ten, this was like everything he did in
Speaker 6: node had to do a callback and it was really
Speaker 6: terrible and every you know, everybody hated it. But yeah,
Speaker 6: the people do a node in twenty ten, man that
Speaker 6: you were that was hardcore.
Speaker 2: But banging rocks together?
Speaker 6: Yeah right, Oh what's so ironic is is this how
Speaker 6: well JavaScript is a language and touch script especially on
Speaker 6: top of it, have evolved since then too, you know,
Speaker 6: add acy, kuwait and all of these things, such that
Speaker 6: it's termed what was really annoying? This event move model
Speaker 6: of only one thread at a time. It's a really
Speaker 6: a pretty pleasant environment to work in. And so to
Speaker 6: get back to what data leader this is basically because
Speaker 6: you have to await everything anyway, the promise in the
Speaker 6: event loop is basically what sets a really fast timer
Speaker 6: for you. So like, pretend we weren't in JavaScript, we
Speaker 6: were in Java or you know, o G Java or
Speaker 6: something like this, and you're like, okay, well I'm going
Speaker 6: to do you know, ten wire calls or twenty of
Speaker 6: wire calls. But I don't really know how many I'm
Speaker 6: going to do, right, because before you start your four loop,
Speaker 6: you don't know if there's five books or ten books
Speaker 6: or you know how many books that four loop is
Speaker 6: going to go through. And so you kind of but
Speaker 6: but you don't you want to make that first book
Speaker 6: call and I have it not go right away, right,
Speaker 6: because like as soon as the io leaves the server,
Speaker 6: you know there's your inmplus one. So you want to
Speaker 6: go through your your probbial four loop. You know, maybe
Speaker 6: this is a graph QL server run time or whatever,
Speaker 6: but you know, let's think of it as a four loop.
Speaker 6: You want to like ask for book one, ask for
Speaker 6: book two, ask for book three, ask for book four,
Speaker 6: and have these like not actually happen yet. You want
Speaker 6: them to just be I'm going to goad and jump
Speaker 6: to the term promises. You want to to be a
Speaker 6: promise of a book, and you want to wait until
Speaker 6: you've asked for all of the books. And there's the
Speaker 6: hard thing is you don't know when you're done in
Speaker 6: most environments, right, So like an og JAVA or something
Speaker 6: like this, you'd write a four loop and you would
Speaker 6: get to the end of the fore loop and then
Speaker 6: you would have to like tell the run time to like, Okay,
Speaker 6: I'm at the end of the fore loop, ask for
Speaker 6: all my books. You know, flush my book calls and
Speaker 6: you could do that, but nobody does. And so what's
Speaker 6: really interesting about promises instead is that the very first
Speaker 6: you know time you asked for a book, it puts
Speaker 6: a little I want to use the term poison building,
Speaker 6: but that's not quite right. It puts a little hint
Speaker 6: at the end of the event loop, which is going
Speaker 6: to run right away, right right. It's not like a
Speaker 6: set and Millie's fifty or a set Milli's one hundred.
Speaker 6: It just says, like, you know, in just a little bit,
Speaker 6: the next tick, right, plush, plush, my sequel calls and
Speaker 6: that's it. Like that, that's the end of the trick,
Speaker 6: and it's It's really pretty surprising how such a simple
Speaker 6: little idea can you know, fundamentally transform the performance in
Speaker 6: ergonomics right of choice, like with joice and things. Using
Speaker 6: data Vader, you get this really elegant you know, ervergence, autobatching.
Speaker 6: It just works, it always works. You don't have to
Speaker 6: do anything to get it.
Speaker 3: Yeah. I think that Objection does something similar to this too,
Speaker 3: at least it does with its query builder. You may
Speaker 3: have taken it a step further and that you're you're
Speaker 3: exposing a query builder kind of implicitly, so as you're
Speaker 3: going through the loop, the query builder continues until you're
Speaker 3: done with the loop. I haven't actually, I don't know
Speaker 3: if I've actually tried this an objection to know whether
Speaker 3: or not it's doing something similar with with the n
Speaker 3: plus one problem. But it the query builder in general
Speaker 3: is built that way, but it's more of a chaining
Speaker 3: type of thing, like you you can keep chaining the
Speaker 3: query builder and then it waits until next tick to
Speaker 3: actually resolve the query builder into something. So by the
Speaker 3: time you await it, you're awaiting whatever is at the
Speaker 3: end of the chain, not what's at the beginning of
Speaker 3: the chain, or or the chain collapses. I'm not really
Speaker 3: sure what the how the mechanism works, but I do
Speaker 3: know that it has it has similar magic where there's
Speaker 3: state management inside of the query builder that's waiting for
Speaker 3: that next tick in order to resolve the query builder.
Speaker 3: And this this looks This looks similar, but it's got
Speaker 3: more of a a naive looking you know, like like
Speaker 3: it looks naive and then you it look it looks
Speaker 3: like you have a dot each, So rather than using
Speaker 3: the four loop on it, you use it. Well, I'm
Speaker 3: I see where you're you're building the query. I don't
Speaker 3: see where you actually use the query. I saw one example,
Speaker 3: like there was a dot each. Is that what you're providing?
Speaker 3: So people don't people don't call four each, they call
Speaker 3: dot each.
Speaker 6: I'm trying to find that dot each that you're referencing.
Speaker 6: Oh you might.
Speaker 3: Oh that was that was an example of ruby code.
Speaker 6: Never mind, Yes, sorry, yeah.
Speaker 2: That is a very ruby thing.
Speaker 6: Yes, yeah, yeah, you know I didn't actually use rails
Speaker 6: for like years and years and years, but did just
Speaker 6: stuff rails and active record to be thoroughly impressed with
Speaker 6: the ergonomics and and so Joyce is kind of unashamedly
Speaker 6: tries to you know, borrow as much ergonomics and best
Speaker 6: practices as we can for active records. And so you'll
Speaker 6: see some active record isms, especially in the docks of
Speaker 6: you know how well, and particularly the M plus ones.
Speaker 6: I guess that would be one thing I think we
Speaker 6: kind of use this as a talking point is how
Speaker 6: active record, I would have heard, has not really solved
Speaker 6: like in the same way the joyst has solved M
Speaker 6: plus ones. You know, inactive record is is kind of
Speaker 6: this whack a mole job of finding where you need
Speaker 6: to do your load hint, you know, preload hint. And
Speaker 6: we can get into it maybe a little later, but
Speaker 6: but Choice does have the concept of preload hints to
Speaker 6: make all of your weights go away, which which is
Speaker 6: maybe a tangent. And so in Joyce you can do
Speaker 6: preloadhnts because you'll get more ergonomics and you don't have
Speaker 6: to awight coat, but you don't have to, like you'll
Speaker 6: still get this emergent auto batching behavior even without. And
Speaker 6: it's interesting you mentioned objection. I'll have to go. Look,
Speaker 6: it's been a while since i've you know, for sure
Speaker 6: taken a look at the other or ms around. I
Speaker 6: think a lot of the ORMs that I've seen, you know,
Speaker 6: do require these hints for the engineer to like know
Speaker 6: upfront what's going to happen, you know, to know upfront
Speaker 6: that in my query I need to ask for this,
Speaker 6: and in my query I need to ask for this
Speaker 6: because later somebody is going to use it, right, because
Speaker 6: later somebody is going to do a for loop. And
Speaker 6: that's really the beauty of the approach is it's there's
Speaker 6: you know, any emergent behavior that actually accidentally runs accidentally
Speaker 6: or on purpose runs in a loop gets the gets
Speaker 6: the autovension.
Speaker 3: Okay, yeah, so if I I would love it if
Speaker 3: with your N plus ones lazy loading in a loop, example,
Speaker 3: if if it continued like the next one or three
Speaker 3: lines or whatever comes after this, I get what's happening there.
Speaker 3: But then I wonder, how would I use this, because
Speaker 3: it because you know, every everything's alighted away as to
Speaker 3: how I use it, And just for the mental model
Speaker 3: of it, I'm like, do it, do I await it
Speaker 3: a final time? Or do I what I.
Speaker 6: See what you're saying. Maybe go to the load safe
Speaker 6: relations page right below this you'll get a little bit
Speaker 6: of a few more Synceax examples of like using acting
Speaker 6: the entities and the relations on the entities, so we
Speaker 6: do wrap our relations, you know. So this would be
Speaker 6: author dot books, you know, that's the books relation or
Speaker 6: author dut publishers, the publisher relation, and some of the
Speaker 6: og ORMs like type orm at least back when I
Speaker 6: did it, and I'm ninety percent sure they still do that,
Speaker 6: and even the java ORMs the hybernates in the world.
Speaker 6: What a model of those like? As the array directly right,
Speaker 6: author dot books is literally a book array, but it's
Speaker 6: not really because it has to be lazy loaded, right,
Speaker 6: and so then they do various proxy lazy loading magic
Speaker 6: to make it look like a book array as soon
Speaker 6: as you access it. We go ahead and wrap all
Speaker 6: of our relations and these little rappers that you can
Speaker 6: either ask to be loaded. So like on that load
Speaker 6: safe relations, you'll if the publisher's not loaded yet, the
Speaker 6: type system knows about it. If this is kind of
Speaker 6: the tangent that I was alluding to earlier, is that
Speaker 6: when I used type orm back in the day, because
Speaker 6: of this, the type system would never know whether something
Speaker 6: was loaded or not. Right, if you just gave me
Speaker 6: an author and I wanted to get to the books,
Speaker 6: sure I could do author books, but but I didn't
Speaker 6: really know whether that had been loaded or not.
Speaker 3: And if they're all monads, it's monads all the way down.
Speaker 6: Well you're getting yes, you're getting that. Yeah, and so
Speaker 6: correct use of monads. Nice. No, Actually, well, you guys
Speaker 6: talked about effect recently, right, how those guys on the podcast.
Speaker 6: I think that's how that go by the TS effect
Speaker 6: Or maybe I'm getting my podcast mixed up. Well, the
Speaker 6: promise promise is basically a monad unless you talk to
Speaker 6: the TS affect people, and the TS effect people have
Speaker 6: strong opinions how promise is not the perfect monad, and
Speaker 6: they have their own effect that is the more perfect monad.
Speaker 6: Which is fine, but I I don't know. I think
Speaker 6: it's a little maybe academic and promising is just fine
Speaker 6: to me, I guess so for.
Speaker 3: The people at home, yeah, that have never encountered somebody
Speaker 3: who can both know what a monad is and explain
Speaker 3: it in a way that other people can understand at
Speaker 3: the same time. I am the singularity. Now, a monad
Speaker 3: is simply an object that encapsulates a value that is
Speaker 3: not the value itself. So, for example, if you have
Speaker 3: answer is equal to forty two, that's a value. If
Speaker 3: you were to wrap answer in a promise so that
Speaker 3: you have to do something else like call dot then
Speaker 3: or in some way unwrap it in order to get
Speaker 3: the value forty two out of it, that's a monad.
Speaker 6: Yeah, and I think it's applicable here because I think
Speaker 6: one of the things moments are great about is delaying evaluation.
Speaker 6: You know, to your example, when you ask for forty
Speaker 6: two and it's just like forty two is right there.
Speaker 6: You know, there's no ability to do like metaprogramming around
Speaker 6: that or you know, but if you're you know, you
Speaker 6: mentioned monad wrapping the value that you have to ask
Speaker 6: for the fact that monad's fundamental and promises. You know,
Speaker 6: is is if you squint a monad, you have to
Speaker 6: ask it for its value. That that delayed execution is
Speaker 6: what allows you to do fun things like autobatchet sequel calls.
Speaker 5: So one thing that's interesting here and looking at this
Speaker 5: is I come from them. I live in the PHP
Speaker 5: world of Claravel, and I'm sing a heck of a
Speaker 5: lot of similarities here, sure, just in terms of relationships
Speaker 5: and definitions and how you load them, how you get
Speaker 5: them the syntax hopefully a good way you're using Yes, yeah,
Speaker 5: you're using dot instead of you know, as an arrow
Speaker 5: since P versus no. But yeah, so that to me
Speaker 5: that looks very similar.
Speaker 6: Yeah, I mean we try to be very boring in
Speaker 6: a good way and then like, uh, you know, but
Speaker 6: still have the value adds that or innovations that make
Speaker 6: it different so to say.
Speaker 7: But yeah, but yeah, you know, Aja you had mentioned,
Speaker 7: what does it just look like to even get the
Speaker 7: data out that this next a load safe relations hopefully
Speaker 7: shows you.
Speaker 6: It's very soon. You know, you go to you have
Speaker 6: an author, you go to your publisher. You ask for it, yes,
Speaker 6: for the books, you ask for the things. Maybe the
Speaker 6: second code example of the load safe relations is an
Speaker 6: interesting thing to talk about because it shows the difference
Speaker 6: between like a dot load that returns a promise versus
Speaker 6: a dot get that returns it synchronously. So promises are
Speaker 6: actually kind of annoying. They're very boiler plate because you've
Speaker 6: got to await everything. Right. So if you've got a
Speaker 6: little you know, let's say ten to twenty line method,
Speaker 6: and you want to go from you know, the books,
Speaker 6: to the book reviews to the review comments, and every
Speaker 6: single one of those is is as you know, you're
Speaker 6: gonna have to await promise all your top loop. You're
Speaker 6: gonna have to wait, promise all your inner loop, and
Speaker 6: you're gonna have to wait, you know, promise all your
Speaker 6: third loop, and it, you know, and then flat map
Speaker 6: the promises together and something something something something, and you
Speaker 6: can do it. But you know it's I couldn't you know.
Speaker 6: I guess I'd ask GDP to write it for me
Speaker 6: the first time round. But but what joyceless you do
Speaker 6: with these load safe relations is if you do? You know,
Speaker 6: So I just made a big deal about how the
Speaker 6: auto bashing of our sequel behavior is very emergent. You
Speaker 6: don't have to declare load hints and preload hints to
Speaker 6: get that performance of those. But if you do, you know,
Speaker 6: at a load hint, you know one of these like
Speaker 6: I want the author and I want the publisher and
Speaker 6: the comments in the books, which I think is you know,
Speaker 6: aj kind of like the objection query builder is my
Speaker 6: guess of what that syntax looks like.
Speaker 3: I've tried to forget it. I've tried, I've tried to
Speaker 3: erase it from my memory. I'm done with r MS,
Speaker 3: by the way. I'm a sonic for node and CQC
Speaker 3: for everything else. They've burned me too many times and
Speaker 3: I just can't find the value in the end of
Speaker 3: the Yes.
Speaker 6: Well that there's our second half of the recording, for sure,
Speaker 6: we can get to that. The but you know, back
Speaker 6: to the loads versus the gets is that if you
Speaker 6: do do these loads, which are optional you don't have
Speaker 6: to do for performance, it actually changes the types and
Speaker 6: the type system. So these get methods that let you like,
Speaker 6: there's no a weights now, right, so like it used
Speaker 6: to be if I had a loop and a loop
Speaker 6: and a loop, but I have to await every single
Speaker 6: time I touched a relation. If you do these load hints.
Speaker 6: We'll add in because joys and the choice run time
Speaker 6: and the typescript type system knows the data is there,
Speaker 6: we'll add synchronous methods for you to be able to
Speaker 6: get at it. Just do this, get to this skit,
Speaker 6: and it's as if it was a raised in memory
Speaker 6: or our entities of memory, because it is now and
Speaker 6: we know that it is now right. Whereas if you
Speaker 6: hadn't done that load hint, we don't really know. You know,
Speaker 6: there might be an I'll call there and so you
Speaker 6: have to await. But I would say that's probably the
Speaker 6: second on the list of what you know, what makes things,
Speaker 6: what makes joyce novel and pleasant, it is maybe this
Speaker 6: load safe relations to just remove some of the aweight
Speaker 6: dunks that you would know.
Speaker 3: You're telling me that by virtue of calling aweightauthor dot
Speaker 3: books dot load online three online four, the type script
Speaker 3: checker knows that author dot books dot get exists, and
Speaker 3: it wouldn't know that if online three I hadn't run
Speaker 3: the load Uh.
Speaker 6: Yeah, you know, if you if we're on the same
Speaker 6: we're on the load safe relations. We're in the second
Speaker 6: code block of that page.
Speaker 3: The second code block of that page Okay, now I'm
Speaker 3: looking loads. Yeah, the very first section. Now looking at
Speaker 3: the second code block. Okay, author, dot publisher, dot get ye.
Speaker 3: And you're saying, you're saying that because oh no, this
Speaker 3: is oh this is different, this is different. Okay. So
Speaker 3: it's looking at what load returns, and it's determining from
Speaker 3: what load returns. I was actually looking in the second
Speaker 3: section where or is it the third section? I was.
Speaker 3: I was a little bit further down. Okay, yes, I
Speaker 3: was a little bit further down. I was looking at
Speaker 3: the after it says yuck, and it says anyway, I
Speaker 3: think I I think I get, I think I get
Speaker 3: what's going on. But no, my question still stands, so yuck.
Speaker 3: Given this compilation, some r ms in the JavaScript space
Speaker 3: sometimes fudge collections must be a sync da dad and
Speaker 3: then it and then it has three lines here and
Speaker 3: so there's one line where it awight dot load for author,
Speaker 3: and then there's another line for a weight dot load
Speaker 3: the books. But that one is not doing books equals right.
Speaker 3: So this one, the type checker still wouldn't know for
Speaker 3: certain that dot get exists because this one didn't do
Speaker 3: a book's equals authored books dot load right. Right, yeah, okay, okay,
Speaker 3: all right, now now I'm on board because typescript does
Speaker 3: a lot of magic. It does a lot of magic,
Speaker 3: and I have sure I have fought with some of
Speaker 3: that magic. And you were you were teaching me new
Speaker 3: I thought you were teaching me new magic that I
Speaker 3: needed to know. But but no, it's it's it's it's
Speaker 3: old magic, old magic. Got it.
Speaker 6: I'm with you, right, Yeah. The example could probably be
Speaker 6: cleaned up a little bit. I don't know why the
Speaker 6: camera keeps going out of focus, but uh, the intent
Speaker 6: was to show that type O REM was probably the
Speaker 6: m other ORM I've used the most before Ritey joiced it,
Speaker 6: and it was five years ago, so I have to,
Speaker 6: you know, add all sorts of disclaimers that maybe they
Speaker 6: fixed things camerah that you know, you'd have to like
Speaker 6: magically access a relation in one part of the code
Speaker 6: base to then like access it in another, and it
Speaker 6: would just it would just work over there and you
Speaker 6: wouldn't have to await it. And I don't know, it
Speaker 6: was kind of magic magic at the distance, as I recall,
Speaker 6: But but disclaimers, that was a while ago, and it
Speaker 6: was what that section was attempting to show, but yeah,
Speaker 6: can probably be for stuffed a little bit.
Speaker 3: Right, Well, I'm with you. I think that this is
Speaker 3: in some ways, like like many good solutions. When you
Speaker 3: see it, it's obvious and you wonder why doesn't everyone
Speaker 3: do it this way? Like looking at it, it doesn't
Speaker 3: look like, oh, you did something super intelligent that required
Speaker 3: the brain of a thousand men combined into one. Sure,
Speaker 3: you know, it looks it looks like well, dove, of
Speaker 3: course you do it this way, but other people weren't
Speaker 3: doing this way. So you are the genius. You're the
Speaker 3: genius that discovered the simple way to do it.
Speaker 6: Sure, I found I found data loader first.
Speaker 4: I guess.
Speaker 6: But yes, yeah, yeah, I mean that's kind of the
Speaker 6: intent is is that again? You know, shout out to
Speaker 6: the rails active record fos of boring is good? Right,
Speaker 6: you know some of the other things that we do
Speaker 6: try and do well, I'm this might tiptoe aj into
Speaker 6: your like orems you know, are terrible sort of thing.
Speaker 6: We try to like make first class notions around domain
Speaker 6: and modeling. Right, so like we try to think of
Speaker 6: not just tables in the database, but try and think
Speaker 6: of like our entities as a graph. And you know,
Speaker 6: how are we modeling the world? You know, I like
Speaker 6: domain driven design, although there are can they're sign a
Speaker 6: kind of some complexities in cargo culting ish around some
Speaker 6: of the domain driven design stuff.
Speaker 3: But you'll have to give me the simple explanation of
Speaker 3: domain driven design because with all of the you know,
Speaker 3: the xdds that exist.
Speaker 6: I mean, it's an older notion from so. Eric Evans
Speaker 6: was the guy in you know, probably twenty ten or so,
Speaker 6: two thousand and five or so that popularized the term.
Speaker 6: Really a lot of it was, you know, you biquitous
Speaker 6: language and engineers speaking in the same language as your
Speaker 6: business users and uh, you know, really modeling the entities
Speaker 6: in their world, you know, in the code and that
Speaker 6: sort of thing. And well, for me, that was the
Speaker 6: you know, eighty percent of what domain driven design was about.
Speaker 3: Anyway, Sorry, I heard words. What did you say? Take it?
Speaker 3: Take it one take it one layer lower, like like
Speaker 3: remove the buzz the buzzwords from it if you can.
Speaker 6: And yeah, well, so ubiquitous language is like you know,
Speaker 6: if the if you talk to your uh you know,
Speaker 6: so I do a lot of back office ish sort
Speaker 6: of software, right, so so if I'm talking to a
Speaker 6: user of my software and they they call something a bill,
Speaker 6: I probably want to call that a bill in the
Speaker 6: code base, right, like like we want to remove these
Speaker 6: sort of like talking past each other where you know,
Speaker 6: I call the or or I don't. I don't I
Speaker 6: call it something different, or I don't even have the
Speaker 6: concept of a bill right it with within the code base,
Speaker 6: or you know, for any of the other you know
Speaker 6: sort of workflow. You know, you know, I'm falling back
Speaker 6: on like you know, uh, crowd app, you know, credas,
Speaker 6: enterprise spreadsheets and those sort of things where you're you're
Speaker 6: making software for business users running a business that you know,
Speaker 6: all of the business concepts have a matching concept in
Speaker 6: the code that kind of matches it as much as
Speaker 6: you can, and you know you don't want to, yeah,
Speaker 6: as much as you can. And so that's the the
Speaker 6: ubiquitous language side of things, and and the domain driven
Speaker 6: design sort of things is kind of a set of
Speaker 6: patterns around you know it really kind of I want
Speaker 6: to say it's at the heart of it. But you know,
Speaker 6: if there's a bill concept to the user, you probably
Speaker 6: have a bill entity. And if the user has a
Speaker 6: you know, bank account concept, you probably have a bank
Speaker 6: account concept and that sort of thing. So just you know,
Speaker 6: modeling the world that you're building your system around in
Speaker 6: your code base, I guess better explanation hopefully.
Speaker 3: So, so just more of a one to one between
Speaker 3: the way that you would speak about the business rules,
Speaker 3: as in, when a customer places an order, it puts
Speaker 3: an eyem in the shopping cart and then it triggers
Speaker 3: the payment, So you would you would just have a
Speaker 3: pretty much a one to one with that, where okay,
Speaker 3: then there's a shopping cart object, there's a customer object,
Speaker 3: there's a there's a payment object. So just the idea
Speaker 3: of being fairly fairly one to one, not not having
Speaker 3: too many abstractions over what the the the need is
Speaker 3: for the customer to get done and the way the
Speaker 3: software does the design is built.
Speaker 6: Okay, Yeah, which you know you mentioned the you know
Speaker 6: a lot of the joyisms like that they look very
Speaker 6: natural and and kind of default er. What I think
Speaker 6: the ubigotis language is kind of the same thing. I
Speaker 6: don't think it's super innovative per se. It's just a
Speaker 6: term for I think probably what most people do by
Speaker 6: default anyway, you know, potentially, But yeah, well, and so
Speaker 6: along the lines of the domain modeling side of things.
Speaker 6: We try to, you know, add some first class features
Speaker 6: on top of just just a table, just a database
Speaker 6: table and just columns. Right, so we try to be
Speaker 6: very explicit about well we can get into some of
Speaker 6: our reactivity sort of things. But you know, even if
Speaker 6: you start talking about database tables, you know, some of
Speaker 6: your tables are you know, primitive columns, which is great,
Speaker 6: and some of them are your foreign key columns which
Speaker 6: are your relations and all. All of that's fine. We
Speaker 6: want to talk about let's do a cross sense of
Speaker 6: the validation rules. So you know, while this might get
Speaker 6: a j will tiptoe into your you know, just stats
Speaker 6: for ORM sort of discussion. Like one of the things
Speaker 6: that I do, I think entity ORMs so and and
Speaker 6: the economy between. So I mentioned the term entity based
Speaker 6: or amalot, I would say. The other style of working
Speaker 6: with data is quiry builders, right, So the quary builders
Speaker 6: of the node world are like the prismas Drizzle are
Speaker 6: probably the big two these days. Keithley is another, if
Speaker 6: I'm saying their name right. But on the query builder
Speaker 6: side of the spectrum, you issue every single call that
Speaker 6: the ORM does. You do directly, right, you make the
Speaker 6: query and it the quary builders just facilitates. You're doing
Speaker 6: that in a very you know, nicer syntax than writing
Speaker 6: raw sequel, and you you know, hopefully you'll get some
Speaker 6: type safety from it because the quarry builder looks at
Speaker 6: your database schema and does some type checking of your
Speaker 6: typescript DSL and that sort of thing.
Speaker 3: So that's maybe maybe it does, maybe it doesn't.
Speaker 6: Sure, yeah, yeah, and so so those are the quarry
Speaker 6: builders in But my maybe slight quibal is that I
Speaker 6: don't I almost don't consider those r ms. I've got
Speaker 6: a plug blog post I want to go right about
Speaker 6: like what the O in RM means. And I guess
Speaker 6: maybe this is just my I know, this is my biases,
Speaker 6: but the O and an r M to me has
Speaker 6: always kind of meant an entity, right, Like, if I'm
Speaker 6: using an r M, I expect.
Speaker 3: There to be an oh for entity, Yes, you know,
Speaker 3: firm firm.
Speaker 6: I guess it's really the term I'm looking for here.
Speaker 3: But yeah, yeah, for the ten.
Speaker 6: To fifteen years I used r ms like you know,
Speaker 6: the hybernates and the GPAs and all of those other
Speaker 6: in the active record, right, Like every RM i'd used
Speaker 6: up until like three or four years ago in the
Speaker 6: note community had entities. Maybe you had an author file,
Speaker 6: a book file, a book review file, a comic file,
Speaker 6: and maybe it was jop a code, or maybe it
Speaker 6: was Ruby code or whatever, and it seems like THEE
Speaker 6: the go ahead.
Speaker 3: I think that the common pattern is that the O
Speaker 3: r M is built on the queer builder, and so
Speaker 3: the query builder trips through the ORM. Because you use
Speaker 3: the ORM, it uses the query builder. It returns you
Speaker 3: a partially built query builder object. Then you add on
Speaker 3: dot select name, age, and so the ORM is giving
Speaker 3: you In many cases it's giving you both. Because to
Speaker 3: the point of you know, the conference slides of graph QL, Yeah,
Speaker 3: why load the entire ten fifteen columns if all you
Speaker 3: need is two? And the answer to that is, of course,
Speaker 3: well you're going to need the other ten or fifteen
Speaker 3: otherwise you wouldn't have them, so you might as well
Speaker 3: load them and then just cash them.
Speaker 6: That's cheap. Yeah, we're in a row orient in storage.
Speaker 6: So no, you're you're right that For a long time,
Speaker 6: and if you said ORM, it did mean both. It
Speaker 6: meant you had an author file and a book file
Speaker 6: and a book review file. But the worms came with
Speaker 6: the quiry builders, like the hybridates of the world, so
Speaker 6: that you could, you know, or ms kind of by default.
Speaker 6: Of course, you're really good at the very boring credit
Speaker 6: quaries like an insert update the lead of an author
Speaker 6: of book, you know, book review. They can knock those
Speaker 6: things out any any day, every day. What gets hard
Speaker 6: is the queries that like, oh I want to join
Speaker 6: and left join over here and then group by then
Speaker 6: having and all of those other sort of things is
Speaker 6: really where ORMs are not so great, but historically have
Speaker 6: come with quiry builders in them somewhere to at least
Speaker 6: try and let you do that, which maybe another unique
Speaker 6: thing about joys. We don't have that. Like, I think
Speaker 6: that's a very hard problem to solve, and I haven't
Speaker 6: decided to tackle it yet just because I mean, the
Speaker 6: stuff you can do in SQL, I'd rather just write SQL.
Speaker 6: Like I think there's a yeah, yeah, you know that
Speaker 6: there's this psychotomy where people think that, well, if you
Speaker 6: use an ORM, you have to do everything through the ORM,
Speaker 6: or if you do a quiry builder, you have to
Speaker 6: do everything through the quiry builder.
Speaker 3: And now we're getting into interesting. Yeah, now we're getting
Speaker 3: into a very interesting area. And I and now I'm
Speaker 3: very very interested, you know, to hear more of what
Speaker 3: you're saying, because sure, I think that from from my perspective,
Speaker 3: from what I've seen, you know, being in software the
Speaker 3: last twenty years, and O rms have existed longer than that.
Speaker 3: But from what I've seen, the r RM came about
Speaker 3: because Postgress became popular, and suddenly people wanted the the
Speaker 3: you know, the hoity toity people that were using postgress
Speaker 3: my rather than my sequel, or the people that just
Speaker 3: wanted to do the lowly people that were using sql
Speaker 3: light rather than my sequel. They wanted to be able
Speaker 3: to say, my open source project is for you too,
Speaker 3: and so rather than having their project work really well
Speaker 3: with my sequel, they started making compromises so that would
Speaker 3: work just as poorly with Postgress or with sql light
Speaker 3: as it would work with my sqel. But from my
Speaker 3: from my framing, that's how O rms came about was
Speaker 3: instead of let's let's just use the tools of the database,
Speaker 3: well let's castrate them so we might as well just
Speaker 3: be using ago.
Speaker 6: Yeah, that's an interesting.
Speaker 3: LONGO didn't exist yet, right.
Speaker 6: Right, right, right, No, you're right, there is a race
Speaker 6: to like the lowest common denominator across databases, you know,
Speaker 6: for the r ms that so you know, Joyce is
Speaker 6: very tiny, and so we only support post grade right now,
Speaker 6: which is not really on purpose so to say that's
Speaker 6: just the only thing that we've needed personally.
Speaker 3: But because you're hoiity toity, No, we're small.
Speaker 2: I just.
Speaker 3: I'm easy. I'm easy because I was saying, that's.
Speaker 6: Paying me to go go, right, But my sequel driver
Speaker 6: if you want, I hope I hope.
Speaker 3: You never do. But I hope you never do. I
Speaker 3: hope that you just keep because some of the great
Speaker 3: projects out there, they as they grow, they start saying, oh,
Speaker 3: well we are like this is happening with SQL see right.
Speaker 3: SQL see was a postgress only thing. And now they're like, okay, well,
Speaker 3: we're also going to support my sequel and we're also
Speaker 3: going to support sequel light. And rather than just supporting GO,
Speaker 3: which I'm totally fine with them doing the Jason format
Speaker 3: because that's a way of abstraction that seems right, they're like, oh,
Speaker 3: and we're gonna have a Typescript specific driver and we're
Speaker 3: gonna have a Python specific and so now the project's
Speaker 3: kind of you know it ye, Like, I guess it's
Speaker 3: not a paid product, so you can't complain. The author's
Speaker 3: gonna do whatever the author wants to do. But instead
Speaker 3: of chasing dollars, the author's chasing stars, which means that
Speaker 3: now you get more stars by introducing to a new
Speaker 3: community once you've captured the stars of one community. So
Speaker 3: making your Postcress Driver better isn't going to get you
Speaker 3: but another ten percent of stars. Creating a my sequel
Speaker 3: driver is going to double your stars, right, and so
Speaker 3: then the quality of the Postcress Driver, or at least
Speaker 3: the response time to issues with the Postcress Driver go down.
Speaker 3: When it's like, but this is why I wanted it.
Speaker 3: So I hope you never support my sequel, not because
Speaker 3: my sequel is bad, but just because if you could
Speaker 3: focus on doing one thing, well yeah, then it'll work.
Speaker 6: Well yeah, go ahead.
Speaker 2: Go ahead, Steven, and I'll jump in.
Speaker 6: Well, I was gonna say I should just hang up
Speaker 6: now because because like, uh, Joyce doesn't have a lot
Speaker 6: of users, and one of the reasons I'm here is like, hey,
Speaker 6: a lot of people should use Choyce. You know, we
Speaker 6: think it's great we're kind of fan boys of it obviously,
Speaker 6: and I love for more people use it, but they're
Speaker 6: gonna ask for more things. They're going to ask for
Speaker 6: sequel support with my sequel support, and they're gonna ask
Speaker 6: for this, and they're gonna ask for this, And I
Speaker 6: really have qualms, you know, go back and forth. Like
Speaker 6: when you're a project small and dedicated, you can do
Speaker 6: whatever you want to it and and we can do
Speaker 6: that now.
Speaker 3: But just charge money, Just charge money. Just say it's
Speaker 3: it's it's thirty bucks a year, it's ninety nine bucks
Speaker 3: a year for all right, ex features.
Speaker 1: I'm going to say my say, I'm gonna say what
Speaker 1: I'm thinking here because I mean so much of this
Speaker 1: kind of cuts both ways, if you know what I mean, right,
Speaker 1: So it really pays off to have a focused o
Speaker 1: RM that just does the stuff people want to do
Speaker 1: right and and to make the case right, if you're
Speaker 1: using an orm for Mango, it only supports Mango, right.
Speaker 1: If there's if there's something else that kind of looks
Speaker 1: if you squint at it like Mango and kind of
Speaker 1: works if you squint at it like Mango.
Speaker 2: Nobody's writing extensions for those other systems.
Speaker 1: Right, And I get that we're kind of in a
Speaker 1: world where yeah, all of the different sequel based systems
Speaker 1: use sql ra if, right, So you know, so you
Speaker 1: can kind of flirt with it. But the thing that
Speaker 1: I'm seeing too, right is so I you know, it's
Speaker 1: funny because we've all kind of said I work in
Speaker 1: not JavaScript most of the time these days. Ors you
Speaker 1: know something like that, right, Laravel or go or in
Speaker 1: my case Ruby. One thing that I've seen with this
Speaker 1: is with the with the Ruby with active record. Yeah,
Speaker 1: you use the post gross driver and then active record
Speaker 1: takes advantage of that to query the database. But if
Speaker 1: you want other features that postgress provides that are not
Speaker 1: you you know, specifically provided by active record or specifically
Speaker 1: provided by that driver, you can pull in other libraries
Speaker 1: that add the functionality. And so it really depends on
Speaker 1: what your goal is in my opinion, right, is your
Speaker 1: goal just to solve the particular problem that you guys have, right,
Speaker 1: Because if that's the case, and it does a really
Speaker 1: good job of it, and then yeah, other people who
Speaker 1: are using PostgresSQL and are writing back end code, I'm
Speaker 1: presuming you're using express or something. You're right, Yeah, pull, pull,
Speaker 1: in pull in joice right, makes sense. If you're using
Speaker 1: my SQL then and you really want a joicst like thing,
Speaker 1: you can fork it or you can find something else.
Speaker 3: But yeah, just give people a script that installs Postgress correctly,
Speaker 3: with the users set up to be able to create.
Speaker 6: There there we go. Yeah, I do think well, you
Speaker 6: mentioned active record. I think active record has walked the
Speaker 6: line really well of sporting a lot of databases and.
Speaker 1: Yeah, but it does not like I use Postgress, and
Speaker 1: it does not do everything that Postgress does. It does
Speaker 1: a vast majority of the things that most people use,
Speaker 1: and so it does a really good job there, but
Speaker 1: it doesn't do everything.
Speaker 6: Yeah, I think some of this might get back to that,
Speaker 6: Like I'm the you know, when do you use the
Speaker 6: or M and when do you just use a red
Speaker 6: sequel and a quary builder? Right? And that my impression,
Speaker 6: and maybe it's my bias and my assumption is that
Speaker 6: a lot of people have been burned by the r
Speaker 6: m's of the world. I'm sure there's a lot of reasons.
Speaker 6: We can get to yours when you get to but
Speaker 6: is this like obsession with putting everything that some projects
Speaker 6: have not every but a lot of projects have with
Speaker 6: like making everything go through the ORM, right, which, then
Speaker 6: you know, Charles, you run into like, well, the ORM
Speaker 6: doesn't do this for post creder, doesn't do that for
Speaker 6: you know, my sequel or whatnot. And I don't have
Speaker 6: that strict of an opinion about it insofar as like
Speaker 6: I think borms that do ninety percent of your applications
Speaker 6: boring cred quarries, right, which which is by far the
Speaker 6: far far majority of queries we do, is super boring
Speaker 6: crub that is probably exactly the same sequel across five
Speaker 6: to eight top databases.
Speaker 4: Right.
Speaker 6: I think Joyce really can pretty easily support the my
Speaker 6: squels and seql lights and all of those for the
Speaker 6: subset of you know, really common crud queries. And then
Speaker 6: like you know, when you need to escape patch out
Speaker 6: to like the you know whatever left joint syntax that
Speaker 6: only post grade supports, I think that's perfectly fine. Go
Speaker 6: use your you know, uh just wright, go write some
Speaker 6: raw SQL and do some you know, low level quarries
Speaker 6: where you need it. And I think that happens so
Speaker 6: when you need it, you really need it, but it
Speaker 6: happens so frequently in a large application. It's like sub
Speaker 6: five percent of the time, probably five ten percent of
Speaker 6: the time that you can still get a ton of
Speaker 6: benefit from the entity or side of things through all
Speaker 6: of the super boiler plate stuff. And and also for
Speaker 6: the that super boiler place stuff I think is also
Speaker 6: what's most common commonly is supported across the you know,
Speaker 6: most popular databases. So we are a post ray right now,
Speaker 6: but only But I don't think it'll be a big
Speaker 6: shift from our vision to Polina my sequel or something
Speaker 6: like that. Get when do we get to it?
Speaker 3: So tell me more about raw dogging the sequel. Yeah,
Speaker 3: how do you how do you approach that? Because it
Speaker 3: seems like it I again back to the why arms exist.
Speaker 3: I think they started out because people wanted to support
Speaker 3: seql light and postgrass and they're my sequel projects, That's
Speaker 3: what it seems like. But then once they were there,
Speaker 3: it started to kind of like functional programming was also
Speaker 3: you know, hitting one of its uh one of its phases,
Speaker 3: and so it's like, oh, look, I could do the chaining,
Speaker 3: I could do I do all the functional program Functional
Speaker 3: programming is more amenable to relational algebras opposed to the
Speaker 3: Java style programming that it was you know, existed at
Speaker 3: the time that this stuff seemed to be really taking
Speaker 3: off from from you know, my point in history, which
Speaker 3: I'm you know, I missed a bunch of fit because
Speaker 3: I came in kind of not I thought I was
Speaker 3: in the early days. Maybe I was more towards the
Speaker 3: middle of it than I thought. But anyway, so, so
Speaker 3: you've got that, and then but so then the whole
Speaker 3: thing is, well, you know, now it's typed, and now
Speaker 3: it works in your language, and now and so and
Speaker 3: so SQL became the bad guy. It's like, well, the
Speaker 3: o RM isn't just so that you can support multiple databases.
Speaker 3: It's actually because it is the morally superior choice. Good
Speaker 3: people use rms because they're good people, and and so
Speaker 3: then so so it's like, well, if you buy into
Speaker 3: the idea of an ORM, then you're a good person.
Speaker 3: And if you're a good person, you're not gonna raw
Speaker 3: dog the sequel, are you, because then you lose your portability,
Speaker 3: and then you lose your functional programming, and then you
Speaker 3: lose all the things that are so enlightened. So how
Speaker 3: how do you have this the economy where you gonna say,
Speaker 3: use joys to RM? But actually, yeah, rob Dog the
Speaker 3: sequel when you need to.
Speaker 6: I don't know, I just do. I mean the excellent well,
Speaker 6: I mean I've tried to use r ms in the
Speaker 6: past that you know, you get their dsls get so
Speaker 6: contorted to try and support every little thing in SQL
Speaker 6: that you'd want to do in a typescript DSL and
Speaker 6: that sort of thing that you're just you know why,
Speaker 6: you know, even if it's type to like I really
Speaker 6: love types, right, I really love static typing. I love code,
Speaker 6: you know, generating you know, the database schema and pulling
Speaker 6: those you know, like the act of what active record does,
Speaker 6: like that, you know, is really what joys trades to do.
Speaker 6: You granted at coaching times, so the typescript compiler can
Speaker 6: see it. But like there's a limit to where like
Speaker 6: let's just write some sequel. And I think especially because
Speaker 6: it just doesn't happen that often, right, Like, and that's
Speaker 6: what makes me feel not so bad about it, Right
Speaker 6: Like if I had a one hundred thousand line code
Speaker 6: based in fifty thousand of it, or like entities and
Speaker 6: the other fifty thousand were you know, raw dog sequel,
Speaker 6: and it was very hard to see when you you
Speaker 6: would use each and you you know, there were little
Speaker 6: camps of like on this one you you know, which
Speaker 6: one do you use and that sort of thing. But
Speaker 6: at least on the projects that we've got going on
Speaker 6: so far, like like, it's really pretty obvious that you
Speaker 6: early seems like it that that you know, you do
Speaker 6: use the r M for as much as you can,
Speaker 6: but then those last few and in terms of what
Speaker 6: it actually looks like, we don't have a little bit
Speaker 6: of glue. So right now, Joyce sits on top of Connects,
Speaker 6: which is just another it's one of these query builders.
Speaker 6: It's like the key sleep and that's what Joyce itself
Speaker 6: sends the queries through. And so we use the same
Speaker 6: connection pools as Connects, if I'm saying that right. And
Speaker 6: so if you.
Speaker 3: Do, it's after the Lego alternative.
Speaker 6: Yeah, yeah, yeah. And so when you want to you know,
Speaker 6: broad dog to your sequel, you just get the connects
Speaker 6: d s L from the same I mean, I say DSL,
Speaker 6: but but there's it is a DSL, but it's it's
Speaker 6: it's much lower level. It's much closer than the sequel
Speaker 6: and it's not as type to me's for thing, and
Speaker 6: you just do a few of them and you know,
Speaker 6: make sure you write tests and I don't know, I
Speaker 6: don't care that the code ends up being cleaner. And yeah, oh,
Speaker 6: I wanted to follow the tangent you had mentioned that,
Speaker 6: you know, ORMs were really great for cross database compatibility. Actually,
Speaker 6: I don't know if that's the case. I know that
Speaker 6: that is a purported benefit of the ORMs, but just like,
Speaker 6: how often have you really seen a project my great databases?
Speaker 6: Like it's just like, well, that's the thing, Like it's
Speaker 6: not gonna I think that.
Speaker 3: There's an impetus, right, I mean you have to go
Speaker 3: back to the root cause. What's the root cause? Well,
Speaker 3: I believe the root cause is more stars and back
Speaker 3: then there wasn't GitHub, but still download count on SourceForge, right,
Speaker 3: That's that I think is the thing is that people
Speaker 3: wanted to see the number tick because if you're not
Speaker 3: getting paid in dollars, you want to get paid in
Speaker 3: social credit. And I believe that what it was is
Speaker 3: they wanted to get other people in their community to
Speaker 3: wash that download tick or source sports go up.
Speaker 6: I'll give you that. That's that is an interesting dissertionon
Speaker 6: I'll have to think about that the whole Like, you know,
Speaker 6: then you mentioned the sq C goes after the all
Speaker 6: of the seql light users and that sort of thing.
Speaker 6: I don't know, I'll step back a little bit, like
Speaker 6: more than like cross database compe, Like I'm gonna we
Speaker 6: use abos aurra at at homebound. It's amazing. I'm going
Speaker 6: to run on Aurora for the next you know, twenty
Speaker 6: years if I can. Like it just gets as big
Speaker 6: as you you know, want it to. And granted you
Speaker 6: have to pay for it, but it's an amazing product
Speaker 6: and I have no desire to run on anything other
Speaker 6: than that. But oh, but that's not why I use
Speaker 6: the r M. Why use the r M is business
Speaker 6: variant enforcement, right, So validation rules such that you know what,
Speaker 6: I my my just credulity with the Corey builder approach
Speaker 6: is like, you know, let's say I'm in my author endpoint,
Speaker 6: I'm in my save author endpoint, and I'm going to
Speaker 6: do an insert an update. Let's say I'm going to
Speaker 6: update the author Okay, so somebody raw dogs an update
Speaker 6: to the author table. What business rules did they check? Well,
Speaker 6: you know, before they switched that first name, before they
Speaker 6: updated the you know, book title, or before they increased
Speaker 6: the book rating, and like how many derive values, validation
Speaker 6: rules and drive values are trying to watch whatever they
Speaker 6: just updated, right? So uh, you know, let's say that
Speaker 6: the author has a star count right and or or
Speaker 6: you know these sort of you know, Active record has
Speaker 6: some countercashers that we haven't quite flung that yet, but
Speaker 6: just in general, the idea of you know, after you
Speaker 6: update this row in the database, something else needs to
Speaker 6: know about it. And that's why I use RMS. I
Speaker 6: would just be super scared of like raw dog and
Speaker 6: a s an update to an author and forgetting what
Speaker 6: else did I have to do? You know, what other
Speaker 6: validation rules did I have to run? What other dragau
Speaker 6: should have to update? And those are the two things.
Speaker 6: You know, we were kind of into the third phase
Speaker 6: of what joyce is amazing yet you know M plus
Speaker 6: one and you know avoidance was the first one. Second
Speaker 6: one is those you know, populate hints to move a
Speaker 6: get rid of a weight gunk. And the third one
Speaker 6: is this like not only validation rules and life cycle hooks,
Speaker 6: like active record has the you know, we have active
Speaker 6: record style before flushes and before updates, we do cross
Speaker 6: entity reactivity, which is kind of a fancy marketing praise
Speaker 6: from it. So I guess I am kind of putting
Speaker 6: on my my marketing hat here. But so you know,
Speaker 6: on the front end, reactivity is a big catchphrase right
Speaker 6: of when you update the component over here, you know,
Speaker 6: the reactivity is updating all of the component. You update state,
Speaker 6: you know, you update state once and then it gets
Speaker 6: broadcasted out.
Speaker 3: Well, I've heard about it. I haven't seen it, but
Speaker 3: I've heard about it.
Speaker 6: Yeah, sure, Well Joyce basically brings that concept to the
Speaker 6: back end. So like when in a Joyce entity, when
Speaker 6: you update an author and let's say the author first
Speaker 6: name or the author last name, we will watch notably
Speaker 6: for like validation rules on the author itself. Like you know,
Speaker 6: the the really simple ones are the validation rules you'll
Speaker 6: see in a ZOD or some sort of schema based
Speaker 6: partier that they just look just at the field and
Speaker 6: just to the primitive values in the field. Isn't too
Speaker 6: long or is it too short? Is it an email rejects?
Speaker 6: Is it not no? Or whatever? And those are fine,
Speaker 6: you know, that's that's what a ZOD can do for you.
Speaker 6: But you know, when you start talking business and varianceisconds
Speaker 6: back to like some of the bigotous language and being
Speaker 6: driven design when you go talk to your you know,
Speaker 6: your business users and they're like, well, I have this
Speaker 6: this rule. I use the term invariant, this business rule
Speaker 6: that I want to just always be true. You know,
Speaker 6: I want this to always be true. And it's probably
Speaker 6: not going to look at just what the first name is.
Speaker 6: Is the first name too long or too short?
Speaker 3: Right?
Speaker 6: It might look at well, are you know the first
Speaker 6: name can't be the last name or or you know,
Speaker 6: it's going to look at multiple fields at once, right,
Speaker 6: just on with one on one entity. But then it's
Speaker 6: also very common for like the rules to want to
Speaker 6: like look across entities like well, if my author is
Speaker 6: has some sort of status, right, if my author is employed,
Speaker 6: And then my other validation rule in the books, like
Speaker 6: the books can be you know, sold or something like this, right,
Speaker 6: and so these sort of cross and variant validation rules.
Speaker 6: That's why I use ORMs, and and I hope you know,
Speaker 6: I can't speak for others, but that's that's what I
Speaker 6: would assume is an attraction to the ORM is not
Speaker 6: just like abstraction from the SQL database I'm using.
Speaker 3: So I guess in that sense I build my own
Speaker 3: RM because I prefer to have business logic in a
Speaker 3: separate layer from storage logic. I see these these two
Speaker 3: things is fundamentally different. And as I you know, I'm
Speaker 3: going through in refactoring code and like like looking through projects,
Speaker 3: as as I tend to do being you know, consultant,
Speaker 3: I think that the worst, like the weakest abstractions are
Speaker 3: the ones that combine storage and messaging with business logic,
Speaker 3: because business logic is the most likely to change. And
Speaker 3: so anytime that storage and messaging are together with business
Speaker 3: logic or you know, either one of those or together
Speaker 3: with business logic, then it it just it's always a
Speaker 3: nightmare when X needs to change, well now you have
Speaker 3: to go change Y and Z as well. You know.
Speaker 3: So I'm I'm very I'm very much a business logic
Speaker 3: goes in the business logic place. Yeah, And that's so
Speaker 3: fundamentally my stack, my ideal stack is routing is global.
Speaker 3: Business logic is per component. Storage is more or less
Speaker 3: global slash hierarchical. But like the business logic uses the storage,
Speaker 3: it's not in the storage. And then messaging likewise, messaging
Speaker 3: might be global with like some hierarchical component to it.
Speaker 3: But yeah, the business logic uses the messaging. So what
Speaker 3: I'll do, which you don't see this in a lot
Speaker 3: of code bases because people like to abstract it away,
Speaker 3: because I want to function that's like save that's going
Speaker 3: to do the business logic, do the storage logic, and
Speaker 3: do the message logic altogether. What I'll do is I'll
Speaker 3: literally like call the get function, take the data, call
Speaker 3: the business function on the data, and then take the result,
Speaker 3: and then call the messaging function. But then then whenever
Speaker 3: it's time to refactor, whenever business logic changes, it's like
Speaker 3: I got to go and just change that one thing.
Speaker 3: I don't have to go change my storage module or
Speaker 3: my messaging module or or whatever.
Speaker 6: Sure, yeah, no, I mean what you're saying reminds me
Speaker 6: a lot of I mean I've seen I've seen those
Speaker 6: architectures in the past. I've worked in those code bases,
Speaker 6: and it's a very familiar argument, I guess, especially you
Speaker 6: saw it, you know fifteen, you know, twenty years ago.
Speaker 6: In the Java world, there's a very strong push to
Speaker 6: have well the terms the same POJOs. You know, plain
Speaker 6: old although this was Java now, you you know plain
Speaker 6: at old JavaScript object or plain old Java object you know,
Speaker 6: passed between your layers, and you had to have a
Speaker 6: storage layer, and that was the only place they could
Speaker 6: put like data into your your your POJOs. I guess
Speaker 6: what you know? I think this is what I learned
Speaker 6: from active record and the pattern in general, but then
Speaker 6: also Ruby. The implementation is that if your storage matches,
Speaker 6: this gets to kind of the domain model, the concept
Speaker 6: in your bigder's language. If your storage schema matches what
Speaker 6: your you know, potos supposed to be anyway, the storage
Speaker 6: layer just goes away. Right, There is no storage layer anymore.
Speaker 4: You know.
Speaker 6: That's that's what the active record pattern fundamentally does. And
Speaker 6: I think there is an assumption there that you can
Speaker 6: control your schema, right, So like you know, twenty years ago,
Speaker 6: when your schema was controlled by the Oracle database admin,
Speaker 6: that you had this amid scripts to once a week
Speaker 6: for him to maybe add a table if you ask
Speaker 6: nicely enough, right, and all of these other sort of things.
Speaker 6: You had really shitty database schemist.
Speaker 4: Right.
Speaker 6: They were just ugly and they were wrong, and they
Speaker 6: modeled the data, you know, had ugly names and that
Speaker 6: sort of thing. And so the ORMs way back in
Speaker 6: the day, like hibernates of the world. Part of what
Speaker 6: they tried to do was like fix the terrible database schema. Right,
Speaker 6: you would write your mapping files or your storage layer
Speaker 6: to try and you know, get the data out of
Speaker 6: the super ugly database and put it into your super
Speaker 6: pristine oh kojo later. Right, that was all you know,
Speaker 6: your ivory tower of which you really wanted it to be.
Speaker 6: And to me, that's that's where the whole you know,
Speaker 6: or MS or the Vietnam of computer science came from.
Speaker 6: Is that the Yeah, this notion that that you have,
Speaker 6: oh right, the object relational mismatch you know, that'll get
Speaker 6: you know, thrown around, is in like somehow objects are
Speaker 6: just fun only different from relations. I don't. I don't
Speaker 6: think that they are like you know, I think if
Speaker 6: you they don't have to be anyway. I I think
Speaker 6: they were back in the day when you've had super terrible,
Speaker 6: terrible oracle database schemas that you wanted to map onto
Speaker 6: your different set of you know, objects, you know, that
Speaker 6: was an impedance. But that was not because of the technologies.
Speaker 6: That was just you know, because your schemas were so terrible.
Speaker 6: But you know, if you have the freedom to make
Speaker 6: your your you know, database schema what it really should be.
Speaker 6: You know, if you have an author, you have an
Speaker 6: author's table. If you have a book, you have a bookstable,
Speaker 6: and you know the columns match which you wants them
Speaker 6: to be, and you can change them with migrations extremely
Speaker 6: quickly in a C I CD pipeline. I think that
Speaker 6: impedance goes away and you start thinking of your your
Speaker 6: relational database as a graph database, really just a graph
Speaker 6: database at skills really well, because for whatever reason, graph
Speaker 6: databases haven't really taken off and can you know whatever,
Speaker 6: but you know, you think of your relational database as
Speaker 6: a graph database. And now your storage leader. Coming back
Speaker 6: to where you put your business edge, there is no
Speaker 6: storage layer. The RM just doesn't. And so now what
Speaker 6: the entity has become is not a storage layer. They
Speaker 6: are business logic player, right, so when you're you know,
Speaker 6: you say, well, I'll have my business off somewhere else.
Speaker 6: This is one of my criticisms of the quiry builders
Speaker 6: is that you have to do just what you did. So,
Speaker 6: like Joyce and our entities, we provide a framework for
Speaker 6: business logic and we've we've attempted to vet it and
Speaker 6: attempted to organize it and attempted to, you know, design
Speaker 6: a really pleasant way to organize your business logic. I'm
Speaker 6: gonna say, like separate from your storage layer. But there
Speaker 6: is no storage layer. That's kind of the point.
Speaker 3: Such that, well, there is a storage layer, it's just
Speaker 3: abstracted in some way. I mean, there's obviously there sure
Speaker 3: is a storage layer.
Speaker 1: Active record does this by convention, right, And so you
Speaker 1: don't think about it because it's mostly invisible, right. And
Speaker 1: I think I think that's what you're saying, Steven. And
Speaker 1: what I find is that this probably works ninety five
Speaker 1: percent of the time, and then the other five percent
Speaker 1: of the time you have to go play the game
Speaker 1: of Okay, I've got something that's a little more complicated
Speaker 1: than just business logic in this one narrow vein of
Speaker 1: users for example, Right, And so what I wind up
Speaker 1: doing is I wind up creating some other entity that
Speaker 1: manages that business logic and that workflow and all the
Speaker 1: things that are involved in that. You can call it
Speaker 1: a component, you can call it a service, you can
Speaker 1: call it whatever you want. But yeah, you wind up
Speaker 1: solving that in a different way. And I think sometimes
Speaker 1: people get into the arena of saying I don't like
Speaker 1: rms because they don't solve things in this five percent
Speaker 1: or three percent of the time exactly. And the reality
Speaker 1: is is it's like, look, it does all this stuff
Speaker 1: for me the other ninety five to ninety seven percent
Speaker 1: of the time, and so I'm gonna use it because
Speaker 1: it gets all of this garbage out of the way
Speaker 1: and it makes all of the storage stuff invisible to me,
Speaker 1: and it gives me a place to put the stuff
Speaker 1: that I care about and then yeah, I'm gonna have
Speaker 1: to go and I'm gonna have to special cases other crop.
Speaker 6: Yeah, which is fine.
Speaker 3: And that is actually my plug for or sq C
Speaker 3: is that it gets all of the crap out of
Speaker 3: the way. But there's the only constraints that it has
Speaker 3: is that it can't do meta table stuff like for example,
Speaker 3: and I don't think active record does this either, Like
Speaker 3: if you wanted to create a table dynamically, like let's
Speaker 3: say that you were doing something like Snowflake, where you
Speaker 3: need to create tables on the fly to represent csvs
Speaker 3: that people are importing, sq C is not the right
Speaker 3: tool for that job. Sure, but that is in your
Speaker 3: like zero point one percent. I think like it's very
Speaker 3: rare that you need to do meta manipulations on a
Speaker 3: table in an application that you're like multi vendoring your
Speaker 3: application in that kind of way. But like for all
Speaker 3: the stuff that it but all the stuff that an
Speaker 3: orm is gonna do, typically C is going to do
Speaker 3: for you. It's just that you just write the sequel,
Speaker 3: and you write the sequel as specific as you want.
Speaker 3: And what it does is it uses the Postgress query builder,
Speaker 3: like it links to the C code, and so it
Speaker 3: runs the C code and then it gets back basically
Speaker 3: the like it knows what the C code object is
Speaker 3: going to be, and then it translates that to JSON
Speaker 3: and then translates that to GO or in the case
Speaker 3: of Go, it might do direct because they didn't have
Speaker 3: the Jason adapter. The Jason adapter came before they created
Speaker 3: the adapter that goes to the other languages like Python
Speaker 3: and Typescript. Originally it was just straight from Postgress to GO.
Speaker 3: But anyway, so it hasn't it. It reads from the
Speaker 3: Postgress specific type system into a broad type system, into
Speaker 3: the languages type system, and so you get all of
Speaker 3: the typing, you get all of the objects. It's very
Speaker 3: easy to yeah, any anyway, so so that that's where
Speaker 3: that's where SQL SEE in particular, I think is is
Speaker 3: the best in class. Although it's it's probably not something
Speaker 3: many people have a mental model for because as far
Speaker 3: as I know, it's the only one of its kind.
Speaker 3: It's it's another one of those obvious ideas where once
Speaker 3: you see it, it's like, oh, why haven't we been
Speaker 3: doing this for the last twenty thirty years? But yeah,
Speaker 3: you know again, but nobody did it.
Speaker 6: It is a cute approach. I doe like the novel
Speaker 6: well for my caveat would be for you know when
Speaker 6: Charles said the last two to three you know, four
Speaker 6: percent of things that are really gnarly and you have
Speaker 6: to like reach outside of the box. I think the
Speaker 6: sequel c approach is really pretty novel and great for
Speaker 6: giving you a file to just write your super one
Speaker 6: off according and that sort of thing. I guess for
Speaker 6: the other ninety five percent of things, I don't use it.
Speaker 6: What's that.
Speaker 2: I don't think I've ever used sql SE SQL SEE yeah.
Speaker 3: I don't know if they have a Ruby adapter.
Speaker 6: Yeah, I mean the yeah, the concept.
Speaker 1: Is I'm playing more and more in the JavaScript realm
Speaker 1: anyway anyway, sorry I keep jumping in.
Speaker 3: Oh no, that's no obviously.
Speaker 6: The well yeah, so the the t ld R O
Speaker 6: SQL CEE is that usually you know, we talk about
Speaker 6: raw dogging SQL, right, so usually raw docking SQL in
Speaker 6: most languages is you just go do an embedded sequel stream,
Speaker 6: you know, inside.
Speaker 3: Of your and you lose the types and you lose.
Speaker 6: The types and you're just building a great big squel
Speaker 6: statement as a string. And maybe you use a string
Speaker 6: builder or maybe you you know, you somehow piece together
Speaker 6: what is in your language fundamentally a stream.
Speaker 3: And then then you have a typo in in in
Speaker 3: the name of people where you transpose the O and
Speaker 3: the e and you don't find out until you deploy.
Speaker 6: Uh. And so what's novel about SQL, see is they
Speaker 6: have you write this instead your your query and a
Speaker 6: dedicated file outside of your you know, your language, whether
Speaker 6: it's GO or typescript or whatever called like you know,
Speaker 6: my query dot sql. You know, get authors dot sql
Speaker 6: or you know, read authors dot sql or insert authors
Speaker 6: dot sql and you write literally the the sequel that's
Speaker 6: going to go to the database and you get it.
Speaker 6: Used variable interprelation like dollars sign one dollars tent two.
Speaker 6: And then what they do is they just you know,
Speaker 6: they parse that seqel type check it, and then generate
Speaker 6: a little binding around it that says like oh, if
Speaker 6: you you know, they cogen out a wrapper, that's a method,
Speaker 6: you know, a method that will really just load that
Speaker 6: little SEQL file and then call it. So it really
Speaker 6: is a pretty neat way to get, like you out
Speaker 6: of like writing raw dog sequel inside of strings in
Speaker 6: the database or sorry, in your in your typescript file,
Speaker 6: or you're going five into like what is actually a
Speaker 6: SQL file. I actually think that's pretty great. My disclaimer
Speaker 6: would be like for those three to four to five
Speaker 6: percent of cases where I want to be raw dogging sqel,
Speaker 6: and the other ninety five percent, which is like the
Speaker 6: super boring update author's credit statement that not only is
Speaker 6: the very boilerplate to write the the you know, update
Speaker 6: authors SQL which which you know I don't want to
Speaker 6: write but maybe you could say, is not fine, but
Speaker 6: all of the invariants that I need to go make
Speaker 6: sure still pass right, like sure I updated the author,
Speaker 6: what other business rules.
Speaker 3: Or but that's all in your business logic. That's all
Speaker 3: in your business logic. So that's that's still now, like
Speaker 3: you still get that, you don't bypass that.
Speaker 6: Do seq C have a way tell you how to
Speaker 6: structure your business logic or that's just like on you
Speaker 6: to figure out a way to do it.
Speaker 3: Well, I mean you do it the same way you
Speaker 3: do it anywhere else, right, whether you're using SQL or not.
Speaker 3: So you just sq C takes care of the storage
Speaker 3: layer and you you But okay, I mean I don't
Speaker 3: want to. I don't want to do and yeah, I
Speaker 3: don't want to go.
Speaker 2: To so sure, yeah.
Speaker 6: Maybe one last thing about it is that I think
Speaker 6: the corea builders of the world, and this is I
Speaker 6: would include SEQC in that, but also the Christmas and
Speaker 6: drizzles and all of these leave as an exercise to
Speaker 6: the reader how to structure their business logic, right, like
Speaker 6: like when to invoke it, how to structure it, where
Speaker 6: to put it. And that actually is the most the
Speaker 6: thing that the choice is focused on is like sure
Speaker 6: eighty percent, well you know, sixty percent of is an
Speaker 6: orient to get data out of your database. The other
Speaker 6: forty is a way to structure your business logic. Instead
Speaker 6: of everybody having to kind of make up their own
Speaker 6: and hope they do it right and in those sort
Speaker 6: of things. Grant it is a very opinionated way to
Speaker 6: structure because it uses entities, and it uses life cycle hooks,
Speaker 6: and it uses some reactivity is it? But it isn't
Speaker 6: pin neated.
Speaker 3: It is interesting, and I think that psychologically there's there's
Speaker 3: an effect there that that's really valid because people, you know,
Speaker 3: people go both ways about frameworks, you know, like I
Speaker 3: love a framework because it guides me. I hate frameworks
Speaker 3: because it constricts me. Right, And I think that you
Speaker 3: could have a framework that is here's how to put
Speaker 3: your you know, where to put your business logic, and
Speaker 3: then here's where you plug in your storage adapter. But
Speaker 3: I think that people are more familiar with the idea
Speaker 3: that the ORM is going to be the framework that
Speaker 3: dictates business logic rules with the data association.
Speaker 6: Yeah, which is what we do, yeah, bread and butter.
Speaker 3: Yeah, yep. Cool.
Speaker 1: Well, I think this has been so interesting to just
Speaker 1: kind of listen in on more than participate in. Usually
Speaker 1: I'm jabbering all the time. Sure, but if people want
Speaker 1: to learn more, where do they go find more information?
Speaker 6: Yeah? Sure, you know, so we're joy stash or m
Speaker 6: period I O and you had mentioned you, and if
Speaker 6: you just google for Joyce or m we do kind
Speaker 6: of come up higher in the and the results. We've
Speaker 6: got to get hump project feel free too. Oh and oh,
Speaker 6: we use to have a slack. But what's the thing
Speaker 6: that you you say is discord? You know discord? Uh, actually,
Speaker 6: I'm make sure I'm locked into that when if I
Speaker 6: mentioned it. But yeah, feel free to to stop by.
Speaker 6: You know, I want to make the disclaimer for the
Speaker 6: audience that the the r mu US is a big
Speaker 6: bet on your code base, right, and so we take
Speaker 6: very seriously that if you structure your code base around Joyce,
Speaker 6: that that you're taking a bet. And we really do
Speaker 6: respect and appreciate that. But yeah, but would love to
Speaker 6: have anybody kick the tires and point us out. You know, AJ,
Speaker 6: you've found a few things in the docks that could
Speaker 6: probably be for stuff. Would love to have you know,
Speaker 6: any issues around those things to help you on boarding
Speaker 6: process or things that we're missing. Would really appreciate it.
Speaker 2: Cool, Well, let's go ahead and do our picks now.
Speaker 1: It sounds like you may have listened to an episode
Speaker 1: of the show, so you probably know what picks are.
Speaker 2: Just for anyone who's new.
Speaker 1: I haven't said this in a while, but picks are
Speaker 1: basically shout outs about anything.
Speaker 2: So I usually do board games.
Speaker 1: We've had other people on Ruby Rogues we had picks
Speaker 1: and they you know, one guy did beer picks every week.
Speaker 2: You know, people pick TV shows.
Speaker 1: People pick tech stuff too, right, I mean this is
Speaker 1: a technical show.
Speaker 2: We've had people.
Speaker 1: Pick political candidates, though I'm not jazzed about that all
Speaker 1: the time because people have feels about that, right, and
Speaker 1: that's not really what we're about. But if you care
Speaker 1: about it, you can say it. So anyway, let's go
Speaker 1: ahead and start with Steve and then we'll work our
Speaker 1: way through the panel.
Speaker 4: Yeah, Steven.
Speaker 5: First of all, i'd like to point out I appreciate
Speaker 5: that you spell your first in the correct way, not
Speaker 5: with ian.
Speaker 6: Sure.
Speaker 4: I meant to note that at the beginning.
Speaker 2: Uh, back for my brother about eight times.
Speaker 5: What's funny is and I think I might have mentioned
Speaker 5: this before. I have a brother named Steven. He spelled
Speaker 5: it with a V. He's adopted, uh, and so he
Speaker 5: was already named that one my parents adopted. So we're
Speaker 5: big Stephen, little Steve or I prefer handsome Steve, not
Speaker 5: so handsome Steve.
Speaker 4: You know, it just depends on text.
Speaker 5: But anyway, in regards to two picks, my picks are
Speaker 5: generally the highlight of any episode in there my dad
Speaker 5: jokes of the week, So be prepared to laugh yourself silly,
Speaker 5: just kidding, all right. So, for instance, I asked my wife,
Speaker 5: being a she's a rather non technical person, shall we say,
Speaker 5: I asked her why her password was spelled out snow
Speaker 5: white and the seven dwarves, And she said, I was
Speaker 5: told it had it to be at least eight characters.
Speaker 3: You got it.
Speaker 2: Yeah, that was better than most of the ones he
Speaker 2: comes up with.
Speaker 4: Yeah, I was.
Speaker 5: I was sitting in traffic the other day and that's
Speaker 5: probably why I got run over. Right. And then question
Speaker 5: of the week. If dentists make their money off of
Speaker 5: people with bad teeth, why should I trust a toothpaste
Speaker 5: that nine out of ten dentists recommend.
Speaker 4: It's all about self interest?
Speaker 3: You know, got them?
Speaker 2: I think that's a fair kafiat.
Speaker 4: No, it was like I give you have you anyway?
Speaker 3: I think not out of ten dentists recommend all of
Speaker 3: the toothpastes.
Speaker 4: Right, just Anny, please use something. Those are my picks.
Speaker 2: Nine out of ten dentists that we paid to say.
Speaker 2: So anyway, is the asterisk?
Speaker 3: All right? So since we're on this topic of SQL,
Speaker 3: I'm just gonna throw down. There's a typescript to jazz
Speaker 3: doc module that'll be linked. It's called TS hyphen two
Speaker 3: hyphen js doc. It's exactly what it sounds because I
Speaker 3: don't like typescript. I hate typescript. I think typescript is
Speaker 3: an abomination. You know this. I love types, and I
Speaker 3: love that the typescript checker is getting better and better
Speaker 3: at being able to interpret JavaScript in JavaScript types, and
Speaker 3: I hope that that goes forward. I'd love to see
Speaker 3: one day where you know, maybe collectively we can just
Speaker 3: all drop typescript because the typescript checker is so good
Speaker 3: at JavaScript types that you don't even need to annotate anymore.
Speaker 3: It just gets it. That would be Amazing's that's like
Speaker 3: zig level. The other thing is there's a module called
Speaker 3: my sequel dump TS my SQL hyphen dump pipal t
Speaker 3: iphen ts and this will allow you, of course to
Speaker 3: dump tables out of your my SQL database and then
Speaker 3: get the typescript of them, and then you can run
Speaker 3: the typescript to jes doc to get the jas dock
Speaker 3: of them, and then you can start to you can
Speaker 3: start to make your code better in the sense of
Speaker 3: being able to have type checking, you know, misspellings checked,
Speaker 3: et cetera, and add to them. Yeah, I don't think
Speaker 3: that you would need if you're going this route, I don't.
Speaker 3: I think joycet is solving this problem for you. If
Speaker 3: you're adopting JOYST I don't think you'd need these. But
Speaker 3: this would be in the case where you have an
Speaker 3: existing project and you're trying to get certain parts of
Speaker 3: that project in a in a better way so that
Speaker 3: you can feel safer and sleep better at night about it. Then,
Speaker 3: of course sq se SQLC like I said, it's kind
Speaker 3: of like a reverse sequel query builder because you just
Speaker 3: write the sequel and then it gives you the queries.
Speaker 3: And it's not a binding. Just to be clear, it is, well,
Speaker 3: I mean it is a binding from the perspective that
Speaker 3: it uses the sequel driver. But it's it's not it's
Speaker 3: not calling that that well, it builds, it builds out
Speaker 3: it it builds it out. It's not it's not copying well,
Speaker 3: it is copying from the file. It's not using the
Speaker 3: file you created anyway you can see what it is.
Speaker 3: But sq C I think is the smartest approach because
Speaker 3: it seems like it covers not the ninety five percent
Speaker 3: but the ninety nine point five percent in terms of
Speaker 3: as long as you don't need to do meditable manipulations,
Speaker 3: it's got your back and it's and since you have
Speaker 3: to learn SQL anyway, query builders don't alleviate your need
Speaker 3: to learn SQL. If they did, then I'd say, yeah,
Speaker 3: let's get on the query builder. But the truth of
Speaker 3: the matter is, at the end of the day, chat
Speaker 3: GPT is going to be bomb awesome at generating CQ
Speaker 3: for you, and it's going to be mediocre at best
Speaker 3: at generating queries in your query builder of choice. Well,
Speaker 3: I don't know. I haven't tried it with that specific
Speaker 3: use case in the most recent version, but my previous
Speaker 3: experience with it was it does awesome its SQL, and
Speaker 3: it's really mediocre when it comes to the SQL abstractions.
Speaker 3: So sql C is something that seems to pair really
Speaker 3: well with LMS in terms of being able to get
Speaker 3: the statistically likely correct sequel, which sl really lends itself
Speaker 3: incredibly well to statistical analysis, like that's a match made
Speaker 3: in heaven then Sloanik. Sloanik is kind of a different
Speaker 3: approach in terms of you are putting your queries inside
Speaker 3: of templates, inside of your JavaScript code, but it is
Speaker 3: it's kind of a middle ground between SQLC and a
Speaker 3: query builder in that it's doing the query building dynamically,
Speaker 3: but you are getting the type check on it. But
Speaker 3: SQL see I think, I think sql C is the
Speaker 3: real gold, but sloanik is something that's certainly an interesting option.
Speaker 3: And then you've got template blocks that are SQL tagged
Speaker 3: and so you can get highlighting and stuff like that.
Speaker 3: And then so that's the SEQL stuff that out of
Speaker 3: the way. Two other quick things, swift UI seems like
Speaker 3: amazing and the Android jetpack composed is either it's either
Speaker 3: the clone of swift ui or swift u I is
Speaker 3: the clone of that. And you know Apple likes to
Speaker 3: perfect things when it clones them and then pretend like
Speaker 3: it's the first because it's so good that you know,
Speaker 3: they knock it out of the park when they do it.
Speaker 3: But there's two talks swift UI essentials and introduction is
Speaker 3: swift u I. And if I close my eyes, what
Speaker 3: I hear is react React, React react, But when I
Speaker 3: open my eyes, what I see looks more like view
Speaker 3: and like, oh this actually, this actually looks like it
Speaker 3: would work. Because there's there's the there's the promise of react,
Speaker 3: and then there's the reality that we're all kind of
Speaker 3: familiar swift Ui seems to be both the promise and
Speaker 3: the reality of react. I'm really interested to get more
Speaker 3: into it. And then last thing, I am going to
Speaker 3: make a political pick. I Oh, Trump just makes me
Speaker 3: so ah, can we not have good choices? But then
Speaker 3: but then every time, every time I think we're the
Speaker 3: dregs where the bottom of the barrel? Can this get
Speaker 3: any worse? Then it's like he does an interview that's
Speaker 3: with people that are a different audience, because when he
Speaker 3: speaks to the general public, I'm just like, oh, please no.
Speaker 3: But then sometimes when he speaks to a specific audience,
Speaker 3: it's like, all of a sudden, he's a genius that
Speaker 3: understands how the world works. And so he gave this
Speaker 3: interview or did this presentation in Q and A with Frontline,
Speaker 3: and like everything that he said was actually intelligent, And
Speaker 3: then I had to challenge all my beliefs again. And
Speaker 3: those are my picks.
Speaker 2: What yeah.
Speaker 1: I think everybody who listens to this show on a
Speaker 1: regular basis knows that I'm heavily politically involved. I'm just
Speaker 1: not gonna comment, at least not here. I am working
Speaker 1: on some politically focused shows, and if you don't agree
Speaker 1: with my opinions and you don't want to hear.
Speaker 2: Them, don't listen to that show. I'm going to jump
Speaker 2: in with a couple of things.
Speaker 1: So I'm going to do a board game pick really quickly,
Speaker 1: and that game is what did we play last time
Speaker 1: we played Biblios. That's what we played. So if you
Speaker 1: haven't played Biblios, it's a card game. I'm gonna try
Speaker 1: and do this in less than a minute. But effectively,
Speaker 1: you have dice that are set out and it's if
Speaker 1: it's the score for getting the most books of that
Speaker 1: color and so, and then there are cards will let
Speaker 1: you change.
Speaker 2: The dice, so you can make it one higher or
Speaker 2: one lower.
Speaker 1: And then you're either capturing a card out of the
Speaker 1: cards that you drew, your picking a card that somebody
Speaker 1: else didn't want on their turn, or you're bidding on
Speaker 1: cards with gold after all the cards have been picked
Speaker 1: and so and then whoever has the most in whatever
Speaker 1: color you get those dice. Whoever has the most pips
Speaker 1: showing on the tops of their dice that they wont wins.
Speaker 2: It's more or less that simple board game. Geek rates it.
Speaker 1: I don't have it up in front of me, but
Speaker 1: it was like one point seven to eight or something
Speaker 1: like that. So it's very approachable if you're casual gamer.
Speaker 1: Fun game, probably a half hour game with four players.
Speaker 1: So I'm gonna pick biblios and then.
Speaker 2: I've got a couple of other picks. I went to
Speaker 2: my doctor a couple of weeks ago.
Speaker 1: Maybe I don't talk about this as much, but I
Speaker 1: have type two diabetes and the doctor prescribed me, among
Speaker 1: other things, this it's a blood glucose monitor. Now, the
Speaker 1: ones that I've used in the past, you poke your finger,
Speaker 1: you bleed onto a little test strip, and you have
Speaker 1: to remember to do it on a regular basis, and
Speaker 1: I'm not so good at that, and so I would
Speaker 1: run into the issue where, you know, I'd show up
Speaker 1: at the doctors and he's like, have you been testing
Speaker 1: your blood sugar? My answer was always not for a
Speaker 1: few months. So he prescribed me. This system is called
Speaker 1: the Freestyle Libre three and I'm not sure if you
Speaker 1: can even see it on the camera, but I've got one. Yeah,
Speaker 1: you can kind of see it right there on my arm,
Speaker 1: so you know, yeah, it connects to my phone. And
Speaker 1: so I'm much better at checking my blood sugger because
Speaker 1: i'll you know, periodically look.
Speaker 2: And it's also it's funny. I can't remember which book it.
Speaker 1: Was, but there was a book that talked about the
Speaker 1: concept of keystone habits, and those are the habit that
Speaker 1: get you to do all of the other things right.
Speaker 1: So if you're eating right, then you have a tendency
Speaker 1: to exercise because you're thinking about your fitness more and
Speaker 1: things like that. And so this has been good for
Speaker 1: me because it's kind of a reminder. I'll check my
Speaker 1: blood sugar and then I'll remember I haven't taken my
Speaker 1: medicine yet and so anyway, so there are things like
Speaker 1: that that kind of come out of it. But anyway,
Speaker 1: it's really cool. I've had a little bit of trouble
Speaker 1: with them staying on. So last night I woke up
Speaker 1: in the middle of the night because I got an
Speaker 1: alert on my phone that said that my blood sugar
Speaker 1: was dangerously low, and so you know, I went downstairs
Speaker 1: and ate something to try and get it to go up,
Speaker 1: and then when I came back upstairs, it said that
Speaker 1: the sensor was no longer working and it was dangerously
Speaker 1: low because it had actually come out of my arm
Speaker 1: and then had gotten poked back into my arm but
Speaker 1: not all the way, and so the tissue it was
Speaker 1: testing was not right. It was given it a bad reading,
Speaker 1: so I have had some weird issues with it.
Speaker 2: I put this one on this morning right to replace it.
Speaker 1: The nice thing is, though, is that I went on
Speaker 1: the website for the company and apparently they'll replace them
Speaker 1: if they come out early, so I just requested a
Speaker 1: new one because I have to pay for my insurance
Speaker 1: doesn't cover these, and they're like twenty twenty five bucks
Speaker 1: a pop, but they last for.
Speaker 2: Like two weeks at a time. So anyway, cool stuff.
Speaker 2: I really really dig it.
Speaker 1: And then lastly, I'm just going to put in a
Speaker 1: brief plug for JavaScript Geniuses. One of the things I
Speaker 1: think really helps people level up is if you're talking
Speaker 1: to other people on a regular basis, doing things like meetups,
Speaker 1: and so I'm providing all of those. So if you
Speaker 1: join JavaScript Geniuses, you'll get access to I'm gonna start
Speaker 1: doing videos they walk you through different JavaScript themes.
Speaker 2: So maybe I'll do a video on Joyce.
Speaker 1: I don't know, it's not on my it's not on
Speaker 1: my list yet, but we'll see anyway. Yeah, yeah, so
Speaker 1: we'll get into other stuff, maybe VAT or you know,
Speaker 1: doing agentic AI or things like that. There's all kinds
Speaker 1: of stuff I want to figure out how to do
Speaker 1: with JavaScript. So we'll do that and I'll demo it,
Speaker 1: or I'll have people come on and demo it. So
Speaker 1: maybe we'll have Steve come and talk to us about
Speaker 1: or Steven come and talk to us about Joyce. Anyway,
Speaker 1: we also do accountability calls on Monday. There's a book
Speaker 1: club and we're getting into the AI book from Obi
Speaker 1: Fernandez right now. We also do a personal development book.
Speaker 1: We're doing Awaken the Giant Within by Tony Robbins. And
Speaker 1: you can come to as much or as little of
Speaker 1: this as you want, but anyway, so it's just a
Speaker 1: way of doing community based learning and then you know,
Speaker 1: giving you videos that walk through stuff. So go to
Speaker 1: JavaScript Geniuses dot com. I will have that up this
Speaker 1: afternoon and then you can go in join the vun
Speaker 1: Steven what are your picks.
Speaker 6: Yeah, well I came in without one, so I'm just
Speaker 6: gonna have one. It's a project called grow Fast g
Speaker 6: r Fast grew Fast, and it's by this guy Benji
Speaker 6: out of the UK. He also does well, Charles, you've
Speaker 6: done active record Ruby stuff sidekick right in the Ruby community.
Speaker 6: So this guy kind of has the node version of that.
Speaker 6: Graph file Worker is the name of grafile Worker is
Speaker 6: probably his main project right now. And we use the
Speaker 6: graph file worker as like our sidekick and it works great.
Speaker 6: We you know, we like it and really props to him.
Speaker 6: He's trying to go the you know, make a business
Speaker 6: out of it, right, like not chasing after VC money,
Speaker 6: but trying to do some support and upgrades and that
Speaker 6: sort of thing, which is really amazing, you know.
Speaker 2: PROPSI in uh what they did with sidekicks.
Speaker 6: So yeah, yeah, oh I would have known him had
Speaker 6: you not asked me, but yes, uh the well, so
Speaker 6: anyway you want to Benji's other projects other than graph
Speaker 6: file Worker is this graff Fast, which is really like
Speaker 6: a ground up thinking of how a GRAPHQL run time
Speaker 6: should be, so it doesn't change graph l syntax or
Speaker 6: graph col clients or are how anybody really talks to
Speaker 6: a graph ql server. But it fundamentally, like so Joyce
Speaker 6: has to when we went through all of Joyce like
Speaker 6: using promises to like fix up all of you know,
Speaker 6: all of the n plus ones that would have happened.
Speaker 6: Grapast is a really that that just like fundamentally happens
Speaker 6: with how most graph qol servers are implemented. Like when
Speaker 6: you know the Apollo in the graph qol community or
Speaker 6: in the no community, we have Apollo server and we're
Speaker 6: curious and oh, you know, there's probably two or three
Speaker 6: or four others, but they all work this really inefficient way.
Speaker 6: If you go from an author to a book to
Speaker 6: a book review, it just like it hammers, like each
Speaker 6: layer down in the graph is just call call call
Speaker 6: call call. It's just like fundamentally is as you get
Speaker 6: down in the graph, treating every single graph note as
Speaker 6: its own call. And this grast thing just like really
Speaker 6: flips it on its head. And even as you go
Speaker 6: down the graph, it's it's making one call for for
Speaker 6: all of the nodes that you're processing. So I think
Speaker 6: it has a really great opportunity to undo a lot
Speaker 6: of the performance sort of like hideousness that most graph
Speaker 6: q al things either have to just you know, back INDs,
Speaker 6: either have to just deal with or patch around, which
Speaker 6: is what we did and Joyce and yeah, it's still
Speaker 6: super small projects and I need to spend more time
Speaker 6: with it, but that is my pick. I think it's
Speaker 6: pretty neat.
Speaker 2: Awesome.
Speaker 3: All right.
Speaker 2: Well, if people want to connect with you, where where
Speaker 2: do they find you? Yeah?
Speaker 6: Sure, you know the joysto or m dot I ow,
Speaker 6: I do have a blog that I need to get to.
Speaker 6: It's I'm a little bit embarrassed about the name. It's
Speaker 6: draconianoverlord dot com. But I picked it a long time ago.
Speaker 6: I love it when I was younger and a little
Speaker 6: more idealistic.
Speaker 3: Maybe not idealistic, but Draconian Overlord is idealistic.
Speaker 6: Yeah right, Yeah there was a uh but uh.
Speaker 2: Aspirational depend to what your ideals are.
Speaker 6: Yeah right. But also the domain name was available, like
Speaker 6: I thought of it fifteen years ago, and it's like
Speaker 6: holy domain name is available. So anyway, that's my blog.
Speaker 4: Uh.
Speaker 6: And you know, a lot of the writing is kind
Speaker 6: of older for my earlier jaa you know Java sort
Speaker 6: of heyday back in the day. But yeah, I need
Speaker 6: to post more stuff there if anybody wants to go by,
Speaker 6: but Joyce would be the main place, you know. I
Speaker 6: love to have anybody drop by and say Hi, all.
Speaker 2: Right, cool.
Speaker 3: And I do want to say I like the philosophy
Speaker 3: of Joyce. I want to I just I just want
Speaker 3: to make it clear because I'm the naysayer out of
Speaker 3: the group, Like I'm the one who's always like skeptic.
Speaker 3: I don't believe it's gonna work. Why would anybody want
Speaker 3: to use this? And I like the philosophy. You really
Speaker 3: got me when you said, well, if you need the
Speaker 3: fancy stuff that's the five percent, like, just go do
Speaker 3: the sequel that that's that that you're gonna focus on.
Speaker 3: Just be the good. Just be good at the stuff
Speaker 3: that is the simple that people need the most, and
Speaker 3: not try to cater towards the stuff where people really
Speaker 3: should Just go do the sequel. That philosophy makes me
Speaker 3: believe that this is going to have and hopefully an
Speaker 3: eternal advantage over a lot of the other ones where
Speaker 3: they try to give you these like halfway kind of things.
Speaker 3: So that that's the main point. But it looks, it
Speaker 3: looks good, and like I said, ILike it looks obvious.
Speaker 3: It looks like, well, doesn't take a genius to figure
Speaker 3: this out. It did, but it's you know, when you
Speaker 3: look at it, sure it looks it looks obvious.
Speaker 6: Yeah, no, I appreciate it. I mean that's high praise
Speaker 6: for the looking obvious is totally the goal, that's what
Speaker 6: we're after, So I really appreciate that.
Speaker 2: Yeah, by the way, it was Mike Perham, that is
Speaker 2: the psych chic guy.
Speaker 6: Actually, I don't think I could have told you that.
Speaker 6: I had completely forgotten this mea but yes, yeah, that
Speaker 6: sounds right.
Speaker 2: Yeah, we've had him on Ruby Road because he's a
Speaker 2: truer guy.
Speaker 1: Anyway, let's go ahead and wrap it up until next time,
Speaker 1: folks max out.
Speaker 5: Mm hmm