From 2eef50c5c233b775338a56f29969e85d1e26ea5d Mon Sep 17 00:00:00 2001 From: Ed_ Date: Mon, 8 Jun 2026 21:49:35 -0400 Subject: [PATCH] transcripts --- ...suming_as_much_as_possible_andrewreece.txt | 3729 ++++++++++++++ .../wo84LFzx5nI_big_oops_casemuratori.txt | 4320 +++++++++++++++++ 2 files changed, 8049 insertions(+) create mode 100644 docs/transcripts/i-h95QIGchY_assuming_as_much_as_possible_andrewreece.txt create mode 100644 docs/transcripts/wo84LFzx5nI_big_oops_casemuratori.txt diff --git a/docs/transcripts/i-h95QIGchY_assuming_as_much_as_possible_andrewreece.txt b/docs/transcripts/i-h95QIGchY_assuming_as_much_as_possible_andrewreece.txt new file mode 100644 index 00000000..b49f5ef4 --- /dev/null +++ b/docs/transcripts/i-h95QIGchY_assuming_as_much_as_possible_andrewreece.txt @@ -0,0 +1,3729 @@ +# i-h95QIGchY transcript +# Source: https://www.youtube.com/watch?v=i-h95QIGchY +# Title: Assuming as Much as Possible +# Speaker: Andrew Reece +# Conference: BSC 2025 (Better Software Conference) +# Fetched: 2026-06-08 +# Segments: 3719 + +--- + +[00:00] Now I get to introduce Andrew Reese who +[00:02] I'm very lucky to work with at my day +[00:05] job where I work on Zcash. Andrew works +[00:07] on Zcash as well with me. Um Andrew is +[00:11] the only person well okay so I'm going +[00:15] to do an analogy that I heard John say +[00:16] once which is there's some kind of zen +[00:19] thing where you're pointing at the moon +[00:21] and you're trying to point at the moon +[00:23] but the guy is like yeah you're showing +[00:27] me your finger. I've seen your finger +[00:28] before. and you're like, "No, no, but +[00:30] like it's the moon." Like the thing, you +[00:32] know, it's the thing like over there. +[00:35] Um, so I have lots of conversations with +[00:37] Andrew where like there are these +[00:40] extremely like meta insightful +[00:42] conversations about programming and the +[00:44] nature of programming and patterns that +[00:46] show up and all these kinds of things. +[00:48] And um although he told me that he +[00:51] doesn't feel very smart about these +[00:53] things, I always find that these +[00:54] conversations for me are extremely +[00:56] stimulating. Uh, and I have all kinds of +[00:59] new ideas talking to Andrew. And so he's +[01:01] going to be talking about, see, I +[01:04] thought this was going to be like +[01:05] patterns in software, but it says +[01:07] assuming as much as possible. So, you +[01:10] know, I could have been informed earlier +[01:12] about that, but anyway. So, give it up +[01:14] for the very, very wise and insightful +[01:17] Andrew Ree. +[01:27] Hello everyone and thank you Sam for +[01:29] that far too kind introduction. Um yeah +[01:32] for those who don't know me I'm Andrew +[01:33] Reese. I am uh mostly known around these +[01:36] circles as the creator and lead dev on +[01:39] WhiteBox. Uh if you're unfamiliar it the +[01:42] very short version is it's a debugger +[01:44] with the timeline so you can track how +[01:46] data changes across time. The slightly +[01:48] longer version is that it's uh exploring +[01:52] what happens if you can generalize the +[01:54] features of a debugger and a profiler +[01:57] and a logger and a ripple. Um but we're +[02:00] not going to be talking too much about +[02:01] whitebox itself. Um I'll be pulling a +[02:05] few examples from the codebase just as +[02:07] jumping off points. +[02:10] My role in whitebox other than coding a +[02:15] large amount of it myself has been +[02:17] managing kind of one to five contractors +[02:20] at different times and as part of that +[02:24] it's very useful if you can understand +[02:27] the entire codebase and the basic +[02:31] premise of this talk is +[02:34] finding the +[02:37] patterns there you Go Sam. There are +[02:39] there are patterns in here. +[02:42] Finding the patterns uh in +[02:46] uh ways that you can write code that are +[02:48] friendly to both the developer and to +[02:51] the machine. So +[02:55] here we have two very exciting circles. +[02:58] Uh we have CPUs with all of their things +[03:02] that they're amazing at. Well, they can +[03:04] be they're very stupid, but they're very +[03:05] stupid very quickly, which is really +[03:07] helpful. +[03:09] um they aren't so good when it comes to +[03:14] indirection comes when it comes to +[03:16] branching when it comes to looking at +[03:18] memory they haven't seen before very +[03:19] quickly and then humans have their own +[03:22] set of features uh and there's actually +[03:25] a surprising amount of crossover here +[03:27] we're also not great at context +[03:30] switching into new places or jumping +[03:33] around and remembering the entire stack +[03:35] of things that we've been looking at and +[03:36] so it seems Like there should be some +[03:38] intersection between these for +[03:41] um +[03:43] making sure that we do things that are +[03:46] sympathetic to the machine and also are +[03:49] easy for humans as developers to +[03:51] understand your code. Now I mean so far +[03:55] science has not quite been able to +[03:57] determine whether developers are +[03:58] actually human. Um but it's it's close +[04:01] enough for the moment. Uh the +[04:09] Yeah, we'll be looking for the places on +[04:12] in this overlap where both humans and +[04:15] computers are able to understand and +[04:18] operate on these things quickly. We're +[04:20] not so much looking for complete +[04:22] optimization, but a default path that is +[04:26] straightforward, concrete, and then the +[04:30] CPU will by default be pretty good, +[04:33] although you can always optimize +[04:34] further. +[04:36] I want to take a brief moment to +[04:38] separate generalization from abstraction +[04:41] here. Uh in the there's a lot of +[04:43] crossover uh but I think they're +[04:44] different. And so I see generalization +[04:48] as um describing the +[04:54] describing the problem space with a +[04:57] slightly expanded vocabulary so that you +[04:59] can talk about more things but you can +[05:01] still talk about the same thing in +[05:03] exactly as much detail as you could +[05:04] before. And so my example here would be +[05:06] if you had a minimum function and you +[05:09] can do minimum of a and b you can +[05:11] generalize that to a minimum of anything +[05:14] in an array. You can still do two a two +[05:16] element array but you can do this larger +[05:19] domain as well. Now there are costs +[05:22] associated with generalizations but +[05:24] typically they don't have this same +[05:26] indirection that abstractions do. So +[05:29] abstractions as I tend to think about +[05:31] them are kind of a layer on top of the +[05:34] thing that you're actually doing. Uh +[05:36] where only certain variables only +[05:39] certain features are allowed to bubble +[05:40] through. It's kind of a semi-permeable +[05:42] membrane between the implementation and +[05:45] the um the interface that is presented +[05:48] to the presented above. +[05:51] Okay, let's get into it. +[05:54] Um, +[05:56] for me, lifetimes and stable pointers +[05:59] are a an incredibly useful architectural +[06:03] tool. So, fortunately, most of you have +[06:06] been to the Echoslavs talk the other +[06:08] day, and you'll know how he uses arenas. +[06:12] My use is very similar. Uh, but I'm just +[06:14] going to very briefly um walk through +[06:17] what arenas are for anyone unfamiliar. +[06:20] Uh the basic version of this is that you +[06:25] using some virtual alert tricks have +[06:28] what seems like an infinitely long block +[06:30] of bytes. Uh and then as you want to +[06:33] allocate things, you allocate the first +[06:36] bit and you bump the amount that you've +[06:39] used. Uh you push some other thing on. +[06:42] So maybe you push an array, then you +[06:43] push a strct, then you push a string. Uh +[06:45] and then at some point you are done with +[06:48] those things and you can either pop back +[06:50] to a previous point like that you've +[06:52] seen recently. Maybe you no longer need +[06:54] that string anymore. +[06:56] Uh you could have generated it for print +[06:59] f and then you're done with it for now. +[07:01] Or uh very usefully you can just wipe +[07:05] the entire thing and your arena is now +[07:08] empty and ready to be used for something +[07:09] else. +[07:10] Now in practice uh in my codebase and I +[07:13] think most others who use arenas uh we +[07:15] tend to use multiple of them and so we +[07:18] have many of these stacks that are +[07:21] operating in parallel. Um you can think +[07:24] of these stacks somewhat like a call +[07:26] stack in that after you're finished with +[07:28] things you can you can pop back. Um but +[07:32] the +[07:34] so so what this means is if you're if +[07:35] you're pushing onto one arena +[07:38] and you have your your data at the end +[07:41] um then once you've popped back +[07:45] everything after that point is +[07:47] invalidated effectively. Uh and so this +[07:50] presents our first problem which is uh +[07:53] we quite often want to interle things +[07:57] that happen on different lifetime things +[07:59] that are conceptually nested but which +[08:03] happen um yeah in interled. +[08:07] So +[08:09] as well as having the hierarchy of the +[08:12] the stack itself, there's also a +[08:15] conceptual hierarchy of uh the arenas +[08:19] themselves. +[08:21] So here we have kind of permanent app +[08:23] lifetime arena and pretty much +[08:25] everything is conceptually underneath +[08:28] that. Um, +[08:31] now one of the nice things if you have +[08:33] this conceptualization is that if an +[08:37] inner arena gets a pointer to something +[08:41] in an outer arena, +[08:43] it knows that its lifetime is going to +[08:45] outlive the lifetime is going to extend +[08:47] past its own. And so if we can make sure +[08:51] those pointers are stable, then we can +[08:53] keep that pointer indefinitely until say +[08:56] our run closes. um it it can keep +[08:59] pointers into the app. +[09:03] The interle for instance an example of +[09:05] that happens inside runs. Um as a +[09:08] debugger we get uh all sorts of debug +[09:11] info from the OS and that includes a +[09:15] breakpoint. So when a breakpoint +[09:18] happens, the process stops, we get +[09:20] control and we want to do some caching +[09:22] to make sure that we're only reading the +[09:25] same memory uh once within within that +[09:28] break, for instance. And +[09:32] we do that caching interled with +[09:35] recording stuff that is going to be true +[09:37] for the entire run. So we want to save +[09:40] some data, save some recording uh and so +[09:43] that will go in the run while the stuff +[09:45] that only wants to stay in the uh that +[09:48] only extends for the entire event stay +[09:50] in the event cache. Okay, I think I've +[09:53] done that to death. Let's move on to +[09:55] some more interesting topics. Type +[09:58] mappings. Now you're going to see some +[10:00] familiar things here if you were at +[10:02] Ryan's talk. +[10:05] Whenever you're designing a system, you +[10:09] have a large amount of choice in terms +[10:13] of where what you determine statically +[10:17] at compile time in your type system and +[10:19] what gets determined dynamically at +[10:22] runtime. +[10:24] in a an initial incarnation of whitebox +[10:27] where the primary focus was around JIT +[10:30] compiling small chunks of code and then +[10:33] uh debugging those. We had control over +[10:35] the full um +[10:38] uh the full pipeline of compilation and +[10:40] we we happened to be using clang +[10:43] um which generated dwarf information. +[10:46] The so the first version of this we we +[10:49] were using this dwarf debug information +[10:52] and that is every type of debug +[10:54] information excepting line information +[10:56] but that's beside the point. So types +[10:59] compilation units uh functions variables +[11:02] all of that is a debug information +[11:03] entry. +[11:05] Uh and basically all of the interesting +[11:08] stuff interesting stuff happens inside +[11:11] this dwarf attributes list. +[11:15] So that's fully generic, all determined +[11:17] at runtime. Sorry, fully dynamic, all +[11:19] determined at runtime. And then on the +[11:22] opposite side of the spectrum, uh let's +[11:24] have a look at Clang's version of types. +[11:29] Um yeah, so these are all subasses of +[11:32] type. And what you're not seeing here is +[11:36] all of their subasses. +[11:38] Um and also all of the things that they +[11:41] multiply inherit from. +[11:45] Right. +[11:46] So +[11:49] given the our experience with dwarf +[11:51] debug information um +[11:55] as we moved into doing full executable +[11:58] debug in full executable debugging +[12:02] um we needed to handle PTBs and so we +[12:04] needed our own format that could handle +[12:07] both dwarf and pdb and we decided to go +[12:11] with kind of somewhere in the middle in +[12:13] that static dynamic uh split it. +[12:19] Um, so whereas +[12:22] you have this many types in clang, we +[12:24] have one. Uh, but then we also have one +[12:26] of these these other main types. Uh, I'm +[12:28] going to focus on types mostly uh later +[12:31] on. +[12:33] So this will be familiar if you were +[12:36] here yesterday. +[12:38] uh each type entry uh sorry each kind of +[12:42] conceptual type gets an entry uh in our +[12:45] type arena. +[12:47] Um so that can be strcts or base types. +[12:52] We got enums that have an underlying +[12:55] type of that base type. aliases, type +[12:58] defafs of those uh arrays, pointers, +[13:02] pointers to type defs, uh qualified +[13:06] types, pointers to qualified types, +[13:09] double pointers, +[13:11] qualified pointers. +[13:14] Yeah. Um +[13:18] yeah, as as I said, if you were here at +[13:20] Ryan's talk, uh you would have seen +[13:22] something very similar to this. Now, +[13:25] unfortunately, as some of you may be +[13:27] aware, um Ryan is no longer with us. +[13:34] >> Maybe it sound like something happened. +[13:37] >> But he would want us to go on in his +[13:39] absence. +[13:42] >> He's fine. He's just had to leave early. +[13:45] So, you you'll notice that all of these +[13:49] uh all of these pointers are going in +[13:51] one direction. They're all kind of +[13:52] pointing downwards in this graph and +[13:55] that is kind of towards this notion of +[13:58] an inner type and that'll come up in a +[14:01] sec. +[14:03] So this is a slightly a bridged version +[14:06] of our types. Um you can see there's +[14:09] kind of a general tag uh name size this +[14:12] inner type thing I mentioned and then +[14:14] some uh per type information. You'll +[14:17] note that the inner type is always +[14:19] available. Uh, and +[14:23] one of the things that +[14:25] having been through the whole make a +[14:27] debugger process before, uh, you realize +[14:29] is that +[14:32] you really want be able to get these +[14:34] inner types. Uh, it's a really useful +[14:36] thing to be able to do. Um, as I +[14:39] mentioned, we have these qualified types +[14:41] and enums and aliases. And sometimes, +[14:43] you know, if you're if you're presenting +[14:45] this to the user as a type, that's +[14:47] information that you want to know and +[14:48] you want to be able to show that. But +[14:52] quite often, you know, if you're reading +[14:55] data, you don't really care whether it's +[14:57] an S4 or an int. You just want to know +[14:59] how many bytes to read and how to +[15:00] interpret them. Uh, so we have this +[15:04] inner type for finding that, finding +[15:06] that out. +[15:08] You'll notice that we have this nil type +[15:11] at the bottom. +[15:13] And that is an entry into our type array +[15:18] that basically does nothing but is a +[15:20] place for things that don't actually +[15:22] have an inner type to legally point. And +[15:24] you can see that this points back to +[15:26] itself, which means if you aren't sure +[15:29] whether something has an inner type, you +[15:30] can safely just read it and you can do +[15:32] inner type of inner type of inner type +[15:34] of inner type and you can safely access +[15:37] this. um which just makes +[15:41] it makes the code that is using all of +[15:43] this type information so much easier to +[15:45] read without having to qualify +[15:48] everything in conditions about whether +[15:49] or not there isn't is an inner type. +[15:53] Now normally I'm I'm on the zero is +[15:56] initialization train. Um but this of +[15:59] course uh doesn't apply here because +[16:02] this is a pointer not an index. uh we +[16:04] need to actually initialize this. +[16:08] So I was thinking about this and I was +[16:11] wondering like why is this an +[16:13] appropriate time to be doing something +[16:16] other than zero zero is initialization? +[16:18] What am I what am I giving up here? And +[16:22] the the conclusion I came to was that +[16:27] our our type concept is kind of an outer +[16:30] level strct within our program. there's +[16:33] an array of these effectively +[16:36] um and nothing else things will point to +[16:40] types but nothing else actually contains +[16:42] them. +[16:44] Nothing else actually contains them. +[16:47] Now this means that when you're +[16:48] initializing if you're initializing a +[16:51] strct uh if it's a if it's a type you're +[16:55] basically doing it because you care +[16:57] about the type. You're only doing it for +[16:59] the for the sake of initializing a type. +[17:01] And so it's really not very much extra +[17:03] extra cost to do this nil type thing. Uh +[17:07] it's also +[17:09] uh it's also the case that because we +[17:11] have this as an array uh the array +[17:13] itself is zero initialized. Uh so you +[17:16] have you know n elements equals zero. +[17:21] Um but then as we saw +[17:26] the the types of strcts that are +[17:28] contained like strings kinds uh those +[17:30] are all zero initializable. So yeah I +[17:34] think this kind of containment idea is +[17:35] at least a partial heristic for that zi +[17:38] or nil type uh dichotomy. +[17:43] Okay. So +[17:46] we've got this typekind tag at the top. +[17:51] Um the normal way of doing this default +[17:54] I think is you have an enum and it just +[17:56] increments from zero and you know +[18:00] doesn't really mean anything. It's just +[18:02] an arbitrary identifier so you can +[18:04] distinguish between different things. Um +[18:06] the kind of the most semantic use of +[18:09] this is as an index into lookup a lookup +[18:13] table. So you might have some metadata +[18:15] like strings or sizes or something else. +[18:18] Uh and you would read that with you know +[18:22] enum strings enum b and get b out. +[18:26] Uh if you're feeling slightly spicy, you +[18:29] can order these in a particular pattern +[18:31] so that you can do uh simplifi like +[18:35] pretty small evaluations to do more than +[18:37] one check more than one thing at once +[18:39] and group them into some uh some +[18:42] pattern. +[18:45] The other common use for enums is as +[18:48] flags. So you have each bit uh is either +[18:52] you you have each flag is typically one +[18:55] bit set uh at some position in the +[18:58] number and you can it's a bit more +[19:01] flexible because you can have +[19:02] non-ontiguous elements all grouped +[19:04] together in this kind of flag CDE and +[19:06] that's pretty much entirely what it's +[19:08] used for is allowing you to have all of +[19:10] these booleans uh and switch switch them +[19:13] all on and off independently. +[19:17] So our outer types um the pointers, the +[19:21] qualifiers, the strcts, enums, all of +[19:24] that, +[19:25] we don't really have a huge number of +[19:27] them. And you know, we're doing debug +[19:31] information. It's it's stayed pretty +[19:33] much the same for a long time. And I +[19:35] think we can assume here that it's going +[19:37] to remain the same for at least a while +[19:39] longer. I think we have about 19 +[19:41] different types here. And you you may +[19:43] see where this is going. Um, one of the +[19:46] things we can do is we can just turn +[19:49] each of those into a flag. +[19:52] Now, we're ignoring base types for the +[19:54] moment. +[19:56] This may look a little wasteful. +[20:00] Uh, you know, we're using one to the 26. +[20:03] That's uh that's a very large number. +[20:06] Um, you don't really want to be indexing +[20:07] with that. But we buy some stuff with it +[20:11] and I think it's worth it. This this +[20:14] only really works because we know this +[20:15] max bound that we've we've got of +[20:18] there's only a fairly limited number of +[20:20] things that we we want to represent. +[20:24] And because we we're treating these +[20:27] things as flags, we can group them +[20:28] because it's it's actually quite common +[20:30] in debug code to be uh to segregate +[20:34] different code paths by various +[20:36] different groups of type information. So +[20:38] often you want to treat pointers and +[20:39] arrays quite similarly. sometimes +[20:41] arrays, pointers. Uh we can see we've +[20:44] got arl and nonar valvel refs. U strrus, +[20:47] unions, and classes are all types of +[20:49] records that you want to often but not +[20:51] always want to treat the same. +[20:55] Welcome to our separate bplot +[21:00] bits are high level. +[21:05] In this case, we are continuing on where +[21:08] we left off with +[21:11] and and or operators. +[21:14] Now, you are hopefully familiar with +[21:17] these. Uh we saw before +[21:20] uh you know, we had these these flags +[21:22] and we get to set them. Now the cool +[21:25] thing here is that we basically get to +[21:26] treat our um the kind of the thing we're +[21:29] querying against as a set and we get to +[21:33] um we get to query that with our kind. +[21:38] Now because of the way that uh these +[21:42] work where we only ever have kind of one +[21:45] additional qualifier or pointer per +[21:47] thing, we only ever have one bit set in +[21:51] this kind if in the outer types. +[21:56] Um so we get to do a multiple lookup +[21:58] with a single operation. +[22:01] The computer is fantastic at ends. It +[22:04] has no problem with them at all. And +[22:06] this um oring these things together I +[22:10] mean ores are cheap enough as it is but +[22:13] um this will just get evaluated at +[22:15] compile time and treated as a single +[22:16] value. +[22:19] Okay. And then we have this ability to +[22:22] uh to invert the bits and we can check +[22:25] whether or not check that our thing is +[22:27] not one of these things. +[22:29] Now +[22:31] this is simple right? But if you don't +[22:35] approach this through the lens of what +[22:38] can I achieve using flags, what can I +[22:40] how can I how can I make do this in a +[22:43] sympathetic way, it's very easy to end +[22:45] up with, you know, a completely abstract +[22:47] set type or uh you know just a loop over +[22:52] an array which is it's not the end of +[22:54] the world. But if we can do that in a +[22:56] way that is incredibly concrete, +[22:58] incredibly simple, and easy for the +[23:01] computer, that seems like a a complete +[23:04] no-brainer. +[23:12] All right, so +[23:18] we have this inner type. we have this +[23:20] primitive way of determining whether um +[23:27] whether a type is of a particular kind. +[23:30] What's quite common is that we actually +[23:33] we want to get through all the way as I +[23:34] mentioned before we don't care about +[23:37] many of these steps uh on the on the +[23:40] path. We just care about the innermost +[23:43] thing. And so a useful thing to be able +[23:46] to do is just we can loop over our um +[23:51] our anquery. +[23:53] And so you end up with a very simple +[23:55] way. Uh once you're familiar with this, +[23:57] this is about as simple a loop as it +[23:59] gets um and we +[24:03] can skip through enums and qualifiers +[24:05] and whatnot. Uh and get our type out. +[24:08] And then you can do the inverse and find +[24:10] the first instance of something. Again, +[24:12] very simple loop. +[24:14] Okay, so I was I was looking through my +[24:17] notes and I got to this point. I was +[24:19] like, +[24:20] "Okay, who who cares? +[24:23] How is this how is this helpful?" Um, +[24:26] and +[24:29] the important thing here is what's not +[24:32] here, right? So, I look back at the +[24:35] dwarf code and the equivalent of this is +[24:40] this. +[24:42] Now, +[24:44] that's not a totally impenetrable amount +[24:46] of code. You you could read through this +[24:48] and understand it. Um, +[24:52] but this is basically a primitive in all +[24:54] of your debug operations. And so when +[24:56] something goes wrong, you have to now +[24:59] question whether this is correct. +[25:03] Would you prefer to be using this as the +[25:05] primitive or this? +[25:10] Okay. +[25:12] Now +[25:15] we've done this by looping over the +[25:17] different pointers. +[25:19] An alternative we could have taken was +[25:21] would be to +[25:23] basically cache these uh these mappings +[25:26] early on and have this pass through +[25:30] alias pass through qualifiers pass +[25:32] through qualifiers except not atomic +[25:34] types because those needed for separate +[25:35] things. Um, but that gets +[25:39] it's unnecessarily expensive and we can +[25:41] do it fairly easily with this functional +[25:42] mapping. +[25:48] Okay, we've gone we've gone inwards as +[25:52] it were. Um, but sometimes we want to go +[25:54] outwards. We've started with a pointer. +[25:57] We've got our int. Uh, but in many cases +[26:00] we want to do the opposite. What is the +[26:02] pointer type for this value? Do we have +[26:04] one? If not, we can create one. But +[26:06] let's at least try and get the canonical +[26:08] version first. +[26:11] So +[26:15] we could have done the same as here +[26:18] effectively and tried to added the +[26:21] pointer to the equivalent pointer type, +[26:24] the equivalent reference type, the +[26:25] equivalent um volatile, all of those +[26:28] things. Again, it's it's pretty sparse. +[26:31] Like most of these things don't actually +[26:33] have outer types. +[26:35] Now I was thinking of this in those +[26:38] terms. Think of this as a reference to +[26:40] the outer type and +[26:45] at some point +[26:47] kind of a an audible click happened in +[26:49] my head as well first of all I slapped +[26:53] my forehead that might have been part of +[26:54] it. Um, +[26:56] but if you reframe from +[26:59] references to mappings, +[27:02] it's very it's obvious like what is the +[27:05] canonical map? A map, a hashmap. +[27:09] You can just map from type to type. And +[27:13] because we have stable pointers, um, you +[27:16] can easily treat those as keys and +[27:18] values. +[27:20] Again, we have another choice to make +[27:22] here. Um, do we want to +[27:26] have a very simple map but one of them +[27:29] per kind of um per kind of mapping that +[27:33] we want? Uh, or do we want to include +[27:36] that outer type kind uh the kind of +[27:39] thing that we're looking for with a +[27:41] qualifier or a pointer in the key to our +[27:43] map itself. +[27:45] And +[27:47] this kind of trade-off often comes up +[27:49] where you want you you can choose +[27:51] between many simple things or one +[27:54] slightly more complicated thing. And in +[27:56] this case, I chose the slightly more +[27:58] complicated thing as it's only a little +[28:00] only a little bit more complexity. +[28:05] More choices appear. Um how do we want +[28:09] to hash this thing? So uh you will note +[28:12] the explicit padding in here because +[28:14] otherwise you might not get those as a +[28:16] value that you expect. The compiler +[28:19] might do anything with them. Um but this +[28:21] way with the uh with all of the bytes +[28:24] filled we could just hash variably. +[28:26] That's the kind of most most generalized +[28:28] version. But we know the type of thing +[28:31] that we're doing. We know it's fixed +[28:32] size. Let's make assumptions about that +[28:35] and benefit from it. we can do a two +[28:38] element hash and turn that into +[28:42] um the thing that we use as the key in +[28:44] our app. +[28:47] But we know more about the platform that +[28:50] we're operating on. +[28:53] So +[28:55] on 64-bit systems, specifically x8664, +[29:01] what do we know about pointers? +[29:06] They're not actually 64-bit. +[29:09] Uh at typically they are 48 bit +[29:13] occasionally 52 and uh I think Arch 64 +[29:18] um ARM 64 has some 56 bit uh address +[29:23] bases. +[29:25] This basically means we have 8 bits +[29:27] guaranteed at the top of our uh pointer +[29:30] given that we know our platform. And +[29:32] I'll point out that uh as a debugger, +[29:34] you have to know your platform. Uh and +[29:36] so portability is already uh it's not +[29:39] it's not a cause that we can go for. Uh +[29:41] so let's let's take advantage of this +[29:43] and use those top eight bits. +[29:47] Ah +[29:49] uh it seems like we may have hosed +[29:52] ourselves here because we've got massive +[29:54] values, right? We can't just put those +[29:56] into eight bits. Um, +[30:00] but let me introduce you to your new +[30:02] best friend. Okay, we've got left +[30:05] shifting. These are one left shifted by +[30:08] 20, one left by 8, all of that kind of +[30:10] thing. And that takes us from 8 to 256. +[30:14] There's an operation that goes in the +[30:15] other way and that is most significant +[30:18] bit. +[30:21] You will find this incredibly useful. +[30:25] You can you have to do this slightly +[30:27] differently on clang and MSVC. Clang has +[30:29] the benefit that it will happen. It will +[30:31] do it at compile time. Uh you have to do +[30:34] some nasty hacky tricks on MSVC to make +[30:37] that happen. +[30:40] Okay, +[30:42] let's see if we can +[30:46] learn by testing. Anyone in the +[30:48] audience, what is the most significant +[30:50] bit here? +[30:53] >> One. Yes. +[30:54] here. +[30:56] >> Yes. Here. +[30:59] >> Yes. Okay. So, we're we're counting from +[31:01] the right from the least significant bit +[31:02] and the furthest thing is the most +[31:04] significant bit. Great. Uh most sign +[31:07] most significant bit here. +[31:10] >> None. +[31:11] >> No. Yeah. It's failure +[31:13] >> undefined. Yes. +[31:17] So, this is just something to be aware +[31:19] of. Okay. Well, we can look back at our +[31:22] flags and um the way we've described it, +[31:26] each of these is going to be the most +[31:27] significant bit. Is it 8 9 10 11 12? +[31:31] Great. And that's part of the reason +[31:32] that I write it that way rather than the +[31:35] zero xf whatever. +[31:38] Cool. So, uh we have 26 is our max value +[31:43] now. Uh and any any guesses for number +[31:47] of bits that you can represent 26 in? +[31:51] >> Five. +[31:53] >> Correct. +[31:55] Um we're doing one to the 32 +[31:57] effectively. +[32:00] Uh and so we can +[32:04] we can get our pointer, we can get our +[32:07] uh kind and we can put these together. +[32:09] And I think I have written those. Oh no, +[32:13] there's the correct way around. Great. +[32:15] Cool. So +[32:17] we are in this case shifting the pointer +[32:21] up and putting the kind at the bottom. +[32:25] And this is the machine code that uh +[32:28] corresponds to that. +[32:30] Um this BSR is basically the most +[32:33] significant bit that we saw earlier. uh +[32:37] the compiler gets to make an extra +[32:39] optimization here because uh it knows +[32:42] that the value is never above um it +[32:45] never uses more than five bits. So it +[32:46] doesn't even have to end here. +[32:49] Okay, we we did it that way around. Um +[32:52] we had a choice though. We we could have +[32:54] done it the other way around. Uh what +[32:56] happens there? Yeah, it's, you know, +[33:00] it's fine, but +[33:04] unless you have a reason to choose +[33:05] otherwise, you may as well go with the +[33:07] uh the nice smaller one. U less +[33:11] instruction pressure, I catch pressure. +[33:14] Um, and it also uses fewer registers. +[33:18] Um, the other nice benefit of using the +[33:21] small value at the bottom with a pointer +[33:22] at the top, uh, is that if you're really +[33:24] pressed for bits, you may be able to +[33:26] take some from the alignment bits of the +[33:29] type of the pointer. Um, but yeah. Okay. +[33:33] Is is this useful? Is this um like how +[33:38] much of an impact is this really going +[33:39] to have? And to be honest, probably not +[33:42] that much. +[33:44] um choosing one over the other. But once +[33:48] you know this, there is just zero effort +[33:51] to choose the the one that's better. +[33:55] So you have no excuse now. Okay, +[34:00] welcome back to bits a high level. +[34:03] We've been our main thread has been +[34:05] preempted +[34:06] and we're going to talk about +[34:10] bits. +[34:12] Okay, so +[34:14] you get some some bitwise number and the +[34:18] normal interpretation of this is to just +[34:20] treat it treat them all as one value. So +[34:22] this is 233. +[34:25] But there's no reason that you can't +[34:27] split out different fields from this +[34:29] value and treat those as their own +[34:32] separate values. So here because they're +[34:35] four bit they each fit into a nibble or +[34:37] a 16 bit um digit +[34:43] um yeah 14 and nine in this case. +[34:47] Okay. So what can we do with that if we +[34:50] if we split these numbers into multiple +[34:52] parts? +[34:53] All right. Let's start off simple. So we +[34:55] we take our take a couple of bits at the +[34:57] bottom and we can have four values with +[35:00] those. uh we might then add an uh a +[35:07] three length axis on top of that using +[35:10] another two bits. So we have 4x3 and +[35:13] then we we have this kind of rectangular +[35:15] array of uh of different values. +[35:19] Uh you can you can think of that as an x +[35:21] and a y axis. +[35:24] uh and then we can add a uh two length +[35:28] or yeah one bit dimension on on our Z +[35:31] axis and now we have effectively a +[35:33] little 3D mapping within a single number +[35:39] and that's where the uh the value at the +[35:42] top exists. +[35:44] So +[35:45] yeah our our friends in the array +[35:48] programming language world would call +[35:49] this kind of a rectangular mapping. It's +[35:51] basically what they their entire data +[35:53] structure everything is in this format. +[35:56] Uh our our friends in the functional +[35:58] world would call this a product type. Uh +[36:00] and you can you can kind of see why here +[36:02] because you're tsing four by 3x two as +[36:05] the number of different possibilities +[36:06] that you have. Um and another another +[36:09] way of thinking about this is +[36:10] effectively each of these different +[36:12] color dimensions is a strct member. +[36:18] So, +[36:22] I like this rectangular view. Um, but +[36:26] there's there's a more general one, +[36:27] which is this tree. And each time you +[36:30] hit a bit or each time you hit a new +[36:32] dimension, you can split off into +[36:35] however many different options that +[36:36] dimension has. +[36:39] Um, this is occasionally useful for +[36:42] coming up with the shape of things, but +[36:44] probably not great to think about once +[36:46] it's in there. And you'll see why in a +[36:47] sec. +[36:50] Uh, yeah, same same position, but now in +[36:53] this different interpretation. +[36:56] And I I'll say here, and I'll probably +[36:57] say it again, that one of the great +[36:58] things about +[37:01] uh bitwise numbers is that you can +[37:03] interpret them in multiple different +[37:05] ways at different times. and being able +[37:07] to switch between them uh for for the +[37:10] same bit pattern, being able to switch +[37:13] between different interpretations of +[37:14] that um from one moment to the next can +[37:17] actually give you quite a lot of power. +[37:21] So this tree version is even more +[37:23] general. Uh you don't actually have to +[37:25] have even dimensions the whole way. You +[37:27] can uh once you've decided on your first +[37:30] split, you could completely reinterpret +[37:31] the bits differently. So here we have um +[37:35] on the left two by 3x4 and on the right +[37:39] is 2x two by two by two by two. I think +[37:43] I said too many twos. +[37:46] Um again +[37:49] this can encode potentially more +[37:52] different things. You'll see in a sec. +[37:55] But if you can avoid it I would +[38:01] Yeah. +[38:03] Right. Then let's bring it back to +[38:05] types. So we'll start with this tree uh +[38:09] tree view on this this type question. Um +[38:12] there's different ways we could break up +[38:13] our space of types of base types +[38:16] specifically. Um you know we're dealing +[38:18] with floats, dealing with unsigned and +[38:20] signed integers, booleans, chars, that +[38:22] kind of thing. Uh, and each of each type +[38:28] has kind of a a general type kind like +[38:31] signed or unsignedable whatever. Um, and +[38:34] also a size. +[38:37] Now +[38:39] um you know this this float and scaler +[38:42] thing I happen to know is useful in some +[38:44] circumstances when you're um you're +[38:47] interpreting the base type and you maybe +[38:50] you want to encode that in there so you +[38:52] get this information for free um but you +[38:54] end up with this kind of slightly +[38:55] lopsided tree where um +[39:00] doesn't all really it doesn't fit into +[39:02] this +[39:03] this neat multiple dimensions thing that +[39:05] we mentioned earlier. +[39:07] Another thing I'll point out here is +[39:09] that we have these +[39:11] we have we have an outlier case um that +[39:14] is F10 an 80 bit x87 fpu float um and +[39:21] whenever you whenever you try and map a +[39:24] space whenever you try and generalize a +[39:26] model well you often you will often come +[39:29] across situations where ah there's an +[39:31] exception +[39:34] and again at that point you have a +[39:35] choice +[39:36] Do you want to generalize your model so +[39:40] that you can account for this or do you +[39:43] want to um keep the model nice and +[39:46] simple and then +[39:48] keep an keep the exception for the +[39:51] unusual case and you can keep that in +[39:54] the um the interpretation of the data +[39:56] kind of with the the tree style thing we +[39:58] saw before. um you can treat that you +[40:02] can use that do that in the code with +[40:04] whenever you're dealing with stuff you +[40:05] just have an extra if it's uh if it's an +[40:07] 80- bit float um +[40:11] yeah you have that choice now I guess I +[40:13] probably should have mentioned before +[40:15] the convention we have in the codebase +[40:16] is that unless bits are specifically +[40:21] otherwise required uh types normally +[40:23] specified in terms of their bite size +[40:24] not their bit size um +[40:28] yeah and again We've we've got this nil +[40:30] type +[40:32] uh and there's only really one nil type +[40:36] and each of these kind of bottom layers +[40:39] on the tree has four values and that +[40:43] means we're we're oversp specifying nil. +[40:46] Well, you can you can ether interpret as +[40:47] there's a a one bite nil, a two byt nil, +[40:49] a four by nil, and an 8 by nil. Or you +[40:51] can interpret that as there's a one bite +[40:54] nil and then there are three holes in +[40:56] our space. +[40:58] Um +[41:01] now +[41:04] for a certain interpretation that's a +[41:06] problem. Um but if you are willing to +[41:09] ignore it then you get a lot of utility +[41:11] from that. +[41:14] This is another breakdown of that of +[41:17] that tree. Um I know I'm missing +[41:19] unsigned char and v various other things +[41:21] here. Um but let's go with this as a +[41:24] simple version for the sake of the talk. +[41:27] um we're we're just kind of accepting +[41:28] that we have holes where all of our nils +[41:30] are. Uh and in practical use, we don't +[41:34] really have um 8 bit or 16 bit floats +[41:37] that we have to deal with. Uh although +[41:40] just by having this type system, we now +[41:43] handle that um even if unintentionally. +[41:50] Okay, so I mentioned you want to it's +[41:53] useful to be able to think of this as a +[41:55] uh as a as a clean separation of +[41:58] dimensions uh and rather than as the +[42:02] tree. If if you're thinking it as the +[42:03] tree, what typically happens is you have +[42:06] to do each decision point in the tree as +[42:09] a separate conditional. Um, so not only +[42:12] are you nesting bunch more, you're kind +[42:14] of adding this this layer of indirection +[42:16] in your code, you +[42:19] just end up with n * m different um for +[42:24] however many dimensions you have +[42:27] uh different cases you have to handle. +[42:29] And quite often if you have neat +[42:31] dimensions, you can take the value on +[42:33] one dimension, handle that, take the +[42:34] value on the other dimension and handle +[42:36] that as separate cases and end up with n +[42:38] plus m cases instead. +[42:42] Okay, +[42:44] right back to how this works in the +[42:47] codebase. So, we have our types arena uh +[42:50] as a as a top level debug information or +[42:54] debug information type. Uh it ends up +[42:57] being useful basically having an entire +[42:58] array just for types. Um +[43:03] so we have our base types at the bottom. +[43:06] Uh we've got I should have mentioned we +[43:09] have basically end up with four bits for +[43:12] the um the kind and then four bits for +[43:14] the size. Um +[43:19] so we yeah we have 256 +[43:22] uh different locations here. We then +[43:24] have some other built-in types um which +[43:27] we know we're going to need but don't +[43:28] really fit neatly into this. So that +[43:29] includes things like the XMM type uh and +[43:33] you know the Windows thread exe +[43:35] execution block type that kind of thing. +[43:38] Uh and then we just have everything +[43:40] after that. It's pretty much completely +[43:41] arbitrary. Um we have +[43:46] our pointers, our qualifiers, all of +[43:48] that in there. +[43:52] Okay. So we have our different +[43:56] components of our our values. We have +[43:58] our kind and we have our size. Um +[44:02] the fact that we have these as separate +[44:04] components mean not only can we given a +[44:06] type determine both of these we can then +[44:08] re recombine them uh after having done +[44:11] some calculation uh and then find the +[44:14] new computed type. We don't have to +[44:16] indirect this through multiple lookup +[44:19] tables. It's just oring two small +[44:21] numbers together. Uh and this this case +[44:24] is for integer promotion. This is a +[44:26] small snippet as part of that uh where +[44:28] you have to take both kind and size into +[44:29] account. +[44:33] Okay, let's +[44:35] we have both this base type and the +[44:38] other outer types the the qualifiers the +[44:41] pointers and so on. Those are both +[44:42] within our type kind. And this is where +[44:45] I think it gets really cool. Um we do +[44:49] our pass through. We we get the kind of +[44:51] base type as part of that. Sorry, the +[44:53] the the innermost type that we care +[44:56] about as part of that. And then we can +[45:00] switch on this and filter our switch to +[45:02] the level of detail that we care about. +[45:05] So we can mask off we we can basically +[45:08] treat all base numbers and enums the +[45:12] same thing and then they only have have +[45:14] to deal with a single case in our switch +[45:15] statement rather than dealing with what +[45:18] would that be? you know 256 I guess from +[45:21] the previous thing different options +[45:22] from in our lookup table. Um +[45:27] we can then deal with the different out +[45:30] types as as separate things. Another +[45:33] case um in this one we are looking at +[45:39] return values on windows. So that has a +[45:41] particular um particular API particular +[45:44] calling convention. Uh, and in this +[45:47] case, we don't care about the size of +[45:49] the type, but we do care what kind it is +[45:51] because floats get treated differently +[45:53] from basically everything else. Uh, and +[45:56] you can see again there's there's, you +[45:58] know, it's not no entries here, not no +[46:00] cases, but we don't have to deal with +[46:02] the entire type spectrum if it as if it +[46:05] were just a uh a flat undifferiated +[46:09] arbit arbitrary number. +[46:13] And the last case +[46:15] um we can look at just the inner type +[46:17] and then um basically ignore all um +[46:23] ignore all of the outer types, ignore +[46:24] all the qualifiers. And there's another +[46:26] case I didn't add here which is uh where +[46:28] you want to read data. It's useful to +[46:30] know uh what it is so that you can if +[46:32] it's a signed variable and it's smaller +[46:34] than eight bytes um you want to read it +[46:37] and make sure you sign extend it. Uh, +[46:39] and so that's a case where the full base +[46:41] type rather than just one of these +[46:43] components is helpful. +[46:46] Okay, +[46:48] end of part one. +[46:51] Welcome to part two, stacks and +[46:53] stackability, where we're going to talk +[46:55] about white box, the the workings of +[46:57] white box that help it work more like a +[46:59] profiler. +[47:01] Uh so +[47:04] again, white box collects things over +[47:07] time and it can collect things in +[47:09] multiple threads at once. +[47:12] Uh this breaks down for um +[47:18] both both gooey purposes and the +[47:21] internal structure happen to mirror +[47:24] quite nicely here. Uh so hopefully this +[47:26] this will make sense. we have our kind +[47:28] of general run recording and inside that +[47:33] we have um run threads and inside of +[47:36] that we have multiple levels on a call +[47:38] stack. Inside that we have all of our +[47:42] many calls that have happened within +[47:44] that call stack. Uh and then in inside +[47:46] that we have an individual call to a +[47:49] particular function. +[47:52] Now couple of things to note here. +[47:58] Firstly, um, all of these things are +[48:03] on, +[48:05] you know, we have many levels of nesting +[48:07] here and and while I said we have a few +[48:09] arenas, we don't want an unbounded +[48:11] number of arenas. +[48:13] Um if we had an arena per thread, you +[48:16] know, most people many people in here +[48:18] will be sane with their use of threads. +[48:20] But uh in in the general case, there's +[48:23] really not much of a uh not much of a +[48:26] bound there. And that goes for each each +[48:29] entry in this dimension. +[48:32] So we we don't want to just have an +[48:34] arena per array. We want some other some +[48:36] other notion some other method of +[48:38] storing this information. +[48:42] The other thing I'll note here is I +[48:45] still want my stable pointers. They're +[48:46] really useful. Okay, I'm going to keep +[48:49] them. Nothing will stop me. +[48:54] Right. So, an alternative view on this +[48:57] is this. This is with the kind of tree +[48:59] that we're forming. There are other +[49:01] things at each of these levels, but +[49:02] they're not important. +[49:05] Um, I want my stable pointers to calls. +[49:08] Okay. or each individual call instance. +[49:12] What are the options we've got? Okay, +[49:14] I'll start basic. You know, we just +[49:17] pre-allocate some array and it's big +[49:20] enough and we just use as much as we +[49:22] need and we know that we're not going to +[49:24] need more. Um, works in some cases. It's +[49:28] not going to work here. There's too many +[49:30] each of the things is both too big and +[49:32] too volatile in uh too dynamic in how +[49:35] large they end up being. Um and that is +[49:38] true at each level of the stack whether +[49:39] or not it was kind of directly there or +[49:41] indirected via pointer. +[49:44] Probably the default solution here would +[49:46] be a kind of realoclock array where you +[49:48] start with something fairly small and +[49:50] then you double it uh and you move the +[49:53] pointer to the new thing and then you +[49:55] keep a reference to each of these things +[49:56] by index. You may see where I'm going +[49:58] here. It's not stable. +[50:01] Uh and this isn't an entirely small +[50:05] point. So if you if you want to actually +[50:08] reference one of these things and you're +[50:10] using indices at each of these levels, +[50:12] what are you going to end up with? Four +[50:14] indices and a base pointer to start +[50:15] with. +[50:17] It's both it's both starting to get to a +[50:20] reasonable amount of memory if you're +[50:21] holding a lot of these and also it's +[50:23] really inconvenient to write the code +[50:25] around. +[50:27] Okay, another option uh we could we +[50:31] could indirect +[50:33] we could have we could have a a meta +[50:35] block that points into individual chunks +[50:38] and then the individual chunks can +[50:40] remain stable and then we kind of +[50:42] reallocate this meta block structure. +[50:46] Um +[50:48] I think this would work. Uh there's no +[50:50] kind of +[50:52] inherent problem with this. you end up +[50:54] still doing the leaking although now the +[50:57] some fixed size some some constant size +[50:59] smaller than the the full problem. Um +[51:03] and then you you either leak this or you +[51:07] have some pool structure that ends up +[51:10] dealing all this and if you do that then +[51:12] you end up having to free things because +[51:13] they're not in the right place in the uh +[51:16] in the arena stack. I can go on about +[51:19] that but +[51:21] I don't know it's not great. There's +[51:23] also two jumps. So if we could avoid +[51:25] that, that would be nice. +[51:27] Um, common solution for +[51:32] variable length data where you want +[51:33] things to be static where you can grow +[51:35] them is this kind of chunked link list +[51:38] approach. Um, so you have an four items +[51:43] on this particular case have four items +[51:45] in each list list node have a pointer to +[51:48] the start and to the end. And this is +[51:51] great. We use this uh for strings things +[51:53] where you string lists where basically +[51:57] all of the the only thing you need to do +[51:59] with them is iterate through them from +[52:02] beginning to end. +[52:04] Um but in our particular case a +[52:07] constraint that I haven't mentioned yet +[52:09] is that we want random access and +[52:13] that is slow here. Uh now you may be +[52:16] thinking that we can just walk through +[52:21] and find it and it'll be fine. Computers +[52:23] are fast, memory is fast, whatever. +[52:25] Caching has improved so much. All of +[52:27] that fun stuff. Um maybe that would be +[52:30] okay with moderately sized data um that +[52:34] you do relatively infrequently. +[52:37] But uh I don't know if you've ever seen +[52:39] a profiler. Uh if you've ever seen a +[52:42] profiler trace, they end up being many +[52:43] gigabytes. And this is we do this all +[52:46] the time, so it's completely prohibitive +[52:48] for us. +[52:50] Another option could break things down +[52:52] in some sort of tree structure. Um, but +[52:55] we said we're trying to remove +[52:56] interaction here as well. So if we can +[52:58] avoid that, that would be really nice. +[53:00] There's also just like so many things +[53:02] happening all over the place for a +[53:05] structure that is that maybe end up +[53:06] being used quite a lot. We'd like to +[53:09] avoid that if possible. +[53:11] So So this is where I've ended up. um we +[53:15] take the the doubling size that we saw +[53:18] in the the real case and we took the um +[53:22] the metab block or chunk pointers +[53:24] approach of the the case after that um +[53:28] and rather than +[53:32] um rather than doubling in place this in +[53:36] this particular case we double the size +[53:37] of the array uh each each time we add a +[53:40] new chunk. +[53:42] Now, there's a nuance here. I said +[53:44] double the size of the array and not +[53:46] double the size of the previous chunk. +[53:49] Um I I think both can probably work. Uh +[53:53] but the maths well for one thing, you +[53:57] end up with a power of two size if you +[53:58] do it this way for the total total +[54:00] array. And that that's quite nice for +[54:02] various things. Uh and I think the maths +[54:04] work out maths works out nicely when you +[54:06] do it this way. Um so you'll see that +[54:08] the first two blocks are the same size. +[54:11] uh and then we double and then we double +[54:12] again. +[54:14] And you may also notice that the the +[54:17] pointers are just immediately next to +[54:19] the the the size of the array, the +[54:21] number of elements in the array. Uh and +[54:23] that is intentional um because +[54:29] we're on a 64-bit system. There's only +[54:32] 64 times that you can double the number, +[54:35] including the first one, and still be +[54:37] representable in address space, you +[54:39] know. So worst case, you end up with 64 +[54:41] pointers here. +[54:44] Okay, but what have we already said? Uh +[54:47] that we're not actually in a 64-bit +[54:50] address space. We could this that you +[54:52] can you can chunk that down to 48 or 52 +[54:55] or something around there. +[54:57] Okay. And then uh in in reality, you're +[55:01] on an actual physical system and you are +[55:04] very unlikely to have that many actual +[55:07] elements in RAM. +[55:09] Uh next step down. You have a real +[55:14] problem that you're trying to solve. And +[55:16] while in our first example +[55:19] uh we pooed the idea of having some +[55:22] known size of things that we can um that +[55:26] we can definitely fit all of our +[55:27] elements into. when you don't have to +[55:30] pay the actual full cost of that uh in +[55:33] term you only have to pay the log two of +[55:35] the cost of that uh that actually +[55:37] becomes a lot more feasible +[55:41] and then of course +[55:43] each individual element has a size. It's +[55:46] not just one bite typically. Um and then +[55:50] beyond that you shrink the number of +[55:53] pointers you need further by the fact +[55:55] that uh your initial chunk is not just +[55:58] one element but many +[56:01] um possibly you decided by cache size or +[56:04] page size or some other reasonable +[56:07] default for your problem. There's +[56:08] there's a little bit of nuance in how +[56:10] you decide that. Um, +[56:12] but but you end up with this. It's not a +[56:17] completely tiny header structure, but +[56:19] it's it's completely tractable. +[56:27] Right. So, +[56:30] this I I looked around for this. Um I +[56:34] couldn't see anyone talking about it +[56:36] although I'm sure that other people have +[56:37] done it. Uh given that I couldn't find a +[56:40] name I've come up with the name +[56:42] exponential array um or XAR for short. +[56:50] So we have this kind of array idea idea +[56:54] for storing a a virtual array and um but +[57:00] we we have to actually you know we have +[57:02] we need the code for this we need to +[57:04] implement it. It's no longer just a +[57:06] single lookup. There needs to be some +[57:08] kind of operations to find each element. +[57:10] And I guess this is this is where um I'm +[57:14] going to say that abstraction and +[57:17] generalization are not always a bad +[57:18] thing. They have a cost, but sometimes +[57:20] that cost is worthwhile. +[57:22] Uh and +[57:25] the way that we're going to generalize +[57:26] this is by treating bytes as first class +[57:29] citizens. +[57:31] Okay. So parameters that we're we're +[57:33] looking at are the size of each element. +[57:37] Uh the number of elements in the first +[57:38] chunk and from that you can infer the +[57:41] rest of them +[57:43] and the number of pointers that you're +[57:44] going to store to these chunks. And +[57:46] given that you can basically describe +[57:48] this entire structure. +[57:52] Okay, we're going to take advantage here +[57:54] of another thing that we know about the +[57:57] platforms that we're on. Um on +[58:02] um on in the typical Windows and Linux +[58:05] calling convention if you pass a 1 2 4 +[58:08] or 8 byt uh strct and it's there are +[58:11] more options for that on Linux uh if you +[58:14] pass a strct that is ex exactly eight +[58:17] bytes it will get passed as a register +[58:19] and so given that we know this it's +[58:22] actually not that difficult to compress +[58:25] all the information that we need to know +[58:27] into eight bytes +[58:29] um So maybe it sounds like a micro +[58:32] optimization. Um but again it's actually +[58:36] very the the mental overhead on doing +[58:38] this is pretty small once you're aware +[58:40] of it. +[58:44] The other point to do with calling +[58:46] conventions or APIs is +[58:49] you know we we want one version of an +[58:53] array function is to get to the element +[58:55] at index i. Uh and that's that's all +[58:58] well and good. Um, but there are other +[59:00] things you want to do with them. And as +[59:01] soon as you have multiple +[59:03] um multiple different parameters that +[59:06] you're passing, then being able to chunk +[59:08] all of that meta information into one uh +[59:11] one element is convenient both from a +[59:13] calling convention and from a developer +[59:16] perspective. Do you see that +[59:18] intersection happening? Yeah. Um +[59:22] so we +[59:24] um have this incredibly complicated +[59:28] header strct which just contains the +[59:31] size because we've we've said that our +[59:34] the number of chunks number of pointers +[59:36] that we store um may want to differ in +[59:38] different cases. Uh and then um given +[59:41] this +[59:43] we can uh we know that our chunk is +[59:47] going to be immediately following this +[59:48] and we know that they're going to align +[59:49] because of the size of this thing. Um +[59:52] given this we can find the which chunk +[59:56] uh an element is in and then where +[59:58] inside that chunk it is. +[1:00:01] Um I'm very happy to talk people through +[1:00:04] what this is all doing. um we don't +[1:00:07] really it's I don't think we have time +[1:00:08] to do it currently but you can observe +[1:00:11] that all of the operations are just +[1:00:14] shifts and addition and subtraction it's +[1:00:18] all stuff that the computer can do very +[1:00:21] very handily uh and +[1:00:25] I think this is mostly possible because +[1:00:26] of the the +[1:00:29] um the structure that we ended up with +[1:00:30] here with everything being a power of +[1:00:32] two now you could have gone maybe I want +[1:00:35] Fibonacci structure. +[1:00:38] Um and maybe you could have but if you +[1:00:42] do that then +[1:00:45] um finding the doing this inverse of the +[1:00:49] you know maybe going from +[1:00:52] um doing doing the multiplication out +[1:00:53] isn't too bad but then going in the +[1:00:55] opposite opposite direction becomes a +[1:00:56] lot more prohibitive. Whereas we have +[1:00:58] our best friend most significant bit and +[1:01:01] that does it. +[1:01:10] that does our log base 2 +[1:01:13] uh in um with about the latency of an +[1:01:16] integer multiplication and depending on +[1:01:18] the platform it's sometimes more like an +[1:01:20] addition. So it's between very good and +[1:01:22] the best it can possibly be. +[1:01:26] Okay, let's let's look at getting a real +[1:01:29] type that we can find. And we've +[1:01:32] introduced this with um wanting to find +[1:01:34] a um a particular call in this tree of +[1:01:38] calls. But we'll just look at the the +[1:01:40] last array in that. +[1:01:43] Okay. So I'll point out that this is not +[1:01:46] actually how I do it in my codebase +[1:01:48] because uh we have some some macro +[1:01:51] hackery to get around having to +[1:01:53] implement this everywhere or to rewrite +[1:01:55] this everywhere. Uh I don't didn't want +[1:01:57] this talk to be too Csp specific and so +[1:02:00] I'm not going to go into that but feel +[1:02:01] free to ask me about it later. +[1:02:03] Um so anyway we can specify the metadata +[1:02:07] and then call so we have our outer +[1:02:10] function is it's fully typed uh and then +[1:02:13] our inner function um it calls the +[1:02:16] generic byte-wise oper operator and +[1:02:19] returns a pointer to the thing it found. +[1:02:22] Uh if this were an external function um +[1:02:26] like I said the +[1:02:28] uh an eight byt strct will just get +[1:02:30] pushed into a register or moved into a +[1:02:32] register and then passed as one of the +[1:02:34] parameters like that. Uh and you can +[1:02:36] actually see um here we have a shift of +[1:02:40] eight. Um we have 30 chunks and we have +[1:02:45] a you can't see here but it's a 24 byt +[1:02:47] element. Uh and so at the very right we +[1:02:51] have eight uh and then 30 and then at +[1:02:54] the very end this 0x18 that's 24 in hex. +[1:02:59] Um, okay. This is this is an external +[1:03:01] call and in reality um particularly if +[1:03:05] you're a Unity G Unity build team then +[1:03:09] um you're actually going to call you're +[1:03:13] going to get your code +[1:03:15] your compiler and your linker are going +[1:03:17] to know uh what the function is going to +[1:03:19] call and it's going to inline them and +[1:03:21] it's going to be hack times where you +[1:03:23] don't have to do this extra call +[1:03:24] overhead +[1:03:25] before we get there. I mean we just have +[1:03:29] an awareness. We're not going to go +[1:03:30] through this in detail of the the +[1:03:33] machine code that gets generated. +[1:03:36] And um +[1:03:39] hopefully you're all familiar with +[1:03:40] Godbolt at this point. You whenever you +[1:03:42] have a a query about what things get +[1:03:44] turned into, Godbolt is a a lovely go-to +[1:03:47] for quickly checking what things are +[1:03:48] going to look like. Um but this is a a +[1:03:51] general case. There's nothing +[1:03:53] particularly objectionable in there. +[1:03:54] There's like there's a jump. Maybe we +[1:03:56] could have made this branchless. Um +[1:03:58] there's an IMOLE which is not quite as +[1:04:00] fast as some of the other bitwise +[1:04:02] arithmetic but I mean like this is +[1:04:05] pretty much this is this is really very +[1:04:08] good for uh generic code u for kind of +[1:04:12] generic operations dynamic dynamically +[1:04:14] typed operation. Um and then at the end +[1:04:18] we +[1:04:20] um +[1:04:22] we we find out what the pointer ends up +[1:04:24] being to our thing. And so the +[1:04:28] the gold standard here, which would be +[1:04:30] finding the address of an element in an +[1:04:32] array, uh would basically just be a +[1:04:35] single LEA maybe with a a couple of mobs +[1:04:37] before it. Um and while we're not quite +[1:04:40] there, like if you've seen the size of +[1:04:42] some of the disassembly and in many +[1:04:44] other functions, we're not too far off. +[1:04:48] Okay, so if we specialize to a the +[1:04:50] specific types that we're interested in, +[1:04:52] it's actually all very similar. um +[1:04:55] except the there's some early outs at +[1:04:57] the top and um a little trick to compute +[1:05:01] uh 24 times for the size slightly faster +[1:05:04] than a generic multiply. +[1:05:06] Um okay, so so two things jump out at me +[1:05:09] here. One is um this got inlined the +[1:05:13] inner type didn't end up being the fact +[1:05:15] that we did this dynamically initially +[1:05:16] didn't really matter for the resulting +[1:05:18] machine code. Um, and the other thing +[1:05:21] that jumps out is that the dynamic +[1:05:24] version is actually not that bad. Uh, +[1:05:26] and so given that we're a debugger and +[1:05:30] we do many things dynamically, um, it's +[1:05:34] actually occasionally useful to use the +[1:05:36] dynamic version. And the fact that we've +[1:05:37] done it this way rather than through +[1:05:39] templates or something means that we +[1:05:41] have this option to basically have this +[1:05:44] monomorphization on the right or the uh +[1:05:48] or a runtime version on dynamically +[1:05:51] typed version on the left. +[1:05:54] Uh and thinking of this is basically +[1:05:57] bite first thinking wins over type first +[1:05:59] thinking. +[1:06:03] Okay. So why do we need this random +[1:06:08] access? Um +[1:06:10] well, one of the things we need to be +[1:06:12] able to do is +[1:06:16] um bind elements in our calls. And here +[1:06:20] we get to make another awesome +[1:06:22] assumption. +[1:06:23] Uh one of the great things that happens +[1:06:25] when things happen across time +[1:06:28] is they're sorted by time. +[1:06:31] And that is incredibly useful because it +[1:06:33] means that we can binary search them. +[1:06:37] And there's many reasons you need to do +[1:06:38] this uh in profilers in general and in +[1:06:41] white box in particular. Um but let's +[1:06:45] just say we need binary search +[1:06:48] and we can take advantage of this bite +[1:06:50] first thinking. Um so first of all the +[1:06:54] the default if you were treating this in +[1:06:57] a type first way it would be okay. We we +[1:06:59] have our call um let's just say we have +[1:07:02] a simple array rather than this slightly +[1:07:03] more complicated z we have an we have +[1:07:06] our array of calls and oh we need +[1:07:09] because we're in C we need this we need +[1:07:12] this separate uh we need a separate +[1:07:14] function for each type of strct that we +[1:07:17] are going over we need one for calls and +[1:07:19] we need one for stack levels and we need +[1:07:21] one for all these other things that +[1:07:22] we've we've mentioned we have arrays of +[1:07:24] and that is that's that gets unwieldy +[1:07:27] um But like if you're doing a search +[1:07:32] over things, are you actually comparing +[1:07:34] the whole strct? Uh I would say in +[1:07:38] almost all cases, no. You're you're just +[1:07:40] comparing some in 99% of cases you're +[1:07:44] comparing some simple member of that +[1:07:47] strct. +[1:07:49] There's the occasional one where you +[1:07:50] need to compute uh compute something +[1:07:52] given multiple members, but the typical +[1:07:55] case is this. +[1:07:57] And so if you're happy to you have this +[1:08:00] this strct that you're looking through +[1:08:01] and you can identify a search key, you +[1:08:03] really only need one version of this +[1:08:06] function per search key type, not outer +[1:08:08] key type. +[1:08:12] Once you've gone through this and worked +[1:08:14] it out, uh it's it's not much more +[1:08:16] complicated to do it for the for the ZAR +[1:08:18] version. Um and this is the the code for +[1:08:22] that. I'm not going to claim it's the +[1:08:23] best binary search. In fact, I know it's +[1:08:24] not because there are better branch +[1:08:26] versions. But uh I'll just point out two +[1:08:28] things. One, uh we're getting the Z meta +[1:08:32] and you can actually see here the case +[1:08:33] that I was referencing earlier where you +[1:08:36] end up with multiple different um +[1:08:39] parameters and it's quite nice having +[1:08:41] your Z meta constrained to one thing +[1:08:42] rather than is split out into all of its +[1:08:44] members. +[1:08:46] Um +[1:08:47] and the other is you just end up doing +[1:08:51] the typed get +[1:08:54] uh and then get the offset into that +[1:08:56] strct and then you know the thing that +[1:08:59] you test against and you test we're +[1:09:01] doing a slightly +[1:09:03] this is a binary search where uh rather +[1:09:06] than just finding an exact element you +[1:09:08] find the thing that is less than or +[1:09:11] equal to that element. So it's slightly +[1:09:13] unusual. +[1:09:17] And here is where you may have seen a +[1:09:20] hole in the z before. Here's where we +[1:09:22] get to fill that in. Um, and if you're +[1:09:25] thinking that this is a very pure a very +[1:09:28] pure structure, maybe you're making a +[1:09:30] library for this, then um I don't know +[1:09:33] this this is a member that may not make +[1:09:35] sense. But this is for our codebase. +[1:09:38] This is for a spec specific purpose that +[1:09:41] we know. Uh, and so we can put in the +[1:09:44] things that are helpful even if they're +[1:09:45] not pure. Uh and so +[1:09:48] we have all of these parameters current +[1:09:50] uh as as an option. There's like the +[1:09:53] most explicit layer possible. Uh but +[1:09:55] most of the time we don't need all of +[1:09:57] that. That's more complicated than we +[1:09:58] need and we just binary search an array +[1:10:01] kind of as expected. +[1:10:04] General point here is I often find it +[1:10:07] helpful to have um the explicit function +[1:10:10] with everything specified and then all +[1:10:13] helper functions call that with +[1:10:16] different things. So you have you have +[1:10:17] this extra one layer. You don't end up +[1:10:20] then doing like +[1:10:23] this this tree of specializations adding +[1:10:26] one more specialization each for each +[1:10:28] call in that call stack. Uh so side +[1:10:31] point though, +[1:10:34] okay, we're gonna +[1:10:39] jump slightly to a different topic or a +[1:10:42] different aspect of this topic. Uh and +[1:10:45] that is mappings. Back to mappings. +[1:10:50] Now, +[1:10:51] I wanted to include in this talk a kind +[1:10:54] of full section on using um the +[1:10:58] locations of things as a source of +[1:11:00] information. Uh but it turned out +[1:11:03] there's uh far too much to say there +[1:11:05] that um and it would completely blow out +[1:11:08] the rest of this talk and it's it's far +[1:11:11] too long as it is. So, we've got some +[1:11:14] mappings. Um, and what what you're +[1:11:17] probably familiar with is doing you're +[1:11:19] probably familiar with doing parallel +[1:11:20] arrays in the context of um, SOA style +[1:11:24] structures where you know thing at index +[1:11:28] zero in one array maps to thing at index +[1:11:31] zero in some other array and they're +[1:11:33] kind of conceptually part of the same +[1:11:34] thing but stored separately. And the +[1:11:37] wins you get from this are u maybe it's +[1:11:40] cache in that they're um or the access +[1:11:44] pattern means that you're accessing all +[1:11:46] of one array and not the other one. +[1:11:47] Maybe it's a size thing where um one of +[1:11:50] them only has to be bit flags and the +[1:11:52] other one is some large str member and +[1:11:54] the bit flag would throw off the +[1:11:56] alignment so you end up with a bunch of +[1:11:57] wasted space. Um maybe it's just you +[1:12:00] know uh you get this mapping +[1:12:04] and you don't have to record any data. +[1:12:07] You just it's it exists in the ether for +[1:12:10] free. And well you you're just getting +[1:12:13] this from the fact that you have this +[1:12:14] structure. +[1:12:16] And then another case um that is +[1:12:20] particularly helpful is +[1:12:23] you have two different arrays that live +[1:12:27] on different lifetimes +[1:12:29] and they get to know about each other. +[1:12:33] Um but you never have to keep an +[1:12:34] explicit pointer or handle a reference +[1:12:36] or anything from one to the other or +[1:12:38] generic map whatever. Uh, and what that +[1:12:41] means is that the thing that you're +[1:12:43] pointing to, if that disappears, you +[1:12:46] don't have to go and fix up any +[1:12:47] pointers. You don't have to say, "Oh, +[1:12:48] wait, no, this is no longer this no +[1:12:50] longer exists. I need to make sure that +[1:12:52] I've uh I've handled that case." It just +[1:12:55] poof, it's gone. +[1:12:58] And this shows up for us in the call +[1:13:01] stack case. Now I mentioned near the +[1:13:02] beginning that we have this kind of +[1:13:04] event cache um where we look up +[1:13:07] information at the um when we have a +[1:13:10] debug event. Uh and we one of the things +[1:13:15] that we store is like an unwound call +[1:13:17] stack. +[1:13:23] And you've also seen from the timeline +[1:13:25] view that we have this kind of profiler +[1:13:28] like view of calls across time. +[1:13:32] And +[1:13:34] what's quite nice here is we have some +[1:13:36] parallel mapping, but there's a nuance. +[1:13:39] Um, +[1:13:43] call stacks when you unwind them, you +[1:13:45] start at the current um the current +[1:13:47] instruction pointer, the current level +[1:13:50] of the call stack, and then you do a +[1:13:52] little bit of jiggory pokery and you +[1:13:53] find the pointer back to the previous +[1:13:55] level of the call stack, and you end up +[1:13:57] with a kind of gnarly linked list. um +[1:14:01] going from the leaf to the root. +[1:14:03] And then in our profiler leg view, we +[1:14:06] want to store that with the root at the +[1:14:10] bottom because it means that as the as +[1:14:12] the size of the call type changes, it +[1:14:15] stays in the same place. +[1:14:18] Uh so this means that we're we're +[1:14:20] counting in opposite directions. And +[1:14:24] what what this basically means is that +[1:14:26] we have kind of this this inverse +[1:14:28] parallel case which is it's a slight +[1:14:30] extension to the parallel case and it's +[1:14:33] you know big deal I guess. Um but +[1:14:37] there's a there's something else that +[1:14:38] comes out of this which is +[1:14:41] we're thinking about our um profiler +[1:14:44] call levels. Uh I I keep saying +[1:14:47] profiler. you're getting data across +[1:14:48] this as well as calls, but uh I'm sure +[1:14:51] profile is more familiar. +[1:14:55] Um when we're accessing data at these +[1:14:58] different levels, sometimes you're going +[1:14:59] to be okay at at level two, +[1:15:04] we have some data +[1:15:07] and +[1:15:09] maybe um I pass a pointer to that data +[1:15:11] into these lower functions. Maybe they +[1:15:13] modify that data. I want to keep looking +[1:15:15] at that data referenced in in corite +[1:15:18] level two uh and see how it changes +[1:15:20] across time. What you also might want to +[1:15:22] do is say whatever's at the top of the +[1:15:25] stack what is currently happening there. +[1:15:27] And so we need to be able to reference +[1:15:29] uh from both these sides. +[1:15:32] Okay, cool. This this seems like a uh a +[1:15:37] solved issue. You know, you've used +[1:15:39] Python. You've seen many things that do +[1:15:41] this. Um, +[1:15:44] if you're kind of indexing into an +[1:15:46] array, you can use zero to or positive +[1:15:48] numbers to access from from the left or +[1:15:50] negative numbers to access from the +[1:15:52] right and you get this zero one zero and +[1:15:55] minus one kind of the opposite sides and +[1:15:57] then one minus two opposite sides and so +[1:15:59] on. Um, and that's kind of the in the +[1:16:04] general case you're doing this minus x + +[1:16:06] one with the brackets in the right place +[1:16:08] to to convert from level to depth. +[1:16:13] I don't know if anyone can see where +[1:16:14] this is going. +[1:16:18] Welcome to bits of high level part +[1:16:20] three. +[1:16:26] If you're happy to happy to assume that +[1:16:28] you live on a two's complement machine, +[1:16:30] which +[1:16:32] well I know I do. Um +[1:16:35] you can you can make that choice for +[1:16:36] yourself. uh then you you know that this +[1:16:40] minus x + one is the same as a not x. +[1:16:43] Now okay is is this swap going to make +[1:16:47] the difference between a completely +[1:16:49] amazing feature and +[1:16:52] uh something that doesn't work at all? +[1:16:54] Probably not. But you will notice +[1:16:58] uh there's there's many of these things +[1:17:01] there's many operations happening on the +[1:17:02] left. And you know you might do minus x +[1:17:05] plus one and you're like ah I forgot the +[1:17:06] parenthesis. H sorts of bugs. Is it x +[1:17:09] minus one? H what was it? What was it +[1:17:11] again? Um you got to take this extra +[1:17:13] thinking step to make sure you've got +[1:17:15] that right. And it's another place that +[1:17:18] you might get things wrong. Uh and if +[1:17:20] you know that you can do this this not +[1:17:22] operation and do this flip, then that's +[1:17:25] makes things so nice. +[1:17:28] It's small. It's a it's a creature +[1:17:30] comfort. let's say +[1:17:33] um if you're thinking of negation +[1:17:36] uh if you look at it on a on a number +[1:17:37] line we're kind of flipping around the +[1:17:40] middle of zero so negative 0 maps back +[1:17:42] to zero um the negative of the minimum +[1:17:45] number I think is technically undefined +[1:17:47] but in practice often maps back to +[1:17:49] itself uh and then everything else you +[1:17:52] know does it what you expect one goes to +[1:17:54] minus one and so on and then it's worth +[1:17:56] seeing that the the not version of this +[1:17:58] it effectively mirrors around uh you can +[1:18:02] you can think of this either as minus0.5 +[1:18:05] or the left edge of zero depending on +[1:18:08] what makes more sense to you in the +[1:18:11] integer case the the second feel +[1:18:13] somewhat more appropriate. Um +[1:18:16] uh and that means that we can do level +[1:18:19] equals not depth and depth equals not +[1:18:20] level. Uh and everyone's happy and you +[1:18:25] know ah squiggly, +[1:18:32] right? +[1:18:34] Uh let's +[1:18:37] have a have a roundup of where we've got +[1:18:38] to with this call situation. You may +[1:18:41] remember the tree that had run which had +[1:18:45] members of run thread which have levels +[1:18:47] in a call stack uh which have a number +[1:18:49] of calls and then each individual call. +[1:18:53] Uh and this is the a potential layout of +[1:18:56] that within a single arena uh with these +[1:18:59] zars. Um so our red run thread at the +[1:19:04] left points sorry our red run at the +[1:19:06] left points to these blue run threads. +[1:19:10] Um +[1:19:12] the run thread, you can see that these +[1:19:16] uh the run threads are pointing to these +[1:19:18] green call stack levels. And you can see +[1:19:20] we've got three of them. The first two +[1:19:22] are the same size and the uh third one +[1:19:24] is double the size. Um and then +[1:19:28] the +[1:19:30] uh the the stack levels, +[1:19:33] what did I get to? It calls the next one +[1:19:36] down. Um sorry, not calls. it references +[1:19:39] the next level down the with the chunks. +[1:19:42] Um, and then once we're done with this, +[1:19:45] so you can see that we've interled +[1:19:47] pushing onto these different um +[1:19:49] different arrays. And the if it's not +[1:19:51] obvious, the the hashed bits are just +[1:19:53] memory we don't care about. Something +[1:19:55] else is there for for this purpose. +[1:19:57] Um, but yeah, we've we've interled all +[1:20:00] these things. We've done all our stuff. +[1:20:02] We've shown everything to the user. The +[1:20:04] user's so grateful to us for showing us +[1:20:06] all this information. They fixed their +[1:20:07] bugs and yes. +[1:20:10] Um, but now it's time for another run. +[1:20:13] Let's go. +[1:20:16] Clear. +[1:20:18] Just pop back. +[1:20:20] You can zero the um the one array left +[1:20:25] of pointers. And so zeroing it means you +[1:20:28] have um no members and then all of your +[1:20:30] pointers are null and doesn't point to +[1:20:33] anything. And we're reset. And it's one +[1:20:36] operation. You don't have to walk all +[1:20:37] the way up the stack. You don't have to +[1:20:39] keep all of these arrays around in some +[1:20:42] real tree. +[1:20:44] There we go. +[1:20:50] Part three, pipelining dependencies. Um, +[1:20:54] we're going to take a jump back to the +[1:20:56] debugger world here in a sec, but we're +[1:20:58] going to start with a a simple example. +[1:21:03] So, we're building up some case. +[1:21:05] something has happened. Uh we want to +[1:21:07] switch and we we have our case ename a +[1:21:12] we do the thing that happens with that +[1:21:14] and we do some other other code and we +[1:21:16] have another case and we get some stuff +[1:21:18] that's specific to that and then we also +[1:21:21] get some stuff that's the same as the +[1:21:22] the first one. Uh and then we get a +[1:21:24] third case and we we've copied it again +[1:21:26] but we're starting to think this this is +[1:21:29] going to be a little bit hard to +[1:21:30] maintain. Maybe we need to do something +[1:21:32] with this. And then we get a fourth +[1:21:35] case. We're like, yeah, we we probably +[1:21:36] should do something about this. These +[1:21:38] are meaningfully the same. And +[1:21:42] this this is going to be a nightmare. +[1:21:43] Like assume this is not just two lines +[1:21:45] of code, but some considerable amount. +[1:21:49] So +[1:21:51] default response I'd say is pull this +[1:21:55] out into a function. +[1:21:58] And you know it it kind of works. uh +[1:22:02] there's nothing completely nothing wrong +[1:22:04] with that and in many ca in many cases +[1:22:06] that is uh probably the best approach +[1:22:09] but you will often find that a better +[1:22:12] approach is in my particular view uh is +[1:22:16] to do this pipelining thing where you do +[1:22:19] each individual case uh and then you +[1:22:22] move the the common code down so that +[1:22:24] all of them end up going through that +[1:22:26] that code path. +[1:22:28] uh and there's this extra step for setup +[1:22:30] common because there's often something +[1:22:31] that has to be done before that. +[1:22:35] So this is the case with calls. We end +[1:22:38] up with these kind of multiple different +[1:22:40] paths. Uh kind of ends up as a tree. And +[1:22:45] here we have everyone's favorite data +[1:22:47] structure, the DAG. Yes. Yeah. +[1:22:52] Okay. You you might be thinking like +[1:22:54] this is this is an unfair example. +[1:22:56] You've explicitly said that all of these +[1:22:58] things are completely the same and +[1:22:59] there's one of them and they're they're +[1:23:01] all matching. Okay, fair point. Fair +[1:23:03] point. Let's do a slightly more hard +[1:23:06] example. +[1:23:08] So +[1:23:10] now we have five different things that +[1:23:12] might get done as a result of our four +[1:23:14] different enums. Uh and then each of our +[1:23:17] enums does a different but overlapping +[1:23:20] subset of those things. +[1:23:22] Okay. So again kind of first version of +[1:23:26] this pulling out in the in the default +[1:23:28] way to functions. Um +[1:23:32] you can do this but now each of your +[1:23:35] call sites has some different context +[1:23:37] from within that enum specific case. And +[1:23:41] also you now have a function in your +[1:23:43] codebase that might get called from +[1:23:46] somewhere else. And +[1:23:50] you know either you take the approach +[1:23:55] this might get called from somewhere +[1:23:56] else and you handle that in which case +[1:23:59] you have to do all of this work to make +[1:24:01] sure that you're not assuming too much +[1:24:02] context or you don't do that and then +[1:24:06] you later come back to this you're like +[1:24:07] oh that looks like it does the thing I +[1:24:08] want it to do and you use it and you +[1:24:10] forget about all of the assumptions that +[1:24:12] you made as part of making it. uh and +[1:24:14] then you have a bad time debugging +[1:24:16] because there's some subtle case that +[1:24:18] you've forgotten about. So the the +[1:24:22] alternative that I would propose in not +[1:24:25] all but but some cases uh is to do this +[1:24:28] pipelining approach. +[1:24:32] Okay. So in in the kind of abstract we +[1:24:36] have each individual case uh and then we +[1:24:39] work out what we want to do and then we +[1:24:42] do the things that we want to do +[1:24:45] that kind of ends up in in this +[1:24:47] situation. Um except there's a you know +[1:24:51] there's often a wrinkle between with +[1:24:53] with this which is that these have inner +[1:24:56] dependencies between them and in this +[1:24:59] case that's trivial. You've just you can +[1:25:02] just order these if statements in the +[1:25:04] right way. +[1:25:07] Trivial is maybe an overstatement there. +[1:25:10] Sometimes there are complexities there, +[1:25:12] but in many cases once you've worked out +[1:25:15] what the different jobs to be done are, +[1:25:17] ordering them is straightforward. +[1:25:20] Okay, let's have a look a look at a +[1:25:22] couple of ways that we could do this. +[1:25:24] Um, one is I I kind of think of as um a +[1:25:29] bit like a it's you're framing what +[1:25:32] needs doing in terms of the input in +[1:25:35] terms of the problem statement. Um, and +[1:25:38] so using our best friend bits. Yes. Can +[1:25:41] we get another round of applause? +[1:25:47] We can use our linearly incrementing +[1:25:50] enum and turn that into a flag. +[1:25:54] um and then compare that flag with uh +[1:25:56] different combinations of other flags. +[1:25:58] Uh and again, we're doing a few +[1:26:00] operations here, but again, this is +[1:26:01] these are constant things that will get +[1:26:03] uh turned into a single value at compile +[1:26:06] time. Um and if you +[1:26:10] um blur your eyes a little bit, this is +[1:26:12] quite similar to what we were doing with +[1:26:14] our types case, except those were +[1:26:16] already kind of pre-shifted +[1:26:19] um where we were checking against +[1:26:20] pointer and reference and array, that +[1:26:21] kind of thing all at once. +[1:26:23] Um, an alternative is +[1:26:27] we frame the problem in terms of what we +[1:26:29] want to do as a as a result kind of the +[1:26:32] output of this um of this event this +[1:26:36] thing that's happened and um again using +[1:26:41] bits but just slightly differently we +[1:26:43] are just specifying I want to do job job +[1:26:46] one job two job three whatever uh and +[1:26:48] then we do them and you know each of +[1:26:50] these operations bitwise s trivial. Um, +[1:26:54] computer's not going to complain about +[1:26:55] them once you're familiar with them. +[1:26:57] Incredibly concrete, kind of easy to +[1:27:00] understand what's going on. +[1:27:03] Okay, let's let's go one step harder. +[1:27:06] Um, +[1:27:08] it's possible that it's the enum is not +[1:27:11] the only thing that determines what +[1:27:12] needs to be done. Uh, and in that case, +[1:27:15] uh, you, you know, have this if +[1:27:16] statement at the top. Uh, and if that is +[1:27:19] true, then you kind of need to be in +[1:27:22] this um output oriented thing as far as +[1:27:25] I'm aware, unless you start making your +[1:27:27] conditions really complex. Uh, but +[1:27:29] you're probably already doing that +[1:27:32] analysis earlier on when you're trying +[1:27:34] to understand the problem input. Uh, and +[1:27:37] it often ends up being easier to specify +[1:27:38] in this way. Uh, and then another thing +[1:27:41] that might happen is that while doing +[1:27:44] your jobs, you realize that something +[1:27:45] else needs doing afterwards. +[1:27:48] And +[1:27:50] uh I've written this in a slightly +[1:27:51] different way here. Um this is kind of +[1:27:53] doing a branch free branch free version +[1:27:57] of the if statement above. Uh where +[1:28:00] you're converting some condition to zero +[1:28:02] or one and then multiplying it by a +[1:28:04] flag. So that is either zero or the flag +[1:28:07] uh and then you're um oring it which is +[1:28:10] like item potently set including uh into +[1:28:14] your flags. +[1:28:16] Um now +[1:28:21] my gen I tend to tend to have the +[1:28:25] opinion that +[1:28:27] um +[1:28:29] you can go you can definitely go too far +[1:28:31] with branch free code if readability is +[1:28:33] your goal. Um but a little bit of branch +[1:28:36] free code will actually end up being +[1:28:38] easier easier to read once you're used +[1:28:40] to it. Uh because it means you're doing +[1:28:42] this thing than this thing than this +[1:28:43] thing than this thing. There's no +[1:28:44] there's no indirection. and there's no +[1:28:46] kind of extra layer of looking out into +[1:28:48] different different places and trying to +[1:28:49] keep that stack of like what's happened. +[1:28:52] Um, +[1:28:55] your mileage may vary. +[1:28:58] Okay, we can we can expand this a little +[1:29:00] bit more. Sometimes uh just do the thing +[1:29:03] is not enough information. Sometimes you +[1:29:04] need to know like what am I doing with +[1:29:06] this thing? There's some parameter +[1:29:08] effectively that needs to be passed to +[1:29:09] the operation. And so we just add some +[1:29:12] data that's available for that. +[1:29:16] um you you might get to the point where +[1:29:17] you package these together into a strct. +[1:29:20] Uh you might end up that do the thing or +[1:29:23] not do the thing is not quite the right +[1:29:25] framing. A better framing is don't do +[1:29:27] anything or do version one or do version +[1:29:30] two uh or three or four or five. And if +[1:29:35] you have just three options then kind of +[1:29:38] uh from a bit perspective the +[1:29:43] the the flags version two bits and the +[1:29:48] um sorry the flags version which is two +[1:29:51] bits and the kind of enum small enum +[1:29:54] version which is two bits for three +[1:29:56] values uh are the same. Uh +[1:30:00] but from a kind of mental modeling +[1:30:04] perspective, it may make sense to to +[1:30:06] break it down this way anyway. Um or you +[1:30:09] may find that the you know keeping with +[1:30:12] just bits and having a very simple uh a +[1:30:15] simple protocol there is is the e easier +[1:30:18] thing to understand. Once you get kind +[1:30:20] of to higher numbers, um +[1:30:25] the number of values that you can +[1:30:27] represent with a few bits compared to +[1:30:29] the number of uh individual bit flags +[1:30:32] you can represent with the new bits +[1:30:34] grows astronomically. And so uh you can +[1:30:37] you can fit more kinds if they are +[1:30:40] mutually exclusive into a single value. +[1:30:43] Uh and that and that's kind of the big +[1:30:44] one of the big distinctions between kind +[1:30:47] of using um separate dimensions versus +[1:30:52] growing a dimension uh comes down to +[1:30:55] which is kind of are can these things +[1:30:57] happen at the same time or uh can only +[1:31:00] one of these things be true at once. And +[1:31:01] so in this case our job can only be +[1:31:04] beginning or ending or it can be +[1:31:06] neither. +[1:31:09] And so this is modulo some detail pretty +[1:31:12] much what we're doing with debug events. +[1:31:15] Um this is roughly you know again +[1:31:19] skimming some stuff what we get from um +[1:31:22] from the Windows operating system. Uh we +[1:31:24] get uh process has been created a thread +[1:31:26] has been created uh module has been +[1:31:28] loaded. Um and you'll you'll notice that +[1:31:33] uh in create process event at the top we +[1:31:35] have this this thread begins and we have +[1:31:37] some data for the thread. what handle it +[1:31:39] is. And then al the same thing happens +[1:31:41] in create thread. Uh and then the same +[1:31:43] thing that happens in sorry a module +[1:31:47] begins in load DL and a module begins in +[1:31:50] create process debug event. Um as Ryan +[1:31:54] mentioned uh a module you can kind of +[1:31:57] think of as a term that encompasses both +[1:32:00] loaded exes and loaded DLS. +[1:32:04] Uh and then we have the other side of +[1:32:05] this thing which is uh handling our +[1:32:07] debug event. And um we get to handle the +[1:32:12] um +[1:32:14] uh the the thread beginning from the +[1:32:17] create process event and the thread +[1:32:18] beginning from the debug event in one +[1:32:21] place. And I mean just it's one place in +[1:32:24] the code. And that's not just like one +[1:32:26] function where it gets run although that +[1:32:28] is true. It is also one call stack in +[1:32:30] the there is no call stack where this +[1:32:32] gets hit other than the one where it +[1:32:34] gets hit. So you know exactly what is +[1:32:37] happening. You know exactly the context +[1:32:39] when this is run. +[1:32:42] Um again you know we're handling modules +[1:32:46] getting loaded and unloaded. Uh and then +[1:32:48] sometimes you know things happen. Um +[1:32:50] maybe some exception got hit and we need +[1:32:52] to break the user's process. Uh that's +[1:32:54] kind of a a job flag that we we have. +[1:33:00] Okay. So we've +[1:33:03] I think a thing to notice here is that +[1:33:06] the left stuff is framed in the context +[1:33:10] of the problem. And so in this case it's +[1:33:14] platform dependent uh and it's using the +[1:33:19] granularity of states that Windows +[1:33:22] specifies. +[1:33:23] um and also the the way that they've +[1:33:26] split it out and then we get to +[1:33:28] reinterpret that into a way that is +[1:33:30] convenient for us and handle that in our +[1:33:33] own code and we can make it platform +[1:33:35] independent and I I find that there's +[1:33:37] quite often this split of like the +[1:33:40] framing that makes sense from the input +[1:33:41] and the framing that makes sense from +[1:33:42] the output and they're they're not +[1:33:44] always the same thing. um you you get +[1:33:45] this kind of in uh slightly semantically +[1:33:49] compressed +[1:33:51] um +[1:33:53] uh data formats where they represent the +[1:33:55] same information in multiple ways +[1:33:56] depending on you know the size of the +[1:33:58] integer although that that and then that +[1:34:00] doesn't actually change the way that you +[1:34:02] handle that integer after the fact. +[1:34:06] Anyh who, +[1:34:09] we've got this way of +[1:34:14] dealing with +[1:34:16] dependencies. +[1:34:17] We can we can pipeline these things into +[1:34:19] kind of we work out what the jobs to be +[1:34:21] done and then we do the jobs. Great. Um +[1:34:25] if you look for it depend the the issue +[1:34:28] of dependencies appears everywhere. +[1:34:31] It's a really really useful lens to +[1:34:33] have. If if you've been following +[1:34:34] computer enhance Casey, then you'll know +[1:34:37] about the issues with dependencies at +[1:34:40] the machine code instruction level. Um +[1:34:42] you can think of them in this level. You +[1:34:44] can think of them as like build system +[1:34:46] dependencies. Um and then you can you +[1:34:49] have have this completely generic +[1:34:52] version, the most generalized version +[1:34:54] possible that you can think of. And then +[1:34:56] we have all of these specializations +[1:34:58] that we can apply to our actual problems +[1:35:00] that assume the things that we know +[1:35:01] about the problem space. Um so in our +[1:35:05] case we only ever do the thing once or +[1:35:07] we don't do it. You you often end up in +[1:35:10] a situation where there's a you might +[1:35:12] want to do a thing multiple times and +[1:35:14] that's often where cues can get +[1:35:16] involved. Um you can have a a DAG that +[1:35:20] is statically defined and then adds this +[1:35:23] element of um caching or um we we keep +[1:35:29] some data around from from previous +[1:35:31] times. So that we not only does this +[1:35:36] thing +[1:35:37] uh do we depend on the state from like +[1:35:40] just earlier in the function, we depend +[1:35:42] on previous loops of this this whole +[1:35:44] iteration. Uh and then you can get all +[1:35:47] the way to the most generic possible uh +[1:35:49] DAG. Uh but you know who would do that? +[1:35:53] Uh +[1:35:54] okay, admittedly so this is from this is +[1:35:57] from uh this is whitebox. +[1:36:00] This is the the legit ver world of white +[1:36:03] box where +[1:36:06] um you know we basically are operating a +[1:36:10] build system and +[1:36:13] you can see that this is not the +[1:36:15] simplest of dependency graphs. You can +[1:36:18] get more complicated of course um but +[1:36:21] this particular dependency chain was not +[1:36:24] completely obvious a priority. we we had +[1:36:27] to work this out as we went. And so +[1:36:29] having this as a more general data +[1:36:31] structure helped us to both pipe it into +[1:36:34] dots so we could actually see what the +[1:36:36] data data structure was um and then also +[1:36:40] um we could attach state to each of +[1:36:41] these nodes and add some more extra +[1:36:43] debug information which is helpful. +[1:36:46] Thinking back on it I think we probably +[1:36:47] could have gone kind of half a step +[1:36:50] um more specialized more concrete. Um +[1:36:56] I think that the actual operations could +[1:36:58] have been uh done in this +[1:37:03] you know inline way where you just work +[1:37:05] out what what it's doing and your linear +[1:37:07] linearization is kind of statically +[1:37:09] baked in uh and then you add on top of +[1:37:11] this um +[1:37:14] uh a kind of immediate mode API for +[1:37:17] adding the debug information so that you +[1:37:19] can work out what's going on. Um but +[1:37:21] then and then that way your the +[1:37:24] complexities of traverse you know +[1:37:27] modeling and traversing a DAG uh are not +[1:37:30] in your real code. They're only in your +[1:37:31] debug code. +[1:37:33] Um the you've you've simplified that +[1:37:36] into the linearized or pipeline version +[1:37:38] in the actual code. +[1:37:41] Okay. So +[1:37:44] the point about assumptions here is +[1:37:49] that you can if you know the case you're +[1:37:52] working with, if you know the code that +[1:37:55] is running around this, if you know the +[1:37:57] problem domain, you can make so many +[1:38:00] assumptions that make it easier to +[1:38:01] understand and much faster to run. +[1:38:05] Um, +[1:38:06] but +[1:38:08] you know, designs change. You might be +[1:38:10] thinking like, okay, this is good as +[1:38:13] long as my my code stays exactly the +[1:38:15] same forever, but uh +[1:38:19] you know, things change and that is +[1:38:22] true. Um I would like to go more into +[1:38:24] this at some point, but I will touch in +[1:38:26] it now because I feel like I I should. +[1:38:29] Um, +[1:38:33] the first thing to say is +[1:38:38] you probably have some notion of what +[1:38:41] your design is going to be while you're +[1:38:42] writing it. Uh, and many programs are +[1:38:46] big and so you write them step by step, +[1:38:48] but you you have at least some notion of +[1:38:50] where you're going. Um +[1:38:53] there's there's a temptation to +[1:38:57] uh overly concret overly concretize kind +[1:39:01] of wherever you are. Um but you've got +[1:39:04] to there's you just have to have that +[1:39:07] self-awareness to like no this this is +[1:39:09] going to be this is this is going to +[1:39:11] change that don't optimize this. I don't +[1:39:14] want to tie myself into this specific +[1:39:15] limitation. And the example that jumps +[1:39:18] to mind for for me on that is um +[1:39:22] processes. Uh many debuggers will uh +[1:39:26] allow you to run multiple processes uh +[1:39:29] and analyze all of them at once. Ybox +[1:39:31] doesn't. And so I I would like to at +[1:39:34] some point so I don't make the +[1:39:35] assumption that I have a single process +[1:39:37] despite the fact that it's true across +[1:39:38] my entire codebase. +[1:39:43] Uh other friends that you have are +[1:39:46] static assert sizes, ranges, all that +[1:39:48] kind of thing. Um if you're assuming +[1:39:50] that uh your enums are in a particular +[1:39:53] range, uh you can check that at compile +[1:39:55] time. You don't have to um pay any +[1:39:58] runtime cost for that. +[1:40:00] A a fun one that um I haven't seen many +[1:40:04] people do is you can just add kind of +[1:40:07] garbage tokens that are meaningful to +[1:40:10] you. um make them exist somewhere and +[1:40:12] then use them around the code where you +[1:40:15] rely on the assumption that you're +[1:40:17] talking about and then if that if that +[1:40:19] assumption ever disappears you can get +[1:40:21] rid of the in this case define assume fu +[1:40:23] or you could have a constant or you know +[1:40:25] there's a few different ways you could +[1:40:26] do this and then your compiler will say +[1:40:30] basically this assumption is broken here +[1:40:32] and here and here and here go and check +[1:40:34] those +[1:40:37] [Applause] +[1:40:44] Uh, I'm a fan of asserts. Um, I'm sure +[1:40:47] you're all familiar with those. Um, +[1:40:51] there's nothing that requires you to +[1:40:53] requires you to make those be um just +[1:40:56] like simple expressions. If in de if +[1:40:58] you're in debug mode, uh you can do some +[1:41:01] arbitrarily complex check that +[1:41:03] structures are all like in the right +[1:41:05] order. the things that reference each +[1:41:07] other should reference each other, +[1:41:08] things that don't don't or shouldn't +[1:41:11] don't and so on. Um I think you saw +[1:41:15] earlier I have like unreachable and +[1:41:17] switch statements all the time. Um or +[1:41:19] like the end of an if else if else chain +[1:41:21] if you expect it to be handled above. Um +[1:41:24] this is another one that I quite like +[1:41:26] which is um +[1:41:29] in debug mode it will assert if the +[1:41:33] condition is true. Uh but in release +[1:41:37] mode it'll just evaluate to the +[1:41:38] expression itself. +[1:41:41] Um and then that means that you can like +[1:41:45] do the check for like this this just +[1:41:48] shouldn't happen. I I'm pretty sure that +[1:41:49] this doesn't happen. I'm not going to +[1:41:50] deal with that. Uh +[1:41:53] sorry. You are going to deal with that +[1:41:55] though because you're checking. So you +[1:41:57] can be like if this case happens that +[1:42:00] that is unexpected +[1:42:03] um tell me as a developer about it but I +[1:42:06] can do some kind of safe no op or exit +[1:42:08] the function or pass some error code +[1:42:10] back or however you're dealing with that +[1:42:12] um regardless and so that it's not going +[1:42:14] to affect the the end user. +[1:42:17] Okay, +[1:42:22] we have been, ladies and gentlemen, +[1:42:24] preempted again by bits of high level. +[1:42:29] Okay. Um, I'm not going to go over all +[1:42:31] of this. I'm not going to read a table +[1:42:32] off to you. I I just wanted to +[1:42:37] to bring up the idea that +[1:42:41] um you have a bunch of these bitwise +[1:42:43] operations, right? +[1:42:44] They're as concrete as it gets on a on a +[1:42:46] CPU. They're they're pretty fundamental. +[1:42:49] They're like mathematically understood +[1:42:51] concepts and all that. Um but +[1:42:56] once there's there's often a kind of oh, +[1:42:58] I've learned how they manipulate the +[1:43:00] bits now. I'm done with them. Um but I +[1:43:03] think if you can +[1:43:07] if you can see the other interpretations +[1:43:09] of these values +[1:43:12] see the other interpretations of these +[1:43:14] operations uh then you will find that +[1:43:16] they will apply in many cases in your +[1:43:19] codebase and ju just to +[1:43:22] to bring one up which I didn't really +[1:43:24] explicitly go over before um if we +[1:43:28] recall back to the +[1:43:32] this is on on the topic of +[1:43:35] reinterpreting things in multiple +[1:43:36] different ways. Our our base types, I +[1:43:40] know it's it's a long time ago now. +[1:43:42] Sorry for keeping you here so long, but +[1:43:44] if you recall back, we have our base +[1:43:46] type was our kind and our size, and we +[1:43:50] had those like jammed together. And we +[1:43:52] can interpret each of those things as +[1:43:54] separate values. Um, what I didn't say +[1:43:57] earlier, which I should have, is okay, +[1:44:00] we've put those together, we can +[1:44:01] reinterpret those as because we only +[1:44:05] have four bits for each of them. We +[1:44:07] reinterpret that as an 8 bit number, +[1:44:09] it's 256 +[1:44:12] different possible values. That is 256 +[1:44:14] different entries into our uh type +[1:44:16] array. And it means that we can +[1:44:21] we can we do this mapping back from um +[1:44:25] the the two +[1:44:27] twopart type kind into a location. So +[1:44:32] like it's not just it's sometimes one +[1:44:34] number and it's sometimes two numbers +[1:44:36] and the ability to switch between them +[1:44:37] lets you do extra things. And and the +[1:44:40] same goes for for these operations. Um +[1:44:44] yeah, I'm not going to go over them. you +[1:44:45] can get the slides afterwards and look +[1:44:47] over them if you want. Uh or you can +[1:44:48] find many other places that we'll we'll +[1:44:50] talk about them. +[1:44:53] Okay, it's been it's been a while. Thank +[1:44:56] you for bearing with me. Uh just going +[1:44:59] to sum up some of the things. Um I like +[1:45:03] stable pointers. Okay, if you can keep +[1:45:07] stable pointers, things become so much +[1:45:09] easier. I know that there are cases +[1:45:10] where handles are needed and that's +[1:45:12] fine. But there are many many sub cases +[1:45:15] where stable pointers are the best way +[1:45:17] to go. +[1:45:19] Uh if you can break your problems down +[1:45:24] into of separable dimensions +[1:45:27] um then you will find that uh you need +[1:45:33] much less code to handle all of the +[1:45:36] cases. And like you're a limited human +[1:45:38] being. There's only so much code you can +[1:45:40] understand. If you can if you can fit +[1:45:42] all the things that you have going on +[1:45:44] into a smaller space, it's often going +[1:45:47] to be easier. +[1:45:49] Um, now +[1:45:52] if if it's not obvious with the like a +[1:45:53] strct type and the product type um +[1:45:56] mentions, this rectangular dimensions +[1:45:59] thing is is kind of the same as a Plex. +[1:46:02] It's kind of the same as a mega. So we +[1:46:04] are team Plex team mega here. +[1:46:12] Um so what's happening is that with with +[1:46:16] your with your mega strruct you have all +[1:46:18] of these different members you think of +[1:46:20] all of these as a different dimension +[1:46:22] and at a certain point it gets hard to +[1:46:24] visualize but you can kind of abstractly +[1:46:26] think of it that way and then you know +[1:46:29] you don't all don't use all of these +[1:46:31] members in every case and those are just +[1:46:33] effectively holes in that space uh as I +[1:46:36] mentioned for +[1:46:40] hopefully I have convinced you that um +[1:46:42] you can think of bits as high level and +[1:46:45] um you can do these operations that are +[1:46:49] kind of semantically meaningful um that +[1:46:52] are incredibly concrete and the CPU is +[1:46:55] very happy doing them. Um I like +[1:46:59] pipelines. I'm going to keep it nice and +[1:47:02] simple. +[1:47:04] Try it out. see if it works for you. Um, +[1:47:09] again, I think that it you will find +[1:47:11] that it reduces the amount of context +[1:47:13] you need to keep in your head and +[1:47:15] reduces the amount of context that needs +[1:47:17] to be um, +[1:47:21] it reduces the amount that you have to +[1:47:23] add kind of uh, wrapping of stuff to +[1:47:26] make sure that certain assumptions +[1:47:28] aren't broken because if it's only used +[1:47:30] in one place, then you know how it's +[1:47:32] being used. +[1:47:34] Um +[1:47:37] many of these cases are about kind of +[1:47:39] removing indirection in one form or +[1:47:40] another. Whether that's extra calls, +[1:47:42] extra memory accesses, um doing thing +[1:47:46] doing doing things with complicated +[1:47:49] operations where we could do them with +[1:47:50] just a a simple bitwise. And +[1:47:55] [Music] +[1:47:57] the final point on generalization +[1:48:00] um +[1:48:02] I guess I guess my take on this is +[1:48:07] you want to know we've we've gone +[1:48:09] through these different topics. We've +[1:48:10] gone through kind of mappings and +[1:48:12] pipeline or dependencies +[1:48:14] uh and and uh understanding the +[1:48:17] different dimensions of things whether +[1:48:18] that's like tree structures or whatnot +[1:48:21] um tree structures or dimens or uh +[1:48:24] separable dimensions and I think that it +[1:48:28] is useful to know what the +[1:48:30] generalization of the thing you're doing +[1:48:32] is. I think the the map is the really +[1:48:34] obvious example to me there where like +[1:48:36] I'm doing a mapping I can map +[1:48:39] or I can use an array index or I can use +[1:48:42] any of these other things. Um so +[1:48:45] knowing what the generalization is will +[1:48:48] help you know will provide you a way of +[1:48:52] shortcutting to what the possible +[1:48:54] options to your solutions are. And then +[1:48:56] given your different assumptions, you +[1:48:58] can make a different specialization +[1:49:00] um to to do the simple thing, but the +[1:49:04] the simplest thing that is required that +[1:49:06] is not going to lock you in. +[1:49:10] I would tend to lean towards +[1:49:14] generalization over abstraction. uh as a +[1:49:16] rule um you end up with uh many fewer +[1:49:22] code paths and less indirection and a +[1:49:25] much better understanding of of what +[1:49:26] you're doing. Uh and if you actually +[1:49:28] need to understand the codebase, which +[1:49:31] you do because things are going to go +[1:49:32] wrong and you need the bug fix and you +[1:49:35] if there are bugs then your model of the +[1:49:37] world is wrong and you don't know why. +[1:49:40] So you're going to have to assume that +[1:49:42] everything is not working and if there's +[1:49:45] more code and more indirection that is +[1:49:47] going to be so much harder. +[1:49:52] Thank you very much for listening. I +[1:49:54] appreciate you sticking through with me +[1:49:57] there. Uh if you want to follow me on on +[1:50:00] Twitter or follow Whitebox, uh there's +[1:50:02] the the links. Uh feel free to message +[1:50:05] me about this or Whitebox or anything +[1:50:06] else. Uh and you can have a look at +[1:50:08] webbox on the website. Thank you very +[1:50:11] much. +[1:50:21] Thank you so much. That was such a good +[1:50:22] talk. Uh if you haven't already, uh you +[1:50:25] should go to whitebox.systems and try +[1:50:26] out whitebox. It is truly amazing what +[1:50:29] this program can do. It is unlike +[1:50:30] anything I have ever seen before and +[1:50:32] it's it's totally worth a try. Um so +[1:50:34] definitely go there. Um, I did want to +[1:50:36] ask you, +[1:50:36] >> that's very kind. I will just warn you +[1:50:38] that there are still sharp edges. So, +[1:50:39] uh, mind your fingers. +[1:50:42] >> I wanted to ask you, uh, I think it says +[1:50:44] it's on version 0.122. +[1:50:47] I wanted to know what the current state +[1:50:49] of white box is. What's the future? +[1:50:51] >> Um, yeah, that's actually a kind of +[1:50:54] that's an old version. It's actually uh +[1:50:56] we we just stopped doing that numbering +[1:50:59] system at some point and started saying +[1:51:00] the the date that things came out +[1:51:01] because it it felt somewhat ridiculous. +[1:51:03] Um, so we're currently releasing +[1:51:07] whenever there's there's something +[1:51:08] something new. Uh, and you know, if you +[1:51:12] if you've bought it, you access until at +[1:51:14] least the end of version version 1.0 +[1:51:16] reel, which we're not at yet. +[1:51:18] >> Is there something that'll mark the 1.0 +[1:51:20] release? +[1:51:23] >> Uh, that's a good question. There's +[1:51:26] there's a number of things that we +[1:51:27] definitely need. Um, and then there's a, +[1:51:30] you know, a list a list of nice to +[1:51:31] haves. Um, but I think it would take too +[1:51:34] long to to iterate through that now. +[1:51:38] >> So, I'm in the fortunate place of having +[1:51:40] seen this talk twice now. Uh, and I +[1:51:42] think I understand it about maybe 60 to +[1:51:44] 70%. I'm getting there. Um, so if you +[1:51:47] haven't or you know in the future once +[1:51:48] this is able to be watched as a VOD, you +[1:51:50] should definitely watch it again if you +[1:51:51] didn't understand everything, which I +[1:51:53] suspect is most the people here in the +[1:51:54] audience. Um, but you have an amazing +[1:51:56] amount of insight. There's so many +[1:51:58] interesting concrete details here that +[1:52:00] you've pointed out. Um, one of the +[1:52:02] things I find very interesting is, uh, +[1:52:04] you you have this sort of like empathy +[1:52:06] for the computer that helps you see the +[1:52:08] like combination between you and the +[1:52:10] computer and what is capable between you +[1:52:12] two. Um, specifically like operator the +[1:52:15] operands for instructions uh can be +[1:52:17] encoded smaller if you use numbers that +[1:52:19] are not shifted up like 32 bits or +[1:52:21] whatever. Um and and also like the whole +[1:52:24] uh structures that you have basically +[1:52:25] generics in C uh where with the calling +[1:52:29] conventions and knowing that you only +[1:52:30] have so many registers to pass um that +[1:52:32] sort of like three-way connection blows +[1:52:34] my mind. Um how did you how did you get +[1:52:37] to the state you were able to make those +[1:52:38] kinds of connections? +[1:52:40] So I think as a debugger you get a a +[1:52:44] head start on insight into those because +[1:52:46] you have to deal with calling +[1:52:47] conventions and you have to deal with +[1:52:49] you know what what registers are being +[1:52:51] passed and so on. Um +[1:52:53] uh more recently we're we're trying some +[1:52:57] uh some JIT stuff in the user process +[1:52:59] and as part of that we've been making um +[1:53:02] kind of a an assembler API. Uh so it's +[1:53:06] just just function calls rather than +[1:53:07] interpreting some text but basically +[1:53:09] doing the same thing that an assembler +[1:53:10] would for the subset that we of x86 that +[1:53:13] we need. Um, and that like really drives +[1:53:17] home the uh the encoding issues like +[1:53:21] this this is an immediate I have a +[1:53:24] deleted scene that um where the encoding +[1:53:29] of an LEA kind of changes between um you +[1:53:33] know you can you can encode you use LEA +[1:53:36] to do these little tricks where you +[1:53:39] multiply by one two three four five +[1:53:43] eight or nine +[1:53:44] Um, and kind of surprisingly a multiply +[1:53:48] by five, three, five or nine is encoded +[1:53:54] smaller than the powers of two. Um, +[1:53:58] and and that's like a quirk of the x86. +[1:54:01] Um, there are reasons behind that, but +[1:54:04] like it's it catches you out when you +[1:54:06] when you look at it. Um, +[1:54:09] so having done that really reinforced +[1:54:11] it. I think as I mentioned earlier, +[1:54:13] Godbolt is just like a wonderful +[1:54:15] resource. Everyone, if you haven't used +[1:54:16] Godbolt, what are you first of all, what +[1:54:18] are you doing? And second of all, go +[1:54:19] there now and put some code in and see +[1:54:21] what happens. Uh see what the machine is +[1:54:23] actually doing with with your +[1:54:24] instructions. +[1:54:26] >> Um so, uh if you haven't noticed, I've +[1:54:29] gotten more than my fair share of +[1:54:30] questions, uh in this conference. Um and +[1:54:33] I have around 20 questions written down +[1:54:36] here, so I'm not going to ask all of +[1:54:37] those. +[1:54:37] >> You can't ask all of them. We we there's +[1:54:40] no way we can fit Demetri. So we have to +[1:54:42] move into tomorrow. So you actually have +[1:54:43] >> Wait, hold on. +[1:54:44] >> Yes. +[1:54:45] >> How many is too many? +[1:54:48] >> All right. Well, for now I I will ask +[1:54:49] one more question. We'll do some +[1:54:50] audience questions. When we run out, +[1:54:52] we'll do more questions. Uh so buckle +[1:54:54] in. Um so one of the things I find +[1:54:57] really interesting uh and uh is that uh +[1:55:01] I often do I think Casemitori does this +[1:55:03] for bitwise operators. you'll often do +[1:55:05] like is flag set or all flag set or +[1:55:07] things like this where you kind of wrap +[1:55:08] up the bitwise operators and you kind of +[1:55:09] push them away a little bit with a +[1:55:10] define. Um, and I think at one point you +[1:55:13] called the unary not operator a squiggly +[1:55:15] kind of like endearingly. Um, I'm +[1:55:17] curious like do you think there's a +[1:55:19] benefit to keeping those operators in in +[1:55:21] the front there like being able to see +[1:55:23] those? +[1:55:24] >> Yeah. So, +[1:55:27] I think +[1:55:30] this doesn't really help when you're +[1:55:31] first writing it, but the the benefit of +[1:55:37] choosing one of these paths, whether you +[1:55:38] have kind of a meaningful name or the +[1:55:41] the operator just bare. Um the the value +[1:55:45] you get from having one of those +[1:55:47] consistently within a location is the +[1:55:49] ability to uh compare and contrast +[1:55:51] between them. So +[1:55:54] the problem is you don't know this +[1:55:55] beforehand which of those you don't +[1:55:57] necessarily know you might have a +[1:55:58] heristic which of those is going to be +[1:56:00] useful but you might end up with a +[1:56:02] situation where you want to contrast +[1:56:04] like is any bit of this set in one case +[1:56:06] and is all are all bits set in the other +[1:56:08] case and I know in the white box +[1:56:11] codebase we do that in a in a checkbox +[1:56:14] for like is a is it a tick or is it a +[1:56:16] the um you know half filled in square uh +[1:56:20] and in that case your your diff The +[1:56:22] point of having these things next to +[1:56:24] each other is to juxtapose those two +[1:56:26] different versions. Um, but then I think +[1:56:28] the the raw version is useful where +[1:56:33] um +[1:56:35] you end up with a bunch of these these +[1:56:37] operations next to each other and +[1:56:41] particularly if you're doing it in a +[1:56:42] branch way, you're just doing kind of +[1:56:44] simple maths at each point. Um, and I +[1:56:47] mean you saw what happened with the the +[1:56:49] minus x plus one and you can you find +[1:56:54] that many of these bitwise operators +[1:56:56] have a mathematical identity with some +[1:56:58] other things. So if you have some +[1:57:00] complex combination of operators, it may +[1:57:02] actually just collapse down to one or +[1:57:04] two. And +[1:57:08] um I guess that's interesting from a +[1:57:10] micro optimization point or if it's in a +[1:57:13] hot loop. Um but sometimes that's also +[1:57:15] interesting from like oh there's some +[1:57:18] kind of more fundamental thing that is +[1:57:19] happening. I'm I'm doing all this +[1:57:21] garbage as a way of describing this +[1:57:22] operation. Uh or you know this this +[1:57:25] straightforward way of describing this +[1:57:27] operation that happens to have multi +[1:57:28] multiple steps but actually there's +[1:57:30] there's only one thing that's happening. +[1:57:32] Well there's only a couple of things +[1:57:33] that are happening. Um, +[1:57:37] I wish I could give a prescription to +[1:57:39] when when to choose which, but it's a +[1:57:42] kind of gut feel, I guess. +[1:57:44] >> You said you work with contractors. Do +[1:57:46] you feel like you ever get push back +[1:57:47] from them being like, "Oh, this is +[1:57:49] scary. This is an operator. I don't +[1:57:50] know. I don't use the squiggly that +[1:57:51] often. What does that do again?" +[1:57:54] Um +[1:57:57] uh +[1:57:59] I mean I don't think we've had any +[1:58:03] issues with that because +[1:58:06] uh they're all intelligent and well +[1:58:09] practiced programmers. Uh so um +[1:58:14] you know I I kind of think that +[1:58:19] the these bitwise operators are pretty +[1:58:22] fundamental things in computing and +[1:58:26] unless architectures change +[1:58:27] dramatically. They're going to be around +[1:58:29] for a for a long time. um +[1:58:34] if you if you don't know them now then +[1:58:36] then you can learn and you know that +[1:58:39] they're a little bit unfamiliar at first +[1:58:40] but I think the familiarity is the the +[1:58:42] main barrier to get over once once you +[1:58:44] understand what they do that they're +[1:58:45] fairly straightforward. +[1:58:47] >> I used to have a co-orker I would talk +[1:58:49] to a lot about JavaScript. He loved +[1:58:51] JavaScript and he would often tell me +[1:58:53] that like oh yeah this this oneliner map +[1:58:56] like map thing that you can do in +[1:58:57] JavaScript it's amazing. And I was like +[1:58:59] well you know it's a little bit hard to +[1:59:00] understand. And he was like, "No, no, +[1:59:01] you should understand map for free. +[1:59:03] That's like a thing you should know as a +[1:59:04] JavaScript developer." And the rest of +[1:59:06] like all these like standard library +[1:59:07] things come for free assuming you're a +[1:59:09] good developer in this space. And I +[1:59:11] always kind of hated that idea of like +[1:59:12] uh just like the standard libraries, +[1:59:15] your atomic units that you should like +[1:59:16] take for granted, right? But I feel like +[1:59:18] the binary operators as you as you point +[1:59:20] out here, they are more fundamentally +[1:59:22] atomic units that like if you understand +[1:59:23] them, you understand them and those +[1:59:25] those help you out, you know, in the +[1:59:27] long term. +[1:59:27] >> Yes, definitely. Um, and not not only +[1:59:32] are they fundamental, +[1:59:35] um, +[1:59:38] I've kind of said this a few times, but +[1:59:39] they're very concrete. Like if you have +[1:59:41] a map over something with, I don't know, +[1:59:46] you you don't know what the +[1:59:48] implementations of that are. Um, there's +[1:59:50] maybe some side effect in terms of +[1:59:52] memory that you weren't expecting or +[1:59:54] maybe there's some edge case that it +[1:59:55] doesn't handle depending on what it is. +[1:59:57] Um +[2:00:00] and in the in the JavaScript case there +[2:00:03] are a million of them. There are like +[2:00:06] depending on how you count them like +[2:00:07] seven seven eight nine um bitwise +[2:00:11] operators, you know, it's something you +[2:00:13] can learn. +[2:00:15] >> All right, I'm going to go ahead and +[2:00:16] open it up uh for audience questions. Um +[2:00:18] let's go here. Yakas. Uh okay regarding +[2:00:22] your exponential array type um like have +[2:00:26] you ever tried comparing uh sorting +[2:00:29] sorting performance on let's say +[2:00:31] millions of items versus just regular +[2:00:34] array because I I do those a lot. So +[2:00:38] >> uh no I haven't tried comparing um we +[2:00:41] don't actually end up having to do any +[2:00:42] sorting because we're lucky enough that +[2:00:45] our input is already sorted by time. +[2:00:48] That's an important distinction. +[2:00:50] >> Yeah. +[2:00:51] >> Yeah. Yeah. Okay. +[2:00:52] >> I mean, +[2:00:54] there's maybe an edge case where like +[2:00:56] profiler style events come in that may +[2:00:58] be slightly out of order, but you're +[2:00:59] sorting like six elements rather than a +[2:01:02] million. You're just sorting at the very +[2:01:04] end. they're usually just iterating or +[2:01:06] or fetching one item or +[2:01:08] >> uh so what happen a relatively frequent +[2:01:11] case in the the timeline for instance is +[2:01:14] like um we we don't want to show all of +[2:01:18] the things that happened before the +[2:01:19] timeline. Uh so we will binary search at +[2:01:23] the the known start of the timeline find +[2:01:26] the first value at that point and then +[2:01:28] iterate from there there on uh that's +[2:01:30] quite common. um or there are places +[2:01:33] where we have multiple different bin +[2:01:35] multiple binary searches happening +[2:01:36] sequentially. +[2:01:42] No question, just admiration. You +[2:01:44] casually dropped a full Andrews hacker +[2:01:47] delight and the contents of a data +[2:01:49] structure white paper and just +[2:01:51] completely cool. No emotions, not even +[2:01:53] time for people to applause. Just like +[2:01:56] take this. +[2:01:57] >> Thank Thank you very much. That's very +[2:01:59] kind. +[2:02:05] You need to get uh better at pausing for +[2:02:07] applause. Like after every slide, you +[2:02:09] should just +[2:02:12] >> Any more questions? +[2:02:14] >> Will you be offended if I call them res? +[2:02:18] >> I mean, no, but it's more characters. So +[2:02:20] like, do you really want that? +[2:02:24] >> Oh, just the RA even shorter. daughter +[2:02:27] of Andrew. Now, +[2:02:29] >> CZ A R. +[2:02:34] >> Um, so you made a point of evangelizing +[2:02:36] for stable pointers at one point. Um, is +[2:02:39] there ever a time where you care about +[2:02:40] like keeping a pointer stable across +[2:02:44] multiple lifetimes like when it's +[2:02:45] deallocated and reallocated or does that +[2:02:48] basically always mean that you should +[2:02:50] expand the lifetime to to merge both? +[2:02:53] Um, do you have any particular examples +[2:02:56] in mind of when that +[2:02:58] >> I don't. asking if there's any any case +[2:03:00] where that would be something you'd care +[2:03:02] about or whether you +[2:03:04] >> I guess the the closest thing +[2:03:08] I I think we we have +[2:03:11] memory that persists across lifetimes +[2:03:17] um or across multiple lifetimes but not +[2:03:22] not stable pointers +[2:03:26] to them. Uh +[2:03:28] let's think. I think the the place where +[2:03:30] this might come up is to do with +[2:03:33] handling um our run arena because we +[2:03:38] don't want to give the memory back to +[2:03:40] Windows and then immediately ask for it +[2:03:41] again. So we we want we want to keep +[2:03:43] that around and +[2:03:46] um +[2:03:52] I mean so the the +[2:03:55] pointer to that is from like a parent +[2:03:59] strct. So I I guess in some in some +[2:04:02] abstract sense there's like a a run that +[2:04:04] hasn't happened yet. It's kind we're +[2:04:06] kind of between runs um and this pointer +[2:04:10] still exists. +[2:04:12] Uh, but +[2:04:15] I didn't I didn't really go into this, +[2:04:16] but you can kind of break down lifetime +[2:04:18] in multiple ways of like a value +[2:04:21] lifetime and a um a location lifetime +[2:04:24] and a memory lifetime. Um, and like so +[2:04:28] the memory is still is still there and +[2:04:31] the base strct is still there even if +[2:04:33] the thing that is conceptually +[2:04:35] referencing doesn't exist anymore. Um, +[2:04:42] yeah, I think that's where I come from +[2:04:44] with that. +[2:04:47] >> Other questions? Yeah. +[2:04:48] >> So, I find the exponential array like +[2:04:51] super cool. I I've never seen it. +[2:04:55] >> Like a mix between a slab allocator and +[2:04:59] um a binary tree in a +[2:05:02] >> array. +[2:05:03] So, I just want to know like has anyone +[2:05:05] seen it before? +[2:05:08] I think I have seen this. +[2:05:13] >> Can we uh +[2:05:14] >> It reminds me of like array mapped hash +[2:05:16] tries, right? Stuff like that. +[2:05:17] >> Yeah. But those are now called zars. +[2:05:19] >> No, those end up on trees. +[2:05:22] >> Those end up as a tree of nodes. +[2:05:23] >> Yeah. Yeah. Like it's arrays of arrays +[2:05:25] and they're exploited in the fact that +[2:05:26] we have power too where we do logarithms +[2:05:28] and stuff like that. +[2:05:30] >> Yes. But they're like log based on path +[2:05:32] link path. +[2:05:33] >> Yeah. +[2:05:35] You go wider, right? +[2:05:37] So I think +[2:05:40] I think there's like a +[2:05:42] log structured merge tree is a thing in +[2:05:44] databases +[2:05:46] um that uses a kind of similar concept +[2:05:49] of doubling sizes but for the for an +[2:05:52] entire tree at a time uh and that I +[2:05:55] forget the exact sequence but that may +[2:05:57] have been an inspiration as part of +[2:05:58] this. Um, +[2:06:01] but yeah, I'd be interested to see if +[2:06:02] anyone's seen them kind of used as +[2:06:06] intermediate data structures in code +[2:06:07] before. I will have to come and chat to +[2:06:10] you afterwards. +[2:06:11] >> I think it's worth mentioning. There was +[2:06:12] like probably six different messages in +[2:06:14] the chat and the Twitch chat being like, +[2:06:15] "Oh my gosh, this is amazing. This is +[2:06:17] our thing. Oh, what is this? This is +[2:06:18] really interesting." Um, so it's +[2:06:20] definitely a very interesting data +[2:06:21] structure people are excited for. What +[2:06:22] do you think is the applicability for +[2:06:24] your own programs after white box or +[2:06:26] other people's programs? Do you think it +[2:06:28] is a generally purpose or general +[2:06:29] purpose data structure for a large set +[2:06:32] or is it like where's the boundaries +[2:06:33] there +[2:06:34] >> uh of zars that +[2:06:35] >> yeah like what kind of things would make +[2:06:37] it not useful or where's the boundary +[2:06:39] >> so um I obviously showed that within um +[2:06:41] a single a single tree of uh types but +[2:06:46] having introduced the idea to the +[2:06:48] codebase they've they've popped up +[2:06:50] everywhere um because there's just this +[2:06:55] uh this this uh effectively static +[2:07:00] header size and then um all of the +[2:07:05] blocks being pushed later into an arena. +[2:07:08] Uh they're very easy to um +[2:07:13] you can you can have the header on the +[2:07:15] stack uh and then have some scratch +[2:07:18] point to an arena push types push uh +[2:07:22] push strings push um arrays. it's ours +[2:07:27] of any length. Uh and then once you're +[2:07:30] done with the and you can in the the +[2:07:33] important thing here is that you can +[2:07:34] interle pushing onto multiple virtual +[2:07:36] arrays at once uh and then just pop back +[2:07:39] at the end. Um and they're +[2:07:42] uh you know it's as if they never +[2:07:44] existed. +[2:07:46] So keep keeping that that main advantage +[2:07:48] of arenas and +[2:07:51] um yeah I'll I'll the pitfalls of them +[2:07:56] one of them is the same as any other +[2:08:02] actually before that so one way of +[2:08:04] thinking about them is as a +[2:08:05] generalization of regular slices where a +[2:08:08] slice would be um number and pointer and +[2:08:10] this is just number and pointer pointer +[2:08:12] pointer pointer pointer um but the the +[2:08:15] pitfall +[2:08:16] is um true with kind of any chunked +[2:08:21] um +[2:08:23] chunked data structure where you can +[2:08:28] if you if you interle +[2:08:31] uh pushing some stuff and then you take +[2:08:32] another +[2:08:34] um another scratch point on your arena +[2:08:38] push more things you may add another +[2:08:42] chunk onto your ZAR or other chunk +[2:08:45] chunked um array like thing. Um and then +[2:08:48] when you pop back, you now have a ZAR in +[2:08:53] a partially valid state. So you've got +[2:08:55] your first chunks and your last chunks +[2:08:57] and and so accessing this will happen +[2:09:00] will will occur legally and accessing +[2:09:02] that um might not occur every time. And +[2:09:04] so you can you can hit that. So that +[2:09:06] that is a case to be careful of. But I +[2:09:08] think that is as far as I can see just +[2:09:11] um unavoidable in the case of trying to +[2:09:15] have stable chunk arrays of any sort. Um +[2:09:20] and and once you know to watch out for +[2:09:22] it, you can you can do things like I +[2:09:25] mean asan is an obvious example. You can +[2:09:27] poison the end of your arena and so +[2:09:29] accessing it is is immediately +[2:09:31] immediately shows up loudly. Um and then +[2:09:35] the the other cost to them is +[2:09:40] you have you know 20 pointers or however +[2:09:43] many pointers. Uh +[2:09:46] now you can the nice thing about that is +[2:09:49] that you can you know you only have to +[2:09:51] add if you add three more pointers +[2:09:53] you've octupled the size of your array. +[2:09:57] And you know like it's it's pretty easy +[2:09:58] to convince yourself that that is +[2:10:00] sufficient for uses. Um but if you end +[2:10:04] up with um a really large number of +[2:10:08] otherwise small data structures +[2:10:11] that refer to a typically small number +[2:10:14] of things but occasionally it's large +[2:10:16] then um you end up with like quite a +[2:10:19] large overhead of um this these pointers +[2:10:23] and +[2:10:25] yeah I mean you can use one of the other +[2:10:27] options in those cases you could like +[2:10:29] move back to the general case. I I think +[2:10:31] the most general thing is possibly the +[2:10:33] tree case. Um +[2:10:36] but you know there's various options +[2:10:38] that we went over that you could think +[2:10:40] through for your problem. +[2:10:43] >> Yes. +[2:10:44] >> So they kind of exist in reference in a +[2:10:48] blog post from like the the machinery +[2:10:51] guys. Rest in peace. Uh +[2:10:53] >> well they're gone now. So +[2:10:55] >> yeah, but I they don't end up going with +[2:10:58] them. like they kind of think about them +[2:10:59] and say, "Nah, we'll do something else." +[2:11:01] >> Yeah, I think I know the the article +[2:11:03] you're you're referencing there. Yeah, +[2:11:04] >> I don't think they realized that the +[2:11:06] number of pointers you need to keep is +[2:11:08] bounded. +[2:11:09] >> Yeah, I I think that was was an +[2:11:11] important thing. Yeah, the like what +[2:11:13] what made it worth like moving because +[2:11:16] if you have to have that extra pointer +[2:11:18] in direction, it's like I don't know is +[2:11:20] that really worth it? But the fact that +[2:11:22] it's it's that relatively small bound +[2:11:25] makes it quite convenient to keep you +[2:11:27] know you have this single array +[2:11:29] structure all at once. +[2:11:30] >> Yeah, they suggest keeping the pointers +[2:11:32] in a dynamic array and I don't think you +[2:11:34] would suggest that if you realize, oh +[2:11:35] wait, I only need this many. +[2:11:36] >> Yeah. +[2:11:36] >> Yeah. The thing I I was thinking of is +[2:11:39] doing that. +[2:11:40] >> Cool. +[2:11:41] >> So it is normal. +[2:11:48] >> Sam, how are we doing on time? Do we +[2:11:49] want to cut off at a specific time? +[2:11:51] >> All right. All right. Um, so one of the +[2:11:54] things I learned a lot from your talk or +[2:11:56] when I originally saw it especially was +[2:11:58] uh +[2:11:58] >> keep asking. +[2:11:59] >> Yeah. This idea of of parameter space +[2:12:01] and especially how you deal with holes, +[2:12:03] right? So often times when I'm trying to +[2:12:05] make a system uh I really want that +[2:12:07] system to be clean and and like kind of +[2:12:08] perfect in a way, right? So when I come +[2:12:10] across a hole where it's like this +[2:12:11] combination of parameters that's not +[2:12:13] defined, that seems weird. I must be +[2:12:14] doing something wrong. Um +[2:12:17] yeah I guess how did you come across +[2:12:19] that concept? How did so you you +[2:12:21] essentially advocate for like the holes +[2:12:23] can be fine actually right so you do +[2:12:24] this with your your 10 byt or yeah 10 +[2:12:27] byt float uh and even though it +[2:12:29] technically is a slightly unbalanced +[2:12:31] parameter tree uh it's more useful to +[2:12:34] have a consistent parameter space that +[2:12:36] you can talk about stuff with with a +[2:12:38] hole or an extra thing on top. +[2:12:40] >> Yes. Um, +[2:12:46] now I guess the reason +[2:12:50] that I think that +[2:12:52] um is because I was already on team +[2:12:54] mega. +[2:12:56] Um, and then +[2:12:59] like I listened to some array +[2:13:01] programming people talk about what +[2:13:02] they're doing with their their different +[2:13:04] dimensions and um the fact that all of +[2:13:07] their arrays are rectangular and they +[2:13:08] talk about having holes but how it +[2:13:10] doesn't matter. um like the the the the +[2:13:12] the real benefit comes from having this +[2:13:15] simple and consistent um +[2:13:18] this simple and consistent mapping for +[2:13:20] things and simple and consistent +[2:13:21] identity. Uh and then +[2:13:24] the connection between those I I know I +[2:13:27] I mentioned all these different things +[2:13:28] and it may have seem seemed somewhat +[2:13:31] random to bring up array programming and +[2:13:32] functional programming. Um but the the +[2:13:36] notion of the product type on once +[2:13:37] you're familiar with the fact that a +[2:13:39] product type or construct is a product +[2:13:41] type and that's just the fact that it's +[2:13:43] referencing effectively these different +[2:13:44] dimensions then that kind of clicked in +[2:13:47] make making the link between these two +[2:13:49] things +[2:13:52] take another audience question +[2:13:55] >> how important is the rule that the first +[2:13:57] element of your has to be two like +[2:14:00] because I know that that means like it's +[2:14:02] going to be a power of two yes So what h +[2:14:04] if you have a power of two minus one as +[2:14:06] like your size, how bad is that? Like +[2:14:07] does that mess up like your entire like +[2:14:09] get function or something? +[2:14:11] >> So how important is it that it's a power +[2:14:13] of two or how important is it that it's +[2:14:15] exactly two? +[2:14:15] >> Size of the entire array is always um +[2:14:18] because I I saw like your first element +[2:14:20] is always going to be two elements +[2:14:21] instead of being one two four you have +[2:14:23] two two four. I know that results into a +[2:14:25] side an array size of like power of two +[2:14:27] instead of like power two minus one. +[2:14:29] >> And how important is that? Okay. So, um +[2:14:32] they don't have to be just two. That +[2:14:35] that was just for the um to keep it +[2:14:37] small on the slide. Uh it +[2:14:40] the way I have my implementation is the +[2:14:44] the first is always a power of two. Um +[2:14:48] so +[2:14:50] commonly +[2:14:52] like a shift of six or a shift of eight. +[2:14:54] So 64 or 256 elements. Um now on the +[2:14:59] context of or the the on the question of +[2:15:02] um nonp power of two base sizes +[2:15:06] um so so I part of the answer to that is +[2:15:09] like that's um +[2:15:13] is +[2:15:16] uh you you get some of the benefit of +[2:15:18] this uh non-power to thing by +[2:15:21] distinguishing between +[2:15:24] the size of the element as just +[2:15:26] an any size that doesn't have to be a +[2:15:28] power of two, anything. Um, and the um +[2:15:31] number of elements being a power of two +[2:15:33] because it means that you can treat +[2:15:35] indices as powers of two um but not um +[2:15:41] like it doesn't have to be a power of +[2:15:42] two offset into the into the array. The +[2:15:48] um question no +[2:15:51] there's a +[2:15:56] the the problem is um I think +[2:15:59] determining which trunk things are in +[2:16:02] and if you have nonpowers of two it +[2:16:04] becomes you have to do like a log +[2:16:06] operator or or some other trick that +[2:16:09] probably I'm actually I'm pretty sure +[2:16:11] there's there are tricks that exist in +[2:16:12] hacker light for like integer logs um so +[2:16:16] you can probably you could probably use +[2:16:17] one of those if you can find one um +[2:16:20] computers that like doing things with +[2:16:22] powers of you. So, uh, +[2:16:27] >> because I had like some I was thinking +[2:16:30] about like binary search and stuff and I +[2:16:31] was +[2:16:35] >> um +[2:16:37] I So I +[2:16:39] Okay, another downside with with these +[2:16:42] uh data structures is that they're +[2:16:43] slightly awkward to take sub slices of. +[2:16:46] Um, +[2:16:48] and so the the kind of naive option +[2:16:52] there is to do just like a pointer to +[2:16:54] the to the thing or just copy all of the +[2:16:57] the size and the um and the pointers and +[2:17:00] then have a begin and end offset. Uh I I +[2:17:04] did +[2:17:05] um I did work out the implementation +[2:17:09] of a +[2:17:12] kind of general sliced version of this +[2:17:14] where the the the first chunk is +[2:17:18] variably sized. Um and as far as I can +[2:17:22] tell that would work and it it works in +[2:17:24] part because um you have to treat zero +[2:17:28] as a special case anyway. Um +[2:17:33] but in practice I haven't used them once +[2:17:35] in since implementing it. Um +[2:17:39] your mileage may vary. +[2:17:42] >> Um one of the quotes in the talk that I +[2:17:44] felt like you should pause and wait for +[2:17:46] applause. Um you said something to the +[2:17:48] effect of bite first thinking wins over +[2:17:49] type based thinking. Um, and I believe +[2:17:51] this is in the context of uh what I +[2:17:53] would try to describe as like C style +[2:17:55] generics, but then you also do this +[2:17:57] parameter space packing and then that +[2:18:00] makes the calling convention much better +[2:18:01] and and like all these things come +[2:18:03] together, right? Um, do you mind +[2:18:04] explaining like that quote a little bit +[2:18:06] more? +[2:18:10] Uh +[2:18:13] I guess I guess one one avenue you can +[2:18:16] go down with that is +[2:18:22] barring some complexities of the C +[2:18:24] memory model. Um +[2:18:28] the the bytes are an actual base +[2:18:30] reality. They're there and they have +[2:18:34] some bit pattern in them and you can +[2:18:36] interpret that bit bit pattern. uh in +[2:18:39] whatever way you'd like. Um the types +[2:18:43] are an artificial construct on top of +[2:18:46] that that helps us think about them and +[2:18:49] helps us catch silly mistakes. Um and +[2:18:52] while they're useful, they're not +[2:18:57] they're not the concrete thing that are +[2:18:58] there. And so if you can think about +[2:19:00] things like if you can think about +[2:19:01] what's actually there, then you have a a +[2:19:04] good chance of being able to work out +[2:19:05] something you can do with that. +[2:19:08] Do we have any more questions from the +[2:19:09] audience? +[2:19:11] I have a Yeah. Uh, let's go. Masha, +[2:19:14] >> it's not a real question. I'm sorry. So, +[2:19:17] the last the very last slide you had was +[2:19:19] marked as the third one, +[2:19:22] >> but it was also written that you had +[2:19:23] like 111. Is there a secret? And can we +[2:19:26] unlock that? +[2:19:31] >> Would you like to see the deleted +[2:19:32] scenes? +[2:19:33] >> We would like to see the deleted scenes. +[2:19:34] >> Okay. +[2:19:42] the these are slightly less structured. +[2:19:45] Um +[2:19:47] uh but I guess welcome to part five of +[2:19:49] bits of high level. +[2:19:51] Uh okay, first is +[2:19:57] thank you. +[2:20:00] Uh I actually lost count. however many +[2:20:02] parts this is. Um, +[2:20:06] again I mentioned before common thing +[2:20:07] you want to do bind some value in a +[2:20:11] lookup table. As a debugger we have to +[2:20:12] deal with fast fail codes. Um, and some +[2:20:16] of these are considered fatal, some of +[2:20:18] them are not. And um, +[2:20:22] the straightforward thing would just be +[2:20:24] to pack these in an array of bulls. And +[2:20:27] that would work. That would be fine. Um +[2:20:30] I in fact it's completely non-issue. Um +[2:20:34] however it's wasting 78 of the space and +[2:20:38] it hurts my soul and it's +[2:20:41] yeah um and there are like 76 of them or +[2:20:46] something depending on which Windows +[2:20:47] platform you run. Uh and +[2:20:50] the trick is realizing that all of the +[2:20:52] interesting ones happen under 63 and +[2:20:55] then you can pack rather than It's +[2:20:58] common to think of lookup tables as +[2:21:00] memory that you look at. Uh but you can +[2:21:02] also think of those as just values that +[2:21:05] you look at and you can kind of pack the +[2:21:07] value into uh a uh a 64-bit integer or +[2:21:12] however many bits you need. And then +[2:21:14] okay, so you've probably seen like +[2:21:16] single bit um bit packing. +[2:21:21] Um +[2:21:22] but there's no reason you have to stop +[2:21:25] at one. you can it's possible to pack uh +[2:21:29] you know any number of you know you have +[2:21:32] a fixed number of bits to play with. Um +[2:21:35] and given that you can scale how many +[2:21:38] different elements you have and how big +[2:21:39] each of those elements are within your +[2:21:41] like literal immediate value array +[2:21:45] thing. Um so if if we look at basic +[2:21:48] version we have um bool array of all of +[2:21:52] these different values you can um index +[2:21:55] into them and get the value out. That's +[2:21:57] it's pretty common. Uh and then we have +[2:22:00] the same but kind of shifted into this +[2:22:02] immediate mode world. Um and like this +[2:22:08] is if you haven't seen this before this +[2:22:09] probably looks unfamiliar. Um, but if +[2:22:12] you blur your eyes a little bit, it's +[2:22:14] quite similar to the array definition. +[2:22:17] Uh, you're shifting by the index into +[2:22:20] the array um multiplied by the number of +[2:22:23] bits each value in the array takes up. +[2:22:26] Uh, and then on the um on so that's +[2:22:29] that's creating the value, you're left +[2:22:31] shifting, and then on accessing the +[2:22:33] value, you right shift it so that those +[2:22:35] bits are the ones at the the bottom and +[2:22:37] then uh mask them off. Um and you can +[2:22:40] see that there's a relationship between +[2:22:42] the shift the number of bits uh and how +[2:22:45] you shift and how you mask. +[2:22:47] Um and then you can look at the +[2:22:51] um the disassembly for that. And +[2:22:55] like I said uh LA depending on exactly +[2:22:58] how how it's being used uh has slightly +[2:23:01] different encodings and so you end up +[2:23:03] with a slightly differently sized thing. +[2:23:04] Uh but you end up with four instructions +[2:23:07] that don't touch data memory. They're +[2:23:10] only touching instruction memory. Um and +[2:23:13] if you're thinking in terms of total +[2:23:14] memory, you end up with slightly less. +[2:23:17] Now again, it's one of those cases where +[2:23:19] it's like who cares? +[2:23:23] When am I going to use this? Um +[2:23:27] you end up with a similar total memory +[2:23:29] footprint. the the case that I've found +[2:23:35] is and and maybe it's just my own like +[2:23:39] personal mental disorder is um with +[2:23:44] um when you have a small array that gets +[2:23:49] you have lots of these small arrays and +[2:23:52] each individual one gets touched +[2:23:54] infrequently. So it won't be in cache +[2:23:56] but you end up touching a lot of them +[2:23:58] total. Um then it kind of becomes +[2:24:03] worth I don't know it if I do it this +[2:24:08] way it gives me peace of mind and it the +[2:24:10] it won't be the memory cache issue won't +[2:24:12] be an issue and I don't have to think +[2:24:14] about it. Um that way I you know it +[2:24:16] haunts my dreams even though it's seven +[2:24:19] bytes whatever. +[2:24:22] Um, and then the other use for this is +[2:24:27] um, +[2:24:30] uh, it's kind of a I think it's a John +[2:24:33] Blow something John Blow said at +[2:24:36] Handmade Con. Oh, sorry. Yeah, one of +[2:24:38] one of the early Handmade Cons um, about +[2:24:42] uh, one generally preferring +[2:24:45] arithmetic based code to like if +[2:24:48] condition based code. +[2:24:51] Uh, and if you have the ability to think +[2:24:54] of your data in terms of these little +[2:24:57] um, mini arrays, then you can you get to +[2:25:00] do this. And the the kind of +[2:25:03] furthest point that I think uh my my use +[2:25:07] of this has got to is um I have like +[2:25:12] these little teeny strcts with two two +[2:25:15] bit members and then I can pack two +[2:25:19] uh two of these strcts into an array of +[2:25:23] of eight bits and then I have an array +[2:25:25] of those like array of those bytes and +[2:25:28] then I have another array of those uh +[2:25:30] bytes. So this is accessing like the +[2:25:33] um it's using because it's a two element +[2:25:36] array it uses a bool as an index um and +[2:25:39] then you shift it by the index times +[2:25:43] whether or not you shift it by four and +[2:25:45] then um you add on the shift of whether +[2:25:47] you want the first element in the strct +[2:25:49] or the second element in the strct. Um +[2:25:51] and then um +[2:25:54] shift it by that much and mask off the +[2:25:57] couple of values. I guess it helps in +[2:26:00] this case that both elements of the +[2:26:02] struct are the same size. +[2:26:05] Uh +[2:26:07] what was this? Yeah, there was some kind +[2:26:10] of general +[2:26:12] recommendations around the little +[2:26:18] thinking about bit packing like does +[2:26:21] does it already if you just put the +[2:26:23] value in some bits does it already fit +[2:26:25] in those bits? If so, you're done. um +[2:26:28] does the minimum the maximum value minus +[2:26:30] the minimum value does that range fit in +[2:26:33] your bits? If so, you can shift it by +[2:26:34] the minimum value and then reintroduce +[2:26:36] the minimum value on the way out. Um you +[2:26:39] can think of it in term rather than +[2:26:40] think of it as a range you think of it +[2:26:42] as discrete values because it might be +[2:26:44] sparse. And then you can um +[2:26:48] you know if you have 255 different +[2:26:51] values regardless of how different those +[2:26:53] values are, regardless of what type they +[2:26:55] are, you can refer to any of them uni +[2:26:58] uniquely with eight bits. Um +[2:27:04] and if +[2:27:07] you know so the then the simple version +[2:27:09] is you'd put that in array but there +[2:27:11] might be some pattern that you can +[2:27:12] exploit so that you just get the value +[2:27:13] out immediately without having to touch +[2:27:14] memory or you do the somewhat +[2:27:20] uh +[2:27:21] yeah you do you do the the bitwise +[2:27:24] immediate array version thing or you do +[2:27:26] some more like real compression style +[2:27:28] thing with +[2:27:30] um +[2:27:31] what is it +[2:27:34] arithmetic trees I forget the precise +[2:27:36] terminology +[2:27:37] if you want to know more about these +[2:27:39] things uh hackers alike is quite well +[2:27:41] known hackme is a PDF that goes around +[2:27:44] occasionally from like +[2:27:48] at least 50 years ago but I forget +[2:27:50] exactly when um it's a little bit more +[2:27:52] kind of sign it's about solving the +[2:27:54] scientific problems rather than the +[2:27:56] direct +[2:27:58] um kind +[2:28:00] more immediate use of of bitwise +[2:28:02] arithmetic that hacker light has and +[2:28:04] then there's an HTML with the URL with a +[2:28:08] couple more uh things that uh probably +[2:28:11] also within one of the other ones. +[2:28:16] Uh +[2:28:19] we Okay. Um this this is like one of the +[2:28:24] earlier slides, but this was blacked out +[2:28:27] before. +[2:28:29] Um +[2:28:31] it's just a a nice simplification that +[2:28:34] if you have flags, you can um you don't +[2:28:38] have to have a separate array, sorry, a +[2:28:40] separate enum for the non like +[2:28:42] non-shifted version of that flag to +[2:28:44] index into them. And then you can um get +[2:28:48] the value both set and get the value +[2:28:51] like directly in a in a way that is +[2:28:55] obvious how it relates to the the +[2:28:56] original flag. And like I said, the +[2:29:00] Clang +[2:29:01] compiler will let you do this at compile +[2:29:04] time. The +[2:29:06] um MSVC compiler will not, which is a +[2:29:10] shame. Um but this is an option if if +[2:29:16] you want to do it on MSBC. Um another +[2:29:19] option is just to have the the +[2:29:21] non-shifted values uh beforehand for the +[2:29:24] for when you're setting the compile time +[2:29:26] uh sorry when you're setting the uh +[2:29:30] the +[2:29:32] flag string index. And then like hidden +[2:29:36] in here is another use of this +[2:29:40] um otherwise ridiculous array access. Um +[2:29:44] so each nibble in that each digit is +[2:29:50] um +[2:29:52] uh is the bit the highest bit within a +[2:29:57] nibble. And then you can uh it's it's +[2:30:00] it's +[2:30:03] the other case where you would use this +[2:30:05] slightly ridiculous array indexing uh is +[2:30:08] in compile time stuff where you can't +[2:30:10] access arrays like actual arrays. +[2:30:13] Uh and if you if you want to walk +[2:30:15] through that I'm I'm happy to go through +[2:30:17] that. +[2:30:19] And then a little trick is um like I +[2:30:25] said and as you knew most significant +[2:30:28] bit is undefined when when you get a +[2:30:32] value of zero um it's there are +[2:30:35] reasonable ways that you can wrap that +[2:30:37] so that you get minus one I think +[2:30:38] someone mentioned uh as the end result +[2:30:41] um but typically I just have it as the +[2:30:45] the bare version um +[2:30:49] the +[2:30:51] what you quite often end up in a +[2:30:53] situation like in my earlier code where +[2:30:58] the first thing and the second thing +[2:30:59] like the zero thing and the first thing +[2:31:03] are handled in the same way. Uh and if +[2:31:06] that is the case then you can do this +[2:31:08] like x or one trick and so if if it was +[2:31:11] zero uh then it becomes one and then the +[2:31:15] most significant bit is zero. If it was +[2:31:18] one already, then it stays the same. Um, +[2:31:20] and if it was a higher bit was set, then +[2:31:24] this is a no-up and you just still get +[2:31:25] the higher bit set. +[2:31:28] I think that is all of the deleted +[2:31:31] scenes. +[2:31:33] Yeah, there you go. Another random. +[2:31:40] Do you have a limit of how many +[2:31:41] questions you want? +[2:31:45] Um, this is an easy one actually. Uh do +[2:31:47] you think using something like Arc would +[2:31:49] go a long way or help you uh in any way? +[2:31:51] I know I believe that uh Whitebox is +[2:31:53] currently using deMue. Uh but I'm +[2:31:57] curious. +[2:31:59] >> Um I specifically the immediate mode UI +[2:32:03] arc arc UI +[2:32:05] >> that arc of the many arcs. Yeah. So, I +[2:32:08] caught some of that uh on stream, but I +[2:32:10] was not here because um uh I have a +[2:32:14] problem with my cash eviction strategy +[2:32:16] in my head. And so, if I'd come to the +[2:32:18] talks earlier, then I wouldn't have been +[2:32:20] able to remember anything for these uh +[2:32:21] for my own. So, I I have glimpsed it but +[2:32:25] not seen seen the details. Um +[2:32:29] it's it's very possible. I'm I'm kind of +[2:32:31] using Darham Guey in a way that it's not +[2:32:33] really intended to be used. Uh and it +[2:32:35] causes some friction. uh and it at some +[2:32:38] point does need a U new UI. +[2:32:40] >> Are there particular like wish list +[2:32:42] things you want from DMUI or if you know +[2:32:44] if you were to use another framework you +[2:32:45] would like something that does X? +[2:32:48] >> Um +[2:32:51] part of the problem is that it's not set +[2:32:57] up directly for exactly how I want to do +[2:33:00] profiler and debugger like views. um +[2:33:03] which you know would be unreasonable to +[2:33:05] ask of someone's UI uh which kind of +[2:33:08] implies that we should probably build +[2:33:10] our own but that's a that's a sort of +[2:33:12] rabbit hole. Um +[2:33:20] yeah I think I think a lot of the issues +[2:33:21] come around with +[2:33:23] when we want to build custom UI +[2:33:25] features. +[2:33:28] >> Are there any more audience questions? +[2:33:32] This might be a bit of a big question, +[2:33:34] but we were talking earlier about hashts +[2:33:37] and how you had a sort of new way of +[2:33:40] doing that on top of arenas. Uh would +[2:33:44] you want to expand a bit on that? +[2:33:48] >> This was a discussion we're having +[2:33:49] outside of the outside of this talk. +[2:33:51] Yeah. +[2:33:54] Um +[2:33:57] so +[2:34:01] okay hashts +[2:34:04] you have +[2:34:06] by the way if anyone hasn't implement a +[2:34:07] hasht I would recommend going and doing +[2:34:09] it not necessarily for use just but to +[2:34:11] understand the different things that are +[2:34:13] going on there it really helps um take +[2:34:15] something that is consider you would +[2:34:17] normally consider magic because of a lot +[2:34:20] of the hash magic that's going on and +[2:34:21] turning that into something that's +[2:34:22] concrete +[2:34:23] Um but specifically to the question +[2:34:26] um +[2:34:29] okay so first thought is many of our +[2:34:33] uses of +[2:34:35] um hashmaps are as acceleration +[2:34:38] structures kind of pointing into already +[2:34:42] stable places and so the +[2:34:45] um I'm far I'm far less concerned with +[2:34:49] having acceleration structures be stable +[2:34:50] than having the kind of quotequote real +[2:34:52] data uh be stable, +[2:34:56] but that's not all cases. Uh and you do +[2:34:59] want, +[2:35:00] as I said, it's nice having stable +[2:35:02] things. So, you have you have a few +[2:35:05] options. Um, +[2:35:08] and as I mentioned to you before, to my +[2:35:10] shame, many of the hash or the h the +[2:35:13] general hash table that we use within +[2:35:15] whitebox is is still uh using reallock +[2:35:18] because +[2:35:20] um I did it ages ago. Um long before +[2:35:24] coming +[2:35:26] coming to the aesthetic sensibilities +[2:35:27] that I have now. Uh and +[2:35:31] um basically it's just never been a +[2:35:33] priority to change. +[2:35:35] Okay, I'll I'll stop deferring and +[2:35:36] answer the actual question. The um +[2:35:42] so we have the +[2:35:46] when when you implement a hash table, +[2:35:48] you have your +[2:35:50] um +[2:35:53] you hash your key and then you end up +[2:35:55] with a thing that you turn into an index +[2:35:57] into some other array. Uh and then from +[2:36:00] that you either directly have the keys +[2:36:02] and values in there or you have a way of +[2:36:04] determining what the keys and values +[2:36:05] are. Um, +[2:36:08] and +[2:36:10] I guess I guess the first way of +[2:36:14] explaining how you could keep that +[2:36:16] stable would just be to slap it onto a +[2:36:18] ZAR. And um, rather than the index being +[2:36:22] a direct kind of um, modulo offset into +[2:36:27] that, it's a it's kind of like a +[2:36:30] virtualized, it's just the regular +[2:36:31] index, but into the ZAR. Um +[2:36:36] the +[2:36:40] uh the the difficulty then comes from +[2:36:44] when you grow the array, you need to +[2:36:45] rehash things. +[2:36:47] Um +[2:36:49] and but okay, as we've all learned, +[2:36:54] right, +[2:36:56] powers of two are loved by computers and +[2:36:59] so they're loved by you. Yes. +[2:37:02] Um so we have our our all of our hash +[2:37:06] blocks are powers of two. Um which means +[2:37:10] that an index into into that is using an +[2:37:13] exact number of bits. And so when when +[2:37:17] we grow our +[2:37:19] hash table and by what power do we grow +[2:37:21] our hash table? We double it. Yes. Um +[2:37:25] excuse me. +[2:37:27] uh when we double the size of our hash +[2:37:29] table, we now have effectively one extra +[2:37:32] bit at the beginning of our index. And +[2:37:35] so the possible solution that we were +[2:37:39] discussing for a linear probing hasht is +[2:37:43] that you can scan from the beginning of +[2:37:45] your block. Um and then each time you +[2:37:47] hit something, you know whether or not +[2:37:50] it there's only two options. It's either +[2:37:52] going to stay stay where it is asterisk +[2:37:56] or go to the um the equivalent like the +[2:38:01] same offset but in the other second +[2:38:02] chunk of the the next chunk across. Um +[2:38:07] okay that asterisk +[2:38:09] is to do with collisions as it always is +[2:38:11] with hash tables. Um, and +[2:38:16] yeah, I mean there's there's some +[2:38:17] implementation of details you work out +[2:38:19] there that if having not implemented it, +[2:38:22] it seems like you could um effectively +[2:38:26] remove an element each time you move it +[2:38:28] and then everything else would shift +[2:38:30] back into place. And if you removed it, +[2:38:31] you don't move forward. You just look at +[2:38:33] the same place again until you've gone +[2:38:34] all the way through. Um +[2:38:37] there might be a slightly smarter way of +[2:38:40] doing it that skips some of that work +[2:38:42] but um I don't have any confident +[2:38:45] statements on that. +[2:38:47] Uh +[2:38:53] and then the other way is to do you +[2:38:57] mentioned with the like hash array map +[2:38:58] tree where then all of the nodes are you +[2:39:03] have a bunch of nodes but where where +[2:39:04] your base data is stable and then +[2:39:06] actually your intermediate nodes are +[2:39:08] stable as well um but you +[2:39:11] um you have your login accesses into +[2:39:13] into the various endpoints and I think +[2:39:15] that's how like C++ ++ is +[2:39:19] ordered map or un unordered map works. +[2:39:22] Um, +[2:39:23] which I don't know why I know because +[2:39:26] well I I don't have to deal with it. So +[2:39:29] yeah um +[2:39:50] Yeah. Um the other the other thing you +[2:39:53] could do is +[2:39:56] um +[2:39:59] yeah so you have more options that you +[2:40:01] can if you keep your you don't have to +[2:40:04] have the same structure for your uh your +[2:40:08] slots your bucket pointers as your +[2:40:10] actual key value data. +[2:40:12] Um, so you could have your key value +[2:40:15] data in what whatever +[2:40:18] uh storage you like. Like if you don't +[2:40:21] need to iterate it, you can just put it +[2:40:22] wherever in the arena. Um, or you can do +[2:40:25] like trunking lists or one of those +[2:40:27] other um +[2:40:31] one of those other collection +[2:40:33] structures. Uh, and then your slots can +[2:40:37] go +[2:40:39] uh you can either just leak the old ones +[2:40:41] each time and double or you can have +[2:40:43] like power of two pools within your +[2:40:45] arena and free it from one that goes on +[2:40:48] the free list for like size eight and +[2:40:50] then you have a new one of size 16. +[2:40:53] Well, you do that after copying the +[2:40:55] things over after rehashing the things +[2:40:57] over. Um, +[2:41:03] >> yeah, I think there were some other +[2:41:04] options, but they have slipped my mind. +[2:41:08] All right, this will be my last +[2:41:09] question. Um, how much of this talk do +[2:41:12] you think applies to C or C++ and how +[2:41:15] much of it applies to all languages? In +[2:41:17] other words, can I tell my JavaScript +[2:41:18] friend that he should watch this talk +[2:41:20] and follow the the advice? +[2:41:24] So, first of all, um +[2:41:31] I mean the the slightly glib answer is +[2:41:33] that +[2:41:35] if you're doing things like the +[2:41:38] um +[2:41:40] treating your value as a very small like +[2:41:44] 32 element set or other things like +[2:41:48] that, then you you do still get that win +[2:41:50] of it becoming one operation. +[2:41:53] rather than a loop of operations or some +[2:41:56] other more complex system of operations. +[2:41:58] Um +[2:42:00] and +[2:42:05] but but yeah, so the other side of it is +[2:42:07] like +[2:42:09] C, C++, other systems programming +[2:42:11] languages. +[2:42:13] um you're running on an actual computer +[2:42:16] and they have this these instructions +[2:42:18] baked in as like fundamental operations. +[2:42:23] Um, and while +[2:42:26] I think most scripting languages have +[2:42:29] them, um, you're kind of still going +[2:42:33] through all of the indirection of any +[2:42:35] other operator and a lot of the +[2:42:39] you know, +[2:42:40] like previously we kind of compared the +[2:42:43] latency of a an imole to an AD and I'm +[2:42:48] pretty sure that the the speed +[2:42:50] difference between those two +[2:42:51] instructions is completely dominated by +[2:42:53] the the VM on other languages. Although +[2:42:56] I guess having said that like V8 is +[2:42:59] pretty impressive at turning turning +[2:43:01] things into machine code if you can +[2:43:03] structure your data in a way that it can +[2:43:06] know to jip the machine code and not do +[2:43:08] the generic VM thing. +[2:43:10] >> Yeah, I imagine there's still quite a +[2:43:11] bit of compile time uh analysis and +[2:43:14] optimizations what can that can apply. +[2:43:16] But there's I don't know, maybe this is +[2:43:19] just because I don't really live in that +[2:43:21] world, but there's a lot of +[2:43:24] blackbox magic in the V8 compiler. Um, +[2:43:28] and I don't know I know there's magic in +[2:43:30] regular compilers kind of. Uh, but +[2:43:34] the kinds of changes that you're going +[2:43:37] to get are are kind of +[2:43:41] Oh, no. I'm I'm going to say they're +[2:43:42] more predictable, but that's like that's +[2:43:43] going to open up a whole can of worms. +[2:43:45] Listen, that's a bad idea. +[2:43:49] >> I think that will we'll call it there. +[2:43:51] Thank you so much. Another round of +[2:43:52] applause for Andrew Reese. \ No newline at end of file diff --git a/docs/transcripts/wo84LFzx5nI_big_oops_casemuratori.txt b/docs/transcripts/wo84LFzx5nI_big_oops_casemuratori.txt new file mode 100644 index 00000000..623bc27e --- /dev/null +++ b/docs/transcripts/wo84LFzx5nI_big_oops_casemuratori.txt @@ -0,0 +1,4320 @@ +# wo84LFzx5nI transcript +# Source: https://www.youtube.com/watch?v=wo84LFzx5nI +# Title: The Big OOPs: Anatomy of a Thirty-Five-Year Mistake +# Speaker: Casey Muratori +# Conference: BSC 2025 (Better Software Conference) +# Fetched: 2026-06-08 +# Segments: 4310 + +--- + +[00:00] Please join me in welcoming the one, the +[00:02] only, the irreplaceable Casey Muradori. +[00:19] Okay. Okay. Way too big. Sam Sam made it +[00:22] way too big. I feel like before we +[00:25] start, we should also thank Sam for +[00:26] putting this together. +[00:33] Uh it's been a very long time since I've +[00:34] been really excited to give a talk and +[00:36] uh a lot of that is because the the the +[00:39] speaker list of this talk is is of this +[00:41] conference is absolutely amazing and I +[00:43] just I don't know I'm I'm really excited +[00:45] to be here and I'm excited to give this +[00:46] talk. So I'm just going to jump right +[00:47] into it. So, I would like to talk about +[00:50] something that happened in 1998 at a +[00:52] company called Looking Glass, which +[00:53] normally like back in the day, +[00:55] contemporaneous with this, if I had said +[00:57] Looking Glass, everyone would know who +[00:58] they were because they were incredibly +[01:00] influential game company that did a lot +[01:02] of uh firsts in gaming. Uh, one of their +[01:05] games, Ultimate Underworld, started kind +[01:07] of the 3D revolution in, you know, PC +[01:09] gaming. And they they were incredibly +[01:11] like innovative company at the time. And +[01:13] a lot of people today, I mean, there's +[01:15] people in the audience here who weren't +[01:16] even born then, right? So, a lot of +[01:18] people they might not know who they +[01:19] were, but they were incredibly +[01:20] important. And one of their games uh was +[01:22] called Thief: The Dark Project. And it's +[01:24] a franchise that lived on. It was one of +[01:26] the first sort of stealth action games. +[01:29] And it looks pretty primitive by today's +[01:31] standards, obviously, but this was a +[01:33] engine contemporaneous with things like +[01:35] Quake, for example. So, this was sort of +[01:37] state-of-the-art at the time. Now, I'm +[01:40] not going to talk about graphics because +[01:41] I'm not qualified to talk about graphics +[01:43] anyway. I'm not a graphics guy. What I +[01:45] want to talk about instead is how they +[01:46] modeled entities. And normally the way +[01:50] you would do things in games at this +[01:51] time and in fact the way that Ultimate +[01:53] Underworld 1 and two and then later +[01:54] System Shock was another one of their +[01:56] games. The way that they did things was +[01:57] actually the way that like uh me and for +[02:00] example Ryan Flurry who's going to be +[02:01] interviewing you after we would say that +[02:02] this is a good way to do things even +[02:04] today. They were sort of fatrus if you +[02:06] will. They just put everything in one +[02:08] structure and when you were going to do +[02:10] things like have different types of +[02:11] entities really all you had was some +[02:13] kind of a type field in there or flags +[02:15] or things like that that would let you +[02:16] know what you were supposed to do with +[02:17] it. But you know these were very very +[02:20] limited resource times. I think the +[02:21] systems uh you know you would expect to +[02:23] have something like 2 megabytes of +[02:25] memory or something total to run in. So +[02:27] you're talking about fixed blocks of +[02:28] small size and everything has to work in +[02:29] that. So that's just what you did +[02:31] because that's what worked. And in this +[02:34] time frame, right? You know, during the +[02:36] 80s and then later 90s when this game +[02:38] was made, this is the sort of thing that +[02:39] was in vogue in like the architecture +[02:41] world. This is nothing to do with how +[02:43] they were doing things at looking glass. +[02:44] This is what we would kind of think of +[02:47] as a normal like oop programming model +[02:48] now where you have a hierarchy of things +[02:50] like there's an entity class and then +[02:52] you have an NPC and item subclass +[02:54] derived from it and then things below +[02:56] that and so on. And that was not +[02:58] something that Looking Glass had ever +[03:00] really used in that lineage of games in +[03:02] their RPGs. And they decided not to go +[03:05] that route even though that was sort of +[03:07] what was in vogue at the time. That was +[03:09] what was uh you would have seen pushed +[03:10] if you were reading like architecture +[03:12] things in oops law or you know the kinds +[03:14] of papers that would have been published +[03:15] on software architecture. So they did +[03:18] something very different. What they did +[03:20] is said look we want all of our systems +[03:23] to be the primary thing that we're going +[03:25] to think about. We want to think about +[03:26] physics and combat and those sorts of +[03:28] things. The same things that were in our +[03:30] fatty strus when we do a more serious +[03:33] architecture here doing more +[03:34] architectural work. We want to put +[03:36] things in terms of their system not in +[03:39] terms of the entity. And so what they +[03:41] did is they came up with a system where +[03:43] they would use an ID. Like if I have a +[03:45] particular object that I'm trying to +[03:47] model in the world, one of these +[03:48] entities, I just have an ID for it and +[03:50] it doesn't really have any data +[03:52] associated with it at all. It's kind of +[03:53] the polar opposite of a fat strct. So +[03:56] they would just say we're going to use +[03:57] the ids to represent things and then the +[03:59] way that we form the entity's data is we +[04:02] just use that ID to look up into a +[04:05] system and say what's the physics like +[04:07] for this thing? What's the combat like +[04:08] for this thing? This fuel system I have +[04:10] or I'm just imagining systems you might +[04:11] have in a game. And in so doing, in 1998 +[04:16] when they shipped Thief the dark +[04:17] project, they shipped to the best of my +[04:19] knowledge the first instance of an +[04:21] actually commercially released entity +[04:23] component system. That's what we call it +[04:25] today, right? People call it this. Uh +[04:27] this is now in an invogue architecture +[04:29] in much the way that those hierarchy +[04:31] kinds of architectures were in vogue at +[04:32] the time and still to some extent are in +[04:34] today, but not necessarily in the game +[04:35] industry. So, this is the first time I'm +[04:38] ever aware of anyone shipping this kind +[04:40] of model. And in fact, it's the first +[04:41] time I'm aware of anyone even talking +[04:42] about this kind of model. I'd never +[04:44] heard of it before. This was the first +[04:45] time. And there's a a pretty interesting +[04:48] thing that you have to understand about +[04:50] this. And I know this may seem like +[04:51] beating a bit of a dead horse here, but +[04:54] those red lines that I've drawn there +[04:56] are basically encapsulation boundaries. +[04:57] And this is a very important theme +[04:58] throughout this talk. I just want to +[05:00] really make sure I hammer it home. +[05:02] Encapsulation boundaries are really what +[05:03] we care about when we're doing +[05:04] architecture. What we care about is +[05:06] where we make it difficult to access +[05:08] things and where we make it easy, right? +[05:11] And so what they chose to do that was +[05:13] very different than that sort of +[05:15] inheritance hierarchy model is they +[05:16] chose to draw the encapsulation +[05:18] boundaries around the systems. Now this +[05:21] is very different because the +[05:22] traditional oop model, right, is you +[05:24] draw the encapsulation boundaries around +[05:26] the objects. So the encapsulation +[05:29] boundary in a normal oop like hierarchy +[05:31] is I have whatever the object is like a +[05:33] mech and the encapsulation boundary is +[05:35] around all of the things that the mech +[05:37] knows about. But that's very different +[05:39] than this. This is about all of the +[05:41] things that are related to a system not +[05:43] all the things that are related to a +[05:45] mech. Now it's important to remember +[05:47] this is not like not oop you could +[05:50] easily call this object-oriented +[05:51] programming. It still obeys a lot of the +[05:53] principles you might recognize from +[05:54] object. It's not like they were saying +[05:56] we're getting rid of object-oriented +[05:57] programming. They were saying something +[05:59] very different. And they were saying +[06:00] effectively what Mark Blank said, he's +[06:03] the person who actually uh implemented a +[06:06] lot of the system. And what he said was +[06:08] for some reason oop has gotten into this +[06:10] mindset of compile time hierarchies that +[06:13] match the domain model. Meaning, if you +[06:15] think about what you're trying to model +[06:16] in the real world, like entities and +[06:18] guards and things like this, or even if +[06:20] you're just thinking like the natural +[06:21] world, we're going to think about, you +[06:23] know, birds and are they, you know, is +[06:25] it a mammal or is it an aven thing, +[06:27] right? You're thinking about this domain +[06:29] model that you're trying to model in the +[06:30] real world and you're bringing it into +[06:31] the software world. And what he was +[06:34] saying is like why are we pushing this? +[06:36] Why is that the idea, right? And he says +[06:39] we can still do oop style stuff and we +[06:41] can just do it by changing our paradigm +[06:43] of what we're thinking about in terms of +[06:45] our domain model, right? Don't don't +[06:47] make the domain model be in the code. +[06:49] Make that be something the user +[06:50] experiences, but the code is done in a +[06:52] way that makes sense for the code. So +[06:55] this is really brilliant and it's a +[06:56] great way to summarize it. It's one of +[06:57] my favorite crystallizations of that +[07:00] concept. So I would only add one thing +[07:03] to it and that's that word encapsulation +[07:05] because I think sometimes people think +[07:06] hierarchy they just think the +[07:07] relationships but it's the encapsulation +[07:09] that's really important because that's +[07:11] what really determines whether or not +[07:12] the code is easy to write or hard to +[07:13] write. It's are those boundaries in the +[07:15] right place. So this is crucial and this +[07:21] talk is kind of about mistakes as you'll +[07:23] see and I made a mistake one time. I +[07:26] went on this thing uh you may have seen +[07:28] it. It's called the internet. It's like +[07:30] this series of tubes that connects +[07:31] people around the world. And it's it's +[07:33] kind of complicated. I'm not 100% sure +[07:35] how it works, but they have a thing on +[07:36] it called social media where what you +[07:38] can do is there's like a box and you can +[07:40] type anything you want into the box. It +[07:41] doesn't have to be correct. It could be +[07:43] it doesn't have to be coherent. It +[07:44] certainly doesn't have to be polite. And +[07:46] then you have to push this button. +[07:47] There's usually a button next to it, but +[07:48] the button says different things +[07:49] sometimes. You push the button and +[07:51] everyone in the world has to read it. +[07:52] Like everybody. +[07:54] And that's an amazing invention. And I +[07:55] was probably doing something like that +[07:57] at the time when I saw uh some people +[08:00] talking you having a discussion about +[08:01] this sort of thing discussion in quotes +[08:03] let's say +[08:04] and they were thinking about this they +[08:06] were thinking about you know we you know +[08:08] we have old old things that were like +[08:09] maybe not quite architecture like those +[08:11] fatty strus things and at some point +[08:13] people started saying you know there's +[08:14] this other architecture we could do +[08:16] which is this hierarchy thing and that's +[08:17] like much you know cleaner it's much +[08:19] better organized it's better +[08:20] architecture and they started to push +[08:22] this right and it definitely got adopted +[08:24] got adopted everywhere and it's a very +[08:27] standard paradigm even to this day and +[08:29] they were they were sort of responding +[08:30] to people who are saying this is bad +[08:32] that this hierarchical thing is not a +[08:34] good idea the capsulation boundaries are +[08:35] in the wrong place as I would say and +[08:38] they're saying okay there's no way that +[08:41] all of these smart people who pushed +[08:43] this stuff and who created this there's +[08:44] no way they could possibly be wrong +[08:46] about it right like surely this comes +[08:48] from all kinds of like academic studies +[08:50] and ways of looking at things and we've +[08:52] we definitely have great examples of +[08:54] this working perfectly, I'm sure, and it +[08:56] all got translated to us and you guys +[08:58] just don't understand. And you know, we +[09:00] don't understand either because we're +[09:00] not really sure what we're saying, but +[09:02] we're basically saying that someone must +[09:03] have known and those people were smart. +[09:05] So there you go. Right? So could you +[09:08] really be saying all you naysayers that +[09:12] it it it doesn't make sense. It didn't +[09:13] come from a logical place. And so the +[09:16] short answer to that is absolutely +[09:18] that's what we're saying. That's 100% +[09:20] what we're saying. And the long answer +[09:22] to this is the rest of this talk. +[09:25] Welcome to the Better Software +[09:26] Conference, the inaugural Better +[09:28] Software Conference. This is the big +[09:30] oops, which is my sort of attempt to go +[09:32] back over 35 years of history +[09:36] to figure out where we went wrong like +[09:39] how did this happen? Okay, now just get +[09:43] some things out of the way first. And +[09:44] this is mostly for the people I don't +[09:46] know where I'm looking. Is there a +[09:47] camera out there? That this is mostly +[09:49] for the people. The people in this room +[09:50] are probably already bought in, right? +[09:52] Low-level programming, that sort of +[09:54] thing. You're probably like, "Okay, I +[09:55] like where this is going." People on the +[09:57] internet, as I said before, you know, +[09:59] maybe that was a mistake, but they're +[10:00] going to have some some uh some issues +[10:02] with some bones to pick. So, I just want +[10:04] to say first, when I say the big oops +[10:07] anatomy of a 35-y year mistake, I'm not +[10:10] talking about uh OOP as a whole. I'm +[10:12] talking about looking for very specific +[10:14] things in it. Okay? And because whenever +[10:17] you talk about oop, it's always this +[10:18] thing where people feel like, well, +[10:19] whatever you're talking about, like +[10:20] that's not really OOP. Like you're +[10:22] you're talking about the things you're +[10:23] using the terminology wrong or that's +[10:24] not how I write code. It's like oop is +[10:25] just a thing where it's like it's how I +[10:27] like to write code and whatever they're +[10:29] thinking at the time, that's what OP is +[10:31] or something. And and I don't +[10:32] necessarily blame them because it's a +[10:33] nebulous term and they have their own +[10:34] definition for I mean I probably have my +[10:35] own definition for that's totally fair, +[10:37] right? But I just want to say we're not +[10:39] going to be dealing with any of that +[10:40] here. So, I don't want to hear the the +[10:42] whole like, you know, I don't know. It's +[10:44] sort of like like wine, which I got the +[10:45] slide up in here. It's like you if you +[10:46] have like a designated origin, you +[10:48] you're not allowed to call it certain +[10:49] things. And it's like it's that kind of +[10:50] feel, right? It's not like it's like +[10:52] it's not actually oop, it's sparkling +[10:53] code or something like this. You have to +[10:55] use the right term for it. So, I just +[10:57] want to be clear. I'm talking about +[10:58] something very specific. And it's the +[10:59] thing that I just said, very, very +[11:01] specific. And I'm not saying it was a +[11:02] mistake. I'm saying this was a mistake. +[11:05] the idea that you're going to draw +[11:06] encapsulation boundaries around these +[11:08] compile time hierarchies that are based +[11:10] off of whatever you're trying to write. +[11:12] Now, second thing we want to get clear +[11:15] is I don't want to hear any complaints +[11:18] that no one ever pushed this model +[11:20] because I know that's going to happen. +[11:22] I'm looking at UI Combinator. I know +[11:24] that this is going to be a threat. So, +[11:27] anticipating that, let's just say we +[11:30] have a lot of historical evidence. When +[11:31] I was doing the research for this talk, +[11:33] I read so many things from the +[11:35] historical record. It is so obvious that +[11:38] everyone actually 100% meant you should +[11:41] look at the domain model and you should +[11:42] code that directly into compile +[11:44] hierarchy. For example, here is +[11:47] literally Bjarn Strus's paper. What is +[11:50] object-oriented programming to tell you +[11:52] what it is? +[11:54] And he starts off with a shape example +[11:56] that I've used before that everyone +[11:58] said, well, that's totally ridiculous. +[11:59] you're just cherry-picking out of an +[12:00] introductory book. It's like this is +[12:02] where he was trying to explain this and +[12:04] sell this to people in his industry who +[12:06] were experts. +[12:08] And he says, look, if we're going to +[12:09] write something like this that has, you +[12:11] know, kind k is an enumerate there of +[12:12] like what the kinds of shapes are, +[12:14] right? If we're going to write something +[12:16] like this, we end up with code that has +[12:17] a switch statement in it. So we want to +[12:19] draw something, we have to say, oh, what +[12:20] what is this? And I have to say, okay, +[12:22] case circle, case triangle, and have the +[12:23] different drawings for that. And he's +[12:25] like, this is a mess. You you can never +[12:27] do something like that. Instead, what +[12:29] you want to do is make a hierarchy where +[12:31] it matches the domain model. I've got a +[12:33] shape class and then he deres from it +[12:34] the triangle class and has a virtual +[12:36] function and all those sorts of things. +[12:37] This is right in the first papers where +[12:40] people are selling this concept in +[12:42] certain programming languages, right? +[12:44] And I guess I should also point out that +[12:47] he says things like when we're talking +[12:49] about objective programming, literally +[12:50] what we're talking about is inheritance +[12:52] hierarchies with virtual function calls. +[12:54] like he says that and he says object +[12:57] programming is programming using +[12:58] inheritance so hammering home that this +[13:01] is literally what we are talking about +[13:02] there's so much evidence and I'm just +[13:04] picking one paper now a lot of people +[13:06] will talk about say Alan K because he +[13:09] was a big father of a compar he's the +[13:11] one who coined the term as far as anyone +[13:12] knows +[13:14] uh and he talks about you know uh this +[13:17] this sort of idea that oop only means +[13:19] like messaging and a few other things +[13:21] right he's said this and so some people +[13:23] might be like well That's what object +[13:24] programming was really about. No one was +[13:26] ever pushing it. And and you know, +[13:27] Jerus, okay, whatever. C++ is terrible. +[13:29] Like he that don't listen to that guy, +[13:31] right? Despite the fact that he made the +[13:32] language that's like one of the most +[13:33] prevalent, it's the one that we all use +[13:35] mostly or at least have for the past 20 +[13:37] years. And so this this is the truth. +[13:40] This is the actual truth here. It's +[13:41] like, yeah, he said that in 2003, right? +[13:44] He said that after a very long time. So +[13:47] why did he say it? It's because 10 years +[13:49] earlier, he was already saying he kind +[13:51] of soured on it. He's like, "Inheritance +[13:52] was like really powerful, but people +[13:54] just didn't know how to use it. Novices +[13:56] and experts apparently both couldn't use +[13:58] it, right? It was just uh you know, it's +[14:00] really good, but no one can figure out +[14:02] how to use it, I guess. Uh so that's a +[14:04] little bit weird. I don't know. Maybe +[14:05] Alan K, he still comments on stuff. +[14:07] Maybe he'll come to tell us what he +[14:08] actually was trying to say there +[14:10] exactly. But if you go back earlier, +[14:12] because small talk is a lot earlier that +[14:13] if you go back look at what they were +[14:14] actually talking about when they were +[14:15] talking about small talk in the times +[14:17] before they had chance to reflect and +[14:19] say that it didn't work." Well, here's +[14:21] what they were saying. Inheritance +[14:22] programming shows the power of +[14:24] differential description, right? They're +[14:25] like, you can take an object and I can +[14:27] say like, I'm going to start with +[14:28] completely undifferiated object and then +[14:30] I'm going to derive a rectangle. I'm +[14:31] going to drive drive drive. And in fact, +[14:32] here is a diagram from one of his +[14:34] articles talking about like cool things, +[14:36] computer architecture. He's like, we can +[14:38] have a generic object and then we can +[14:40] drive from that a rectangle and we'll +[14:41] drive a window and a painted window and +[14:43] a browser. Look, everyone is talking +[14:46] about literally representing in the +[14:49] hierarchy what your domain model is. +[14:51] That's what they're talking about. And +[14:53] if you need further proof, look at +[14:54] what's actually in small talk. We have +[14:56] all the data like for this all of the +[14:58] papers exist. Here is an example from +[15:01] the art and science of small talk where +[15:02] they're talking about some stuff that's +[15:04] needed to adapt values like I want to +[15:06] convert values between things and you +[15:08] know actually exchange values between +[15:09] objects and stuff like this. And here's +[15:11] just a hierarchy that they drew of stuff +[15:13] that they were using for implementation. +[15:15] That's the hierarchy, right? And if you +[15:17] look, it actually says, well, it's only +[15:20] part of the hierarchy for this thing +[15:21] cuz, you know, like we couldn't fit it +[15:22] on the diagram we had so many classes we +[15:25] were inheriting here, right? And guess +[15:27] what? If you liked the shape example +[15:29] that keeps coming up that everyone says, +[15:31] well, no one would ever actually suggest +[15:33] that you use this sort of ridiculous +[15:35] shape example. You know, you're just +[15:36] cherry-picking. Except it exists +[15:38] absolutely everywhere. It's in small +[15:40] talk. There it is. They have a path +[15:42] class and from that path class they have +[15:44] different shapes derived from it. That's +[15:46] what this the path looks like. That's in +[15:48] the base language of small talk that +[15:51] Allen K and uh Robson shipped and Adele +[15:53] Goldberg was the person who documented +[15:54] it. These are the original authors of +[15:57] small talk. Right? And if you don't want +[15:59] to take my word for all of that, you can +[16:01] take Bjarn's word for it. He criticizes +[16:05] small talk for being all about +[16:06] inheritance. that that's all it was and +[16:09] you had to actually use it to get +[16:10] anything done in that language, right? +[16:12] And he's actually saying C++ at least +[16:14] doesn't make you do it that way. You +[16:16] only have to do it that way when you +[16:17] think it's a good idea, right? Which by +[16:19] the way, I agree with him on that. +[16:20] That's why we were able that's why I'm +[16:22] still able to use C++ to this day is +[16:23] because Bjan Stra was actually really +[16:25] smart about a lot of things and he +[16:27] didn't try to force you to do things +[16:28] only his way where Small Thought kind of +[16:30] did. +[16:32] All right. So, now that we've got that +[16:34] out of the the way, let's talk about the +[16:36] origin story for this guy right here who +[16:38] has caused me so much pain. And you +[16:41] know, I won't go into it. Anyway, let's +[16:43] talk about the origin story. So we'll +[16:45] start uh with C++ because obviously +[16:48] that's the most impactful language that +[16:50] really promulgated this inheritance +[16:52] hierarchy concept out to the world in a +[16:54] way that we all kind of experienced not +[16:57] only in programming C++ but obviously +[16:59] languages like Java which are incredibly +[17:01] prevalent in not exactly our circles +[17:03] maybe but obviously in business world +[17:05] and that sort of thing. So it's it's not +[17:07] even just C++ it's like the knock-on +[17:09] effects of C++ also. So this is really +[17:11] really important uh as an entry into +[17:13] where this came from. Let's start in +[17:15] 1978 and looking at that and uh Bjnusup +[17:18] is actually in the uh he's in university +[17:21] at this point. He he hasn't actually +[17:22] gotten to Bell Laboratories where he +[17:24] would do uh the later work on C++. +[17:26] So he is working on his PhD thesis. And +[17:29] again as I'm going through the +[17:31] historical record here I really want to +[17:32] try and give you a mindset of what the +[17:36] people were thinking as far as I could +[17:37] get it from their writings. Right? I +[17:39] went only through primary sources for +[17:41] this and I tried to figure out what were +[17:43] these people feeling like what were they +[17:44] doing when they were coding and so he is +[17:47] actually working on distributed systems +[17:49] he's not a languages guy he's not there +[17:51] like researching languages or anything +[17:53] like that he's working on distributed +[17:54] systems and what he wants to know is +[17:57] look we've got some stuff where we want +[18:00] to know about hardware protection like +[18:02] you know if you kind of think of virtual +[18:03] memory or things like that where you +[18:04] have hardware features uh that are +[18:06] designed to protect different parts of +[18:08] your program from other different parts +[18:10] of your program or different processes +[18:11] from each other or different nodes in a +[18:13] system all those sorts of things. So +[18:14] he's doing distributed architecture work +[18:16] and what he wants to do is run +[18:18] simulations because at the time again +[18:20] putting you in the mindset of where we +[18:21] are in computer history you don't just +[18:23] have computers lying around like we do +[18:25] today right it's not like oh I can just +[18:26] buy a bunch of computers and set up a +[18:28] network and do testing on it's like no +[18:30] there's no way he was going to get +[18:31] things like a distributed multiprocessor +[18:33] system to just play around on in 1978 +[18:35] unless he was extremely important in +[18:37] working for the military or something +[18:38] like that right +[18:40] so what he had to do was write a +[18:41] simulator and what he decided to to to +[18:44] write the simulator because earlier in +[18:46] his career he had well he'd been in +[18:48] university I guess early his education I +[18:49] should say he had been at university and +[18:51] he learned uh from a person named +[18:53] Kristen Nygard who was actually one of +[18:54] the creators of simula he learned the +[18:56] language simula directly from one of its +[18:59] authors basically like he he was +[19:00] actually there at the time uh when the +[19:03] author was also there and this this was +[19:05] how he knew what simula was and how to +[19:06] use it and so what he did was he wrote a +[19:09] simulator for distributed systems in +[19:11] simula which is kind of exactly what +[19:13] it's designed for, right? It's a +[19:14] simulation language. And he had a great +[19:17] time doing it. He was like, "This was so +[19:19] much better than what I'm used to. I +[19:21] really liked the experience of writing +[19:23] that." So, he ended up with this thing +[19:25] where he had like little programs that +[19:26] were simulating what was happening in a +[19:28] distributed network uh or distributed +[19:30] system, I should say, not necessarily on +[19:31] a network. And he found that it was +[19:33] really easy to debug the little programs +[19:34] by themselves. And the language made it +[19:36] really easy to do that. Now, again, it's +[19:38] important to remember keeping all this +[19:39] in your head if you can. I know it's a +[19:41] lot. Uh it was it was a lot of reading, +[19:42] right? So I'm trying to convey it to you +[19:44] in in case possible just pointing out +[19:46] it's important to remember that that's +[19:48] the domain model he was working with is +[19:50] lots of little programs that were +[19:51] talking to each other right +[19:53] so anyway he says that the class concept +[19:55] the simula had because it had the same +[19:57] sort of idea of a class as C++ would +[19:59] later have he said that that class +[20:02] concept that simula had was really good +[20:06] for direct mapping right remember I said +[20:09] compile time hierarchy that exactly +[20:11] models the the domain right? He said +[20:13] that was working really well when he was +[20:15] implementing. He was just saying, "Oh, +[20:17] this is the thing I'm trying to simulate +[20:18] and so I'm literally going to create +[20:20] classes in Simula that model that +[20:22] directly." And that was working really +[20:23] well for him in Simula. And you know, we +[20:25] can kind of start to see how this is +[20:27] breaking down. He happens to be working +[20:29] on something that is literally a domain +[20:32] model of things that are encapsulated. +[20:34] The computers can't talk to each other. +[20:36] The different processes in the computer +[20:38] can't talk to each other. It's an exact +[20:40] fit for what a class actually does. This +[20:44] is important to remember. Okay, so we +[20:47] used hierarchies for this, right? They +[20:49] weren't necessarily particularly deep, +[20:50] but they were the kind of thing where +[20:51] it's like, I have a computer. I derive +[20:52] different things from the computer, and +[20:54] those things are just kind of +[20:55] self-contained. And he had a really +[20:56] great time doing this. Again, he said +[20:58] very positive things about it. And one +[21:00] of the things that he really liked was +[21:02] the fact that the type system, when you +[21:04] had these hierarchies, that type system +[21:06] would catch errors for you. Exactly the +[21:07] kind of thing that we maybe take for +[21:09] granted today because most languages +[21:11] even JavaScript now has like TypeScript, +[21:13] right? Most things that we work with +[21:14] today have the ability for you to do +[21:16] this kind of type checking that catches +[21:17] a lot of errors at compile time. That +[21:19] was relatively new at the time. And I +[21:21] don't mean new in the terms of like no +[21:23] one had ever thought about it before, +[21:24] but I just mean a lot of languages you +[21:26] might be using at this time still had +[21:27] very weak type systems. And in fact, +[21:30] Struestrip complains directly when he's +[21:32] talking about this that using Pascal +[21:34] kind of sucked and he didn't really like +[21:36] it because the type system didn't work +[21:38] very well for expressing things and for +[21:40] catching errors. He felt it was kind of +[21:42] more trouble than it was worth. So that +[21:45] forms his basis for this idea that +[21:48] classes are really good and typeecking +[21:50] on classes is really good, right? And +[21:53] you know just to split those down the +[21:54] middle, I do think the type-checking +[21:56] part is pretty good. maybe the class +[21:57] part or rather the hierarchy part that +[21:59] I'm like a little bit suspicious of, +[22:00] right? But at least half of it I'm with +[22:02] him on already even. Okay, so that's +[22:06] sort of what you will see if you read +[22:09] the Wikipedia or something, right? +[22:10] That's the simple part and they often +[22:12] leave a lot of stuff out. So I thought +[22:14] because this is the better software +[22:16] conference I would include a much more +[22:18] interesting aspect of this story because +[22:20] you would think if you saw a thing +[22:21] that's like hey uh what happened was +[22:24] Bjnestrip was doing stuff with +[22:26] distributed systems and he wrote this +[22:27] thing in simula and it was a great time +[22:29] and so he decided to do when he got to +[22:31] Bell Labs was make C++ and it it would +[22:34] just have you know the classes in it +[22:35] from Simula. It was great. No. So what +[22:38] actually happened was +[22:41] the entire thing completely rolled over +[22:43] and died. He tried to run the simul +[22:46] program and he had all sorts of problems +[22:49] with it and it started even before he +[22:51] tried to run the simulate programs that +[22:53] he was writing. What actually happened +[22:55] is first he hit the same things we hit +[22:57] with C++ today. Build times were through +[23:00] the roof and it was almost impossible to +[23:03] make changes to the program. So much so, +[23:06] and I'm going to let this sink in for a +[23:07] second because it's really awesome. So +[23:09] much so +[23:12] I I mean, I almost want you to read it. +[23:17] If you compiled 130th of the program and +[23:19] tried to link it, it was slower than +[23:21] just recompiling the entire thing. Okay, +[23:25] let that sink in because it means that +[23:27] that Bja was talking about Unity builds +[23:32] in 1994. He was like, "We can speed this +[23:35] up by not doing incremental." +[23:37] Incremental builds sucked that long ago. +[23:41] Anyway, +[23:43] but I digress. +[23:45] Anyway, the runtime also was lousy. He +[23:48] couldn't get the thing to run fast +[23:49] enough because Simulo was extremely +[23:51] slow. Anyone want to guess why it's +[23:53] slow? It's a rhetorical question. I'm +[23:54] going to tell you why it's slow. It was +[23:55] so because the garbage collector, same +[23:57] reason things are slow today half the +[23:59] time. The garbage collector was taking +[24:01] any 80% of the runtime apparently even +[24:03] though there was no actual garbage that +[24:04] needed to be collected because you know +[24:06] I guess at that time garbage collection +[24:07] was even you know very very primitive +[24:09] obviously so it's probably running all +[24:10] the time just to see if there was any +[24:12] garbage and it was like +[24:15] yeah nope no garbage and that was +[24:16] happening a lot so 80% of the time so he +[24:18] had he had the experience with simula +[24:20] that we have with C++ like it is the +[24:22] chain continues right uh the garbage +[24:25] collection obviously not so much so +[24:27] that's what happened he had to rewrite +[24:28] the whole thing from scratch in a +[24:30] different language called BCPL which has +[24:32] no type checking whatsoever. +[24:35] I mean that's not entirely true. It has +[24:36] very very minimal but none of those +[24:38] class things and that sort of thing. So +[24:40] that's the actual story of what +[24:41] happened. So it's kind of interesting. +[24:43] It precages everything, right? It kind +[24:44] of the whole thing is almost like a +[24:45] microcosm. So if we reflect on this for +[24:48] a second again I think I've tried to +[24:49] highlight the important points there but +[24:51] the other thing to remember is a lot of +[24:52] people talk about these things. They +[24:54] talk about those compile time +[24:55] hierarchies and all that sort of stuff +[24:56] and they say like, you know, +[24:59] here's the thing that you just don't +[25:01] understand. It's all about large teams. +[25:04] You know, it's all about these large +[25:05] teams. It's just that you got to have +[25:07] large teams. And if you had large teams, +[25:09] then you would understand the magic of +[25:12] the compile time hierarchy stuff and the +[25:14] encapsulation. It's amazing, right? +[25:17] How big was the team that Bjestro was +[25:19] working with when he figured this stuff +[25:20] out and thought it was good? one, he's +[25:23] doing the same thing we're doing. So +[25:25] these ideas don't come from some kind of +[25:28] a like analysis of what we're going to +[25:31] do with lots of people. So you could +[25:33] argue maybe they turn out to be good for +[25:35] that. But you certainly can't argue they +[25:36] was designing it for that because they +[25:38] weren't. They were doing it for +[25:40] themselves. Strus was doing it for the +[25:42] the protection, the type protection, the +[25:43] error checking, that sort of thing. He +[25:45] wasn't doing it to and also like the +[25:48] virtual function kind of stuff. He +[25:49] wasn't doing it uh for large teams +[25:51] because everyone at Cambridge University +[25:52] was helping out in the product. No, he +[25:53] he was a lone wolf coder. He really was. +[25:56] So anyway, goes to Bell Labs. He makes C +[25:59] uh with classes, which is the first +[26:01] thing that uh it's the original name of +[26:03] C++ called C with class because that's +[26:04] what's going to be. It's going to be +[26:05] taking simul type system and putting +[26:08] something like that into uh into C. And +[26:10] the reason for that is pretty obvious. +[26:12] He goes to Bell Labs and C would be like +[26:14] a lingua frana there probably, right? +[26:15] Because they're the people who make +[26:16] Unix. They're the people who make C like +[26:18] the people uh who are at Bell Labs, the +[26:20] people making these technologies. So he +[26:23] is tasked when he gets to Bell Labs with +[26:25] doing the same sorts of distributed +[26:26] systems analysis that he was trying to +[26:28] do at Cambridge. Uh he's he's trying to +[26:30] do those things for Unix. He wants to +[26:33] analyze certain behaviors of it and that +[26:34] sort of thing. And he finds like the +[26:36] same exact things. He would like to +[26:37] write in something like Simula. He +[26:39] doesn't want to have the same disaster +[26:40] that he had where he had to rewrite +[26:41] everything in BCPL. So he's like, could +[26:43] I take C, add classes to it, and get the +[26:46] best of both worlds? Something that +[26:48] actually runs and doesn't fall over, +[26:50] right? But that has some of these +[26:52] features that I've been enjoying. And so +[26:54] that's what he's doing. And he's doing +[26:56] it for the same reason, right? That sort +[26:57] of modularity and concurrency analysis +[27:00] kind of stuff. He's trying to figure out +[27:02] how these things work and run +[27:03] simulations of them. Same exact thing is +[27:05] happening and it's happening over again. +[27:07] And what he kind of complains about with +[27:10] C if you didn't have these things, some +[27:12] of it's a little confusing. Like he +[27:13] talks about the fact that he says like +[27:15] all program parts can poke into all of +[27:17] the memory. And like C++ doesn't really +[27:19] change that, but I think he's just kind +[27:20] of talking about like, you know, private +[27:22] declarations, right? He's just like, +[27:24] well, you know, I I obviously I don't +[27:25] think you can stop programs from poking +[27:27] into the memory by putting private on +[27:28] it, but it will stop programmers from +[27:30] typing it into the compiler. And that's +[27:31] sort of the same thing, right? And where +[27:34] that comes from, this sort of idea that +[27:35] we're going to protect things that +[27:37] actually comes again from his +[27:38] distributed systems sort of OS thinking +[27:41] background because he's looking at +[27:43] hardware and he's looking at things like +[27:45] virtual memory and protection that you +[27:47] get between processes and those sorts of +[27:49] things and he's saying that's kind of +[27:50] what I want for programming like I don't +[27:52] really want to make those mistakes where +[27:55] I access the private part of things, you +[27:57] know, I want to be able to wall those +[27:59] off. And he's thinking about actual +[28:01] hardware, computer hardware. That's +[28:02] where that idea comes from. Again, it +[28:04] doesn't even come from working on large +[28:06] teams or anything like that. It comes +[28:07] from thinking this might be a nice +[28:08] feature. Just like the computer stops +[28:10] it, right, from happening, the compiler +[28:13] could stop it from happening. And that's +[28:14] where const comes from too. It comes +[28:16] from an OS metaphor. He's thinking about +[28:19] whether or not files have write +[28:21] permissions to them, right? Are they +[28:23] readon or are they writable? That's what +[28:25] const is to him. That's where he thinks +[28:27] thinks about it first. So again, all +[28:29] these things come from a very different +[28:30] place than what you would think if you +[28:32] didn't go back and read the historical +[28:33] documents. Uh and by the way, these +[28:35] aren't hard to find. Like these these +[28:37] just come from the D& which is a very +[28:38] popular book that he wrote. Uh that's +[28:40] just collection of his papers, right? So +[28:42] a lot of this a lot of the stuff in the +[28:43] first part of the talk you don't have to +[28:44] dig that hard for. All right. So anyway, +[28:48] we get sort of a second wrinkle at this +[28:50] point. And what happens when he starts +[28:53] using this stuff is it's important to I +[28:57] shouldn't really say what starts +[28:58] happening. Let's say one of the things +[29:00] he does is he uses the inheritance that +[29:03] he puts into this sort of C with classes +[29:06] because he's just going to do the same +[29:07] thing that was happening in Simula. He +[29:09] uses that inheritance in a way that +[29:10] would generally be you know frowned upon +[29:13] even by him today. And that is to do +[29:15] things like implement a linked list and +[29:16] reuse it. So what he does is he says +[29:19] okay I'm going to take a block that's +[29:21] like the linking part of things and I'm +[29:23] just going to inherit stuff from it so +[29:25] that all the things that inherit from it +[29:26] can go in a list right now he would +[29:28] never say to do that today he would say +[29:30] use a template or something like that +[29:31] like a parameterized type right so but +[29:33] it's important to remember at that time +[29:35] this was a thought and this thought +[29:37] actually does come from simul as well +[29:38] we'll get to that later but so it's +[29:40] important to say in addition to the +[29:42] modeling part they're using inheritance +[29:45] for the purpose of code reuse produce +[29:47] even if it really doesn't have much to +[29:49] do with anything. That's sort of an +[29:50] adjunct split. I just want to include it +[29:52] here so that you understand all of the +[29:53] things that were being thought about +[29:54] with inheritance at the time when it was +[29:56] actually being put into more mainstream +[29:58] languages. So that's what he was uh one +[30:00] of the things he was doing with it in +[30:01] addition to the domain modeling part +[30:02] which is more of a direct mapping. Okay. +[30:05] And you can see him here criticizing it +[30:07] just to hammer this home. He doesn't +[30:09] think you should do that anymore. and he +[30:11] said as much in parameterized types for +[30:13] C++ which is where he started to talk +[30:15] about templates as soon as templates as +[30:17] soon as he got his answer to how we were +[30:19] going to do these sort of things. Uh as +[30:22] soon as he got like a parameterized type +[30:23] model because that wasn't new to C++ +[30:25] there were languages like ADA and clue +[30:27] and stuff that had that in there. He +[30:29] started to say okay C++ has never had a +[30:31] good way to do this because you had to +[30:32] do the inheritance thing. That's not +[30:33] fabulous. Parameterized types are the +[30:35] way to go. So he knows that too. It just +[30:36] takes a while to get there. +[30:39] Okay. So that's kind of the end of it +[30:42] and virtual functions come in a little +[30:44] bit later. The first version of C with +[30:46] classes when he's first starting on it +[30:48] doesn't actually have virtual functions. +[30:50] He eventually does put virtual functions +[30:52] in. And when he does, this is what he +[30:53] says about it. He says it was borrowed +[30:55] from Simula and presented in a form that +[30:56] was intended to be make it simple and +[30:58] efficient. So he was thinking primarily +[31:01] about I I want something kind of like +[31:02] what Simula has for this ability to call +[31:05] functions without knowing the type on +[31:06] them. uh but I want to make sure it's +[31:08] very fast because that was a concern +[31:09] that he always had again because of the +[31:10] disaster he had experienced uh directly +[31:12] with Simula. So again, reflecting on +[31:15] this, it's totally different from what +[31:19] you would think if you just read like +[31:20] the capsule summary. Like he's not +[31:23] talking about large teams still. He's +[31:25] talking about literally we're just +[31:27] working on this thing. I'm using +[31:29] inheritance for some reuse of code and +[31:32] I'm using it to directly model the +[31:34] compile time, you know, at a compile +[31:35] time and using it directly model the +[31:37] actual domain that I'm working in which +[31:38] happens to be distributed computer uh +[31:40] distributed systems analysis yet again. +[31:43] So we have to jump at this point because +[31:47] that's pretty much all we can get out of +[31:48] C++. I mean that's you kind of got the +[31:51] picture now. Everything else is like +[31:52] after the fact. Everything else is post +[31:54] talk. Anything else about C++ was people +[31:56] making stuff up after that or adding +[31:58] things to it after that. But that's +[31:59] where it comes from. So if we want to +[32:02] actually know where these ideas started +[32:03] from, we've got to go back to Simula. +[32:06] We've got to say, well, okay, if all +[32:07] this stuff came from Simula and him +[32:09] using Simula, well, where did it come +[32:11] from in Simula? like did they just make +[32:12] it up? And Simulator originally comes +[32:15] from something called the Norwegian +[32:16] Computing Center. I mean we we are here +[32:18] very close to Norway I suppose. So some +[32:20] of you may have known this place. I +[32:22] didn't really know anything about it +[32:23] until I read that like you know was +[32:24] reading up on Simula and like okay +[32:26] there's this place. It's a quasi kind of +[32:28] private public uh institute for doing +[32:31] computing research and it's it's in +[32:33] Oslo, Norway. And in 1962, +[32:36] these saucy gentlemen right here, uh, +[32:38] and I'm I'm apologizing like Sweden is +[32:42] the worst place to give this talk +[32:43] because now I have to pronounce their +[32:45] names in front of people who probably +[32:46] know, uh, Norwegian pronunciation very +[32:49] well. And so I'm going to butcher it and +[32:52] I apologize. It's Oly Johan Dal. Maybe I +[32:56] can pronounce that correctly. And +[32:57] Kristen Nygard. And you already know +[32:59] Kristen Nigard's name because this is +[33:01] the person who Bjanna Trustup learned uh +[33:04] the simula from originally. He was you +[33:06] know he interacted with him a lot when +[33:08] he was uh at his previous university +[33:10] before Cambridge. So these are the folks +[33:12] who make simul +[33:14] kind of like the masterminds behind it. +[33:17] And the first reference we have to it is +[33:19] in private correspondence that has now +[33:21] been published uh from Nygard to a +[33:24] another person who was working on +[33:26] operations research. And these folks +[33:28] operations research if you don't know +[33:30] what that is, it's when you look at how +[33:32] systems are behaving to in order to +[33:34] optimize them basically. So you can +[33:36] think about things like we're you know +[33:38] we're trying to plan how you know the +[33:40] military is going to organize some +[33:41] things like what is their process going +[33:42] to be and we want to maximize the +[33:43] throughput of like how we're +[33:44] manufacturing this thing or how we're +[33:46] going to load planes onto an aircraft +[33:47] car. I don't know anything like that. A +[33:49] lot of it's military because that's +[33:50] where the funding comes from. But it's +[33:51] for anything really. it's also in +[33:53] business operations research uh things +[33:55] things like the simplex algorithm if you +[33:56] ever heard of that that's operations +[33:57] research etc etc so anyway he says like +[34:01] I got this idea what I'm going to do is +[34:04] I'm going to make this language that +[34:05] makes it very easy to describe one of +[34:07] these systems and then what I will do is +[34:11] use it to describe these problems in a +[34:13] way that allows it to do the simulations +[34:16] automatically so it's like almost like a +[34:18] scripting language for system simulation +[34:21] and if you Look, this is some code you +[34:24] can find when they talk about the +[34:26] history of it. Uh, this is in 1963. The +[34:30] simul language would have looked like +[34:31] this. It's one of the earliest snippets +[34:32] I could find. And so this is not the way +[34:35] the final simul look. This is sort of +[34:37] how they started out. And you can see +[34:39] what it essentially is. And you don't +[34:41] need to understand exactly what's going +[34:42] on in this for the talk. So I'll I'll +[34:44] spare you the details. But essentially +[34:46] what you're doing is you're setting up +[34:47] these various things like customers and +[34:49] stations. It's like things we're we're +[34:51] imagining like entities moving between +[34:53] parts of a system and we write little +[34:55] pieces of code that's like how they will +[34:57] be processed when they get there. Like +[34:59] will this person you know they'll be +[35:00] held for a little bit of time and then +[35:02] we'll check to see if they've paid the +[35:03] fee and if they've paid the fee we'll +[35:05] send them to this station. If they +[35:06] haven't paid the fee we'll send them to +[35:07] this other one. And the idea is you just +[35:09] describe that system this way. You run +[35:11] the simulation and it presents you with +[35:12] a bunch of statistics so you can kind of +[35:14] see like okay this is where the +[35:16] bottlenecks were or things like that you +[35:17] know +[35:19] and that was very successful. They +[35:21] eventually released a thing called +[35:22] stimula 1 which was the first sort of +[35:24] more widespread version of this thing. +[35:26] It was people loved this. They could do +[35:27] their system analysis this way. But uh +[35:30] Nygard and D were thinking in their head +[35:32] like we really like this thing and we +[35:34] think it has more it has possibility to +[35:36] be bigger than what it is. Powerful just +[35:39] what we had in that first version. So +[35:41] they start to make a new version which +[35:43] eventually goes on to be called Simul +[35:44] 67. And this is like it's like Windows +[35:46] 95 right at this point in time people +[35:48] are starting to name languages where you +[35:51] append the year of the language after +[35:52] the language. So we have things like +[35:54] Alol having that or Cobalt 60 is the +[35:57] version of Cobalt that was first +[35:59] introduced in 1960, right? And so that's +[36:02] what Simul 67 would eventually be. And +[36:04] they're trying to figure out what +[36:05] they're going to do uh for this new +[36:07] version. And what happens is they're +[36:10] thinking about code reuse. They're like, +[36:13] we don't really like we have to rewrite +[36:14] things a lot of times and we're trying +[36:16] to figure out some way that we could get +[36:18] some of this reuse in there. like we +[36:20] want to reuse these things and it's not +[36:22] really working out very well for us. +[36:24] They're looking for a solution to this +[36:25] and they're not really finding one. But +[36:28] eventually when they're thinking about +[36:30] this problem, they're saying, "What if +[36:31] we have like a bridge with a toll booth +[36:33] on it and we've got cars going across +[36:35] it?" And they might be either trucks or +[36:37] buses. What could we do so that we could +[36:40] just write this once and have it work +[36:42] for both the trucks and the buses so we +[36:44] don't have to like duplicate all the +[36:46] stuff we said for trucks and buses? +[36:47] That's what they're thinking of. And +[36:49] this is not me saying this was this is +[36:50] them saying this is what they were think +[36:52] this is what they were trying to solve. +[36:54] Literally this is what they were trying +[36:56] to solve when they came up with classes. +[37:00] And here is what those classes look +[37:01] like. You can see up at the top there +[37:03] it's defining link class car. The link +[37:06] is a thing where they have this linked +[37:08] list sort of superass that they're +[37:10] deriving from and they're going to have +[37:11] a car. Then they're going to say +[37:12] underneath cars they're going to derive +[37:14] a car class truck and a car class bus. +[37:16] There's different kinds. You can see +[37:18] load and capacity are like two different +[37:19] data members that those have. Okay. So +[37:22] in this one snippet we can see both +[37:25] things that not only they are about to +[37:29] do but that bjarnstrip is about to do as +[37:32] well. We are using this for reuse. We +[37:35] are deriving from a link class to get +[37:37] its functionality not because we think +[37:39] that we are like a link in the domain +[37:41] model. But then mostly what we're doing +[37:44] is following the domain model with our +[37:46] classes. it is car and underneath it is +[37:49] truck and bus exactly like would +[37:52] eventually be promulgated as how to +[37:54] design oop systems with those +[37:56] hierarchies that I was talking about. So +[37:58] that's what it looked like and they +[38:01] literally said hey this now allows us to +[38:04] quickly just say this thing is a link +[38:05] and then it can go in lists. Awesome. +[38:09] Now you'll notice they didn't actually +[38:10] talk at this time very much when they +[38:12] were counting the history and I guess I +[38:14] shouldn't say you'll notice. I noticed +[38:16] because I had to read the whole thing. +[38:18] They don't really talk about the virtual +[38:19] function part at the outset, right? +[38:22] They're kind of talking about just this +[38:24] reuse part. That's mostly what they're +[38:25] concerned about, but they do eventually +[38:28] care about that virtual part because +[38:29] once they do this subclassing, they're +[38:31] like, hm, we want to have ways that the +[38:34] subasses can do things in addition to +[38:36] what the parents doing. And that's where +[38:38] the idea from virtual functions comes +[38:39] from. They say we have these operations +[38:42] that we were defining, you know, things +[38:43] like what that queuing behavior was +[38:45] going to be that I showed on the +[38:46] original slide from, you know, Simula +[38:48] back in 1963. And they're like, we want +[38:50] to have those operations be modified +[38:53] based on whether this, you know, car is +[38:55] a truck or a bus and things like that. +[38:57] So that's what happens. Now, if you look +[39:01] at how this had to actually work, it +[39:04] works the same way that primitive code +[39:06] reuse works. If you wanted to use it +[39:09] today, if you want to use inheritance +[39:10] for things like links, it worked exactly +[39:12] the same way. They literally had the +[39:14] sort of class hierarchies. I can see in +[39:15] the middle there, class sim set and sim +[39:17] set class simulation. That's basically +[39:19] saying like look, all of this stuff is +[39:21] going to be derived from like linked +[39:23] list holder. That's what simis would be +[39:25] like. Like I'm a person who holds link +[39:26] lists and then we're going to derive the +[39:28] simulation from the thing that holds +[39:29] link lists. That way it can use that. So +[39:32] it's almost like a library like they're +[39:33] using inheritance like a library here as +[39:36] well as the domain model which is under +[39:37] it. So again that same double duty. All +[39:40] right. So again just a hammer at home. +[39:44] Nothing about teams, nothing about +[39:46] architecture, none of this stuff, right? +[39:48] It's all about trying to solve a code +[39:51] reuse problem and then something falls +[39:53] out of that. No analysis is done of any +[39:55] of the things that you would normally +[39:57] say if you were trying to promote the +[39:59] use of domain modeling via those class +[40:01] hierarchies. Right? That's not what's +[40:03] happening. +[40:05] So +[40:07] this is where we actually got compile +[40:09] time hierarch that matched the domain +[40:11] model because simula actually did have +[40:13] encapsulation. You couldn't refer to +[40:15] things outside of the entities like that +[40:17] very much. And so it kind of did have +[40:19] the beginning of that. It wasn't as +[40:21] rigid as C++ as we'll see. But that's +[40:23] effectively what it was. +[40:26] So +[40:29] I don't know how to summarize all of +[40:30] that that we just saw. Basically what +[40:32] I'd say is effectively what we sort of +[40:35] were seeing is this came out of sort of +[40:38] an approach to templates that wasn't +[40:40] very good. Like that's that's sort of +[40:42] what happened. And it's not their fault +[40:43] cuz I mean they're in the wilderness, +[40:44] right? Like nobody knows any of this +[40:46] stuff. We take for granted all the +[40:47] things we know today. They don't know +[40:49] any of this. They have to invent +[40:49] everything. But that's really what they +[40:51] almost wanted if you had handed them +[40:53] templates at the time they were trying +[40:55] to do this. They may never have invented +[40:57] this class concept at all because they +[40:59] they just wanted a link list. they just +[41:00] wanted a way to say I have list of +[41:01] things going across right or whatever. +[41:03] So that's sort of where they had started +[41:05] and they just happened to come up with a +[41:06] virtual function thing which by the way +[41:08] is useful for stuff. I'm not trying to +[41:09] suggest that it isn't but that was sort +[41:11] of a byproduct of what they were trying +[41:12] to do which was just make a list class +[41:14] they could reuse kind of. All right so +[41:18] that's the end. That's the entire story. +[41:19] Now you know where everything came from. +[41:22] I mean, of course, if you only want to +[41:24] do sort of the capsule version, that's, +[41:26] you know, again, sort of the this the +[41:27] Wikipedia version of it, +[41:30] but you have to kind of ask the +[41:31] question, I mean, we know that they did +[41:34] those things, but like where did they +[41:36] get the idea for those things? I mean, +[41:38] that's usually how I approach things +[41:40] anyway, right? I'm like, after I find +[41:41] out that like someone got the idea from +[41:43] someone, I'm like, well, do we know if +[41:45] that guy got the idea from someone? Cuz +[41:47] I want to know about following it the +[41:49] whole way back, right? So, that's the +[41:51] end. If you just use a capsule Wikipedia +[41:53] summary again, you'd kind of get +[41:55] something like that out of it. What you +[41:57] probably wouldn't get is this stuff. So +[42:02] when you actually go digging in here and +[42:03] you pay attention to every little thing +[42:05] and every time you come across something +[42:07] but someone mentions, you're like, +[42:08] "Wait, what?" And then you go try to +[42:10] pull the papers that they're actually +[42:12] referencing, you start to find out a lot +[42:14] of other stuff. So if we keep pulling +[42:16] this thread, what we find is the idea of +[42:19] subclassing is not credited to uh Nygard +[42:23] and Dah. They credit it to somebody +[42:26] else. C actually the guy who +[42:30] invented quicksort. +[42:32] That's who they say this idea of +[42:34] subclassing came from. They don't claim +[42:37] to have invented it. They claimed to +[42:38] invented a version of it that was +[42:41] derived, pun intended, from work, +[42:45] right? +[42:46] And this is the paper that they're +[42:48] referring to. This is the paper that I +[42:49] believe they would have read, although +[42:51] I'm not sure exactly which version they +[42:52] read because different versions were +[42:53] circulated. And there's actually uh sort +[42:55] of a further comments one happens after +[42:57] this. But they would probably be aware +[42:58] of all of this because academics are +[43:00] always very good, right, at sharing +[43:02] their information this way, putting out +[43:03] publications. I mean, it's it's their +[43:05] it's the thing that is cred for them, +[43:08] right? Like your papers are your cred. +[43:09] So you're reading papers by other +[43:11] people. You're writing your papers. So +[43:13] they were uh they read this paper for +[43:15] sure. Which version exactly? I I +[43:16] couldn't tell you. But this is the +[43:18] paper. And here's what is talking +[43:20] about in this paper. He says, "All +[43:23] right, we have in the real world, and I +[43:26] want to underline that because it's like +[43:28] compile time hierarchy that matches the +[43:30] domain model, right? In the real world, +[43:33] we have objects that we want to model +[43:35] and they have different versions of +[43:37] things and we want to model that sort of +[43:39] discrimination that's happening there in +[43:41] the subasses. And so he gives the +[43:43] example of an algebraic expression. He's +[43:45] like, if you look at an algebraic +[43:46] expression, I'm trying to model that. I +[43:47] want to represent that in the computer. +[43:48] I might say I have an algebraic +[43:49] expression and then I have these +[43:51] different things that are types of +[43:52] algebraic expressions, right? And he +[43:54] says constants, variables, diatic +[43:56] expressions, right? He's trying to model +[43:57] language. And by the way, this happens a +[43:59] lot. uh I don't really cover it much in +[44:01] this talk because it's not relevant but +[44:02] you'll see a lot of people this time +[44:04] were working on things like how do we +[44:05] parse stuff right so sort of thinking +[44:07] about how do we parse language how do we +[44:08] parse computer languages how we parse +[44:10] human languages are thinking about this +[44:11] kind of thing all the time it's like +[44:13] what if I want to represent an equation +[44:15] how am I going to do it right and he's +[44:16] saying what about these subasses and he +[44:18] would literally write it just like this +[44:20] so as we can see +[44:23] nyard and doll were not lying they 100% +[44:25] did get this idea from that it looks +[44:28] almost exactly like theirs down to the +[44:30] syntax. You can see that he's saying I'm +[44:32] going to have an expression. Here are +[44:32] the subasses of the expression. It's +[44:34] going to be constant and variable, +[44:36] right? And so this is what NAL read. And +[44:40] they were like, oh wait a second, what +[44:43] if we just had like our cars and trucks +[44:46] and buses under them and we could just +[44:48] use the car and then we put the car +[44:50] across the bridge. Okay, that would +[44:52] work. Wait, but we don't have to stop at +[44:54] the car. We could make something above +[44:55] the car that's like things that are in a +[44:58] list of stuff and then we could use it +[44:59] for everything. Doesn't even have to be +[45:01] the bridge. Holy cow, dude. Like, thank +[45:04] you. Thank you, Tony. Uh, so anyway, +[45:07] yeah, Anthony. They call him Tony +[45:08] because I was he didn't go by Anthony. +[45:11] Anyway, sorry thing I didn't introduce +[45:13] ahead of time. It's just up here because +[45:15] I've been reading this stuff for, you +[45:16] know, I don't know, months at this +[45:17] point. Anyway, so +[45:20] when he presented this in this paper, it +[45:24] doesn't stop there. And this I found so +[45:26] interesting. And we're starting to get +[45:28] into stuff now where like I had never +[45:29] heard before. A lot of this stuff when I +[45:31] diged into it, I was like, how come +[45:33] everyone doesn't know this because it's +[45:35] super cool. When he presented this +[45:37] paper, or I shouldn't say presented this +[45:38] paper, when he wrote this paper, he +[45:40] included discriminated unions in it. +[45:42] Tagged unions, whatever you want to call +[45:44] them. There's FP people out there in the +[45:45] audience are going to scream at me for +[45:46] using the wrong term, but you know what +[45:48] I'm talking about. Something that has a +[45:49] type in it and then subasses inside it. +[45:51] And you don't know which one you have +[45:52] until you look at the type. And then you +[45:54] can, you know, use whichever part makes +[45:56] sense for that type. And this is a super +[45:58] powerful programming. I use it all the +[46:00] time. And I think it's one of the best +[46:01] programming tools you have for things +[46:03] like dynamic polymorphism. I absolutely +[46:05] love it. It's in this paper in 1966, +[46:08] right? A long long time ago. +[46:12] And this is his way better than anything +[46:16] I get to use today in C++ +[46:18] thing he suggested for what you would do +[46:22] when you wanted to use one of these. He +[46:24] said it's a switch statement which of +[46:26] course you know wouldn't been called a +[46:27] switch statement at that time but it's +[46:28] basically a switch statement that says I +[46:30] want to use this object and I'm going to +[46:31] tell you what each type you know which +[46:34] whatever the subtypes might be. I'm +[46:35] going to give you a different block of +[46:37] code to run depending on which one they +[46:39] were. Right? Again, functional +[46:40] programming, I believe, would really +[46:42] like something like this, right? It's +[46:44] doing that discriminated union thing. +[46:45] And furthermore, he gets the fact that +[46:48] this adds type safety and prevents +[46:50] errors. He gets the fact that the code +[46:52] that would come after the then +[46:54] statements can now safely refer to the +[46:56] subtypes because, you know, you've +[46:58] checked what the type actually was. And +[47:00] he says that right in the paper. So, he +[47:04] totally got it. He knew way better than +[47:07] any of the knock-on languages. uh sort +[47:09] of you know I guess from C++ on he knew +[47:12] way better even at that time how cool +[47:15] discriminated unions would be if you had +[47:16] the right language constructs to work +[47:18] with them in a type- safe way. So I +[47:21] thought that was super duper awesome. +[47:24] Now +[47:26] if you think about it if this was in the +[47:29] paper and similar read the paper and +[47:32] that's how they created simula was or +[47:34] the class concept in simula and the idea +[47:36] of subclass simula and then you know C++ +[47:40] came out of simula well why don't we +[47:42] have like why wasn't this a first order +[47:44] feature like where did the discriminated +[47:46] union part go and the answer is well +[47:49] nyard doll actually put it in it was +[47:52] called inspect +[47:53] So, Simula actually had this. You didn't +[47:56] have to use virtual functions. Simula +[47:58] was way better about that. When Strrip +[48:02] went to do his classes, he took it out. +[48:05] He thought that discriminated us were +[48:07] bad because they broke modularity, +[48:09] right? It's because now someone from the +[48:12] outside can tell what class you are. So, +[48:15] we lost out on one of what I consider +[48:17] would be one of the most important +[48:19] features I would use in C++ every day +[48:22] because it got removed when Simula was +[48:25] playing telephone with C++. +[48:34] All right. So, there you go. That's +[48:36] where the concept actually comes from. +[48:38] Right? This is it's this paper by you +[48:42] know Anthony a s he's sir now by +[48:44] the way he he he he's he's been kned I +[48:46] believe right um and again not a single +[48:52] part of it there's no no hint at all +[48:54] that any of this is really about compile +[48:58] time hierarchy stuff or about large +[49:00] teams or about any of the things we +[49:02] talked about today. It was literally +[49:03] like, hey, I might have a record that +[49:06] wants to have a type field and it would +[49:07] be cool if I could just switch on the +[49:09] type field and do different things based +[49:11] on it. How about that? Right? And that's +[49:14] what I would have wanted. So, we had +[49:15] that already back when this paper +[49:18] circulated uh in 1966. So, really the +[49:22] whole string is about us getting a +[49:24] really bad version of discriminated +[49:26] unions. We had them already and now we +[49:29] don't have them. To this day, I don't +[49:31] even know a standard variant really +[49:33] works as well as this thing would have, +[49:35] right? And we could have had it from day +[49:38] one if someone had just believed that +[49:41] this was good. +[49:43] All right, so that's the actual end. Uh, +[49:46] we've gotten back to kind of kind of the +[49:48] point of the first part of the talk. +[49:54] There's another half because it goes way +[49:56] further back than that, but I want to +[49:58] give everyone a chance to kind of +[49:59] stretch out. So, I don't know. Can we +[50:01] take a break? Where where is Sam? Can we +[50:03] take a break for a few minutes? +[50:04] >> Yes. How long do you want? +[50:06] >> I don't care. I can keep going if you +[50:08] don't want, but I figured Yeah, stretch. +[50:10] >> Let's go to 25. +[50:12] >> Okay. I'll see everyone back here +[50:14] whenever that is at 25. +[50:17] [Applause] +[50:25] Okay, so as you saw in the first part, +[50:29] you come to the end a lot of times, but +[50:32] then it's like, well, you know, is it +[50:34] really the end? If you keep digging, +[50:35] turns out you didn't really get to the +[50:38] actual meat of, you know, the the origin +[50:41] story. You didn't really get to the part +[50:42] where I don't know, I'm bad with comic +[50:44] books, but like, you know, Bruce Wayne +[50:45] and the Falling Pearls and the Joker and +[50:47] that kind of stuff. We actually gotten +[50:48] back to that scene and that's the scene +[50:50] that everyone wants to see in the movie. +[50:51] It's like how did he become Batman? So, +[50:54] what we're going to do here in the +[50:55] second half, I promise there's only this +[50:56] only it's one more half. There's two +[50:58] halves. I'm not going to psych out +[50:59] again. +[51:01] We're going to do here is we're we're +[51:02] going looking for Batman, right? So, we +[51:05] left off. We've got this paper on record +[51:08] handling by Uh, right. famous for +[51:12] quicksart like I said one of the the +[51:14] fathers of computer science +[51:17] and the interesting thing is and this +[51:19] was really hard to figure out but I was +[51:22] trying to like where did he get the idea +[51:25] like did he come up with the idea was he +[51:27] sitting around what was he working on +[51:29] right and it was really hard to find +[51:31] this I wish that I could find a document +[51:33] where he talks about it if any of you +[51:35] out there ever find a document because +[51:37] you know I did the the most research +[51:39] that I could do in the time that I +[51:41] uh to figure out where these things came +[51:42] from. But I'm sure I missed something +[51:45] somewhere. So if you're going to +[51:46] actually figure this out, I would love +[51:47] to see it. But after a lot of digging, I +[51:50] figured out something pretty +[51:51] interesting, which was that actually +[51:56] there was this committee that was +[51:58] supposed to alming +[52:01] language that was very popular at the +[52:04] time. It was in use since the the early +[52:06] 60s, actually. Actually, it might have +[52:08] even been before that. I don't remember +[52:09] cuz it's not that relevant to to this +[52:11] particular timeline. But what they were +[52:14] going to do is much like Simula had an +[52:16] update from Simula 1 to Simula 67 here +[52:19] there's going to be an update of Alol up +[52:21] to this new version that would +[52:22] eventually be called Al Gal 68 and the +[52:25] people who are working on this it's like +[52:27] a who's who of like computer science +[52:29] fame right so horror is on this and and +[52:32] so are a lot of other people like +[52:33] Nicholas Worth and that kind of people +[52:34] like people the person invented Pascal +[52:36] or created Pascal right so on this +[52:39] committee there was another guy and his +[52:42] name was Douglas T. Ross. And this is a +[52:46] name that I had never seen mentioned +[52:48] ever before. I have no idea who this guy +[52:50] is. And I'm like, wait, what? And oop, +[52:52] sorry. And when was talking about it was +[52:56] like oh you know in some private +[52:58] correspondence because Alan Blackwell +[53:00] and Carrie Roden not really a part of +[53:01] the story but they're like we talked to +[53:04] her privately about where we got those +[53:06] ideas and he said that they actually a +[53:10] lot of them came from this guy named +[53:11] Ross who he had conversations with when +[53:13] they were on the committee. And I'm like +[53:16] okay so what's this about? And Ross had +[53:20] this thing he called a plex, which is a +[53:23] record-l like data structure. And +[53:24] apparently this was something that +[53:26] really influenced +[53:28] uh horror's record handling paper, which +[53:30] would eventually go on to in you know +[53:33] create the rest of the chain that we +[53:34] just went through. So that's one thing. +[53:37] And another thing is if you look at the +[53:39] other branch, the branch that I'm not +[53:40] really covering very much in this talk +[53:42] because again we don't program in small +[53:44] talk these days, right? The closest +[53:45] thing you would get is maybe something +[53:46] like object Objective C if there are +[53:47] some still people out there using +[53:48] Objective C you know like Apple was +[53:50] using that for a little while. So +[53:52] Objective C kind of came from a small +[53:53] talk background as well. So but it's +[53:56] another huge branch of object +[53:58] programming. Small talk was very +[53:59] important. It's influential at least in +[54:01] the research or in the understanding of +[54:02] oop right it was a very pure oop +[54:04] language. It it pushed oop a lot further +[54:06] than a lot of the other languages by +[54:07] saying everything is going to be +[54:08] object-oriented and that sort of thing. +[54:10] And of course it invented the term +[54:12] object oriented. So it's everything's +[54:13] going to be like small talk which is +[54:14] what objorinted was right if you look at +[54:17] what Alan K talks about for his +[54:20] inspirations like where did he get his +[54:21] ideas from small talk he list some +[54:24] things and there's some like the +[54:25] burough's B5000 and this file system +[54:27] from an air force base that had to do +[54:30] mostly with dispatches we could go into +[54:33] that in the Q&A if anyone cares. But one +[54:35] of the things he talks about is Simula +[54:37] which we've already covered and the +[54:39] other thing is Sketchpad. He talks about +[54:42] sketchpad all the time. This was a huge +[54:44] hugely impactful thing for Alan K. And +[54:47] Sketchpad was like this drawing program, +[54:50] right? I was aware of Sketchpad. I mean, +[54:52] maybe some of you are aware of +[54:53] Sketchpad. It's pretty famous. You can +[54:54] look up demos of it on YouTube, for +[54:56] example. So, we've got this Ross guy +[54:59] that I want to look into more. I'm like, +[55:01] what's going on? And then we got this +[55:03] Sketchpad thing. And I'm like, hm, I +[55:05] think I remember Sketchpad, but I don't +[55:07] really know why that would have inspired +[55:08] Alan K to do object. So, I'm going to +[55:10] look into this more. I want to see just +[55:12] make sure I've got the whole story +[55:13] before I really say the end like I fake +[55:16] did in part one. So, let's go back even +[55:19] further. 1952. Now, there's this place +[55:22] called the Servo Mechanisms Laboratory +[55:24] at MIT, which is kind of an amazing +[55:27] name. Um, I would love to be able to +[55:29] tell people that I worked at a servo +[55:31] mechanisms library, uh, a laboratory +[55:34] rather. But this fellow right here, that +[55:36] is Douglas Ross, who now I know exactly +[55:38] who he is and what he did. He goes there +[55:42] and he's first on the job in 1952. He +[55:45] gets to this laboratory and what their +[55:47] sort of whole mission was, this was +[55:49] Department of Defense, United States +[55:51] Department of Defense research stuff. +[55:53] What they were trying to do is build a +[55:56] system where someone from like, you +[55:59] know, the Air Force could describe a +[56:01] part that they were going to try to +[56:03] manufacture and the computer would just +[56:05] make it. It's almost like the birth of +[56:07] like 3D printing. And they actually did +[56:10] demos of this. They had stuff working +[56:12] where you could like type in a +[56:13] description of an ashtray in like the +[56:15] sort of pseudo language that they had +[56:17] that was meant to be kind of more uh +[56:19] it's sort of, you know, uh almost like +[56:21] in a Gracehopper sense, right? like +[56:23] something that's sort of we're trying to +[56:24] get closer to human language but it's +[56:26] really not human language because they +[56:28] don't have the ability to parse that yet +[56:29] right I mean until a large language +[56:31] models we didn't have the ability to +[56:32] parse that right so when you look at +[56:35] something like this what they're trying +[56:37] to do is say pseudo language and our +[56:39] milling our automated milling system +[56:41] produces like this object out of it +[56:43] right and they actually have working +[56:45] it's it's not entirely they've got it +[56:47] working they have uh instances of +[56:49] objects you can actually look at that +[56:50] they made so they're they're +[56:51] accomplishing this as Well, and you have +[56:54] to remember how early this is. 1978 is, +[56:56] you know, I date these by when the +[56:57] person's talking about it. This is the +[56:59] 1950s that they're doing it, right? So, +[57:02] they're working on this this simulation +[57:04] stuff that I'm sorry, this uh this +[57:05] processing stuff and this where they're +[57:07] trying to take language and turn it into +[57:08] uh sort of CAD, right? The birth of CAD. +[57:12] And just to show you how early this is +[57:15] in the thinking about what's going on in +[57:17] computing, cobalt is generally like +[57:19] again in the kind of uh loweffort +[57:22] Wikipedia search version, cobalt would +[57:24] be the first thing you'd see referenced +[57:26] as having things like record-l like +[57:28] strrus, right? Like we all take a +[57:29] strruct for granted where like a strruct +[57:31] is like the simplest possible thing, +[57:32] right? It's not doesn't have inheritance +[57:34] or it doesn't have uh virtual function +[57:36] calls or any of that stuff. we would +[57:38] just say, you know, if we're just +[57:38] talking about a bare strct, a basic +[57:40] vanilla strruct, that doesn't really +[57:42] exist. Like no one's thought about that +[57:45] really. They have sort of an idea of +[57:47] data records that comes more from like +[57:50] data processing, like the old IBM sense +[57:52] of the term. So they do have an idea of +[57:54] like more of like the database version +[57:56] of like I've got some fields that +[57:58] comprise like a record but people aren't +[58:01] really thinking like when I program +[58:04] the computer program is also going to be +[58:07] written in terms of records that it's +[58:09] using purely for computation not to +[58:11] store a particular piece of data like on +[58:14] magnetic tape or something like this +[58:16] right but it's just purely an artifact +[58:19] of the implication of this program I've +[58:21] defined other records +[58:23] They're not thinking about that. And +[58:25] even in this in 1960 when this was uh +[58:28] printed, this first version of Cobalt, +[58:31] even in that 1960 time frame, this +[58:34] Cobalt didn't really have that. All of +[58:36] its record stuff was pretty much still +[58:37] about data on tape kind of things. It +[58:39] was it was in memory as well when you +[58:40] had a mirror of one, but it wasn't no +[58:42] one was thinking really about that as +[58:44] far as I could tell. They're just think +[58:45] of it as storing data. Now pedance will +[58:48] say that plan calcul +[58:51] has this but it was a purely theoretical +[58:53] language just written down on paper. It +[58:54] was an early German programming +[58:56] language. It's very forward thinking so +[58:58] I don't want to disparage it at all but +[59:00] it doesn't count if you just sort of +[59:01] wrote down well maybe we'll have this +[59:03] way to like put multiple things. It's +[59:05] like no matter how rigorously define it +[59:07] on paper you don't get credit unless +[59:09] you've actually got this working and +[59:10] you're actually programming making +[59:11] programs in it that you run right. So +[59:14] really it's it's kind of not there at +[59:16] the time. So what people are actually +[59:18] thinking about is this right? Lisp is +[59:21] gaining some traction here because it's +[59:23] developed over the course of the 1950s +[59:24] as well. It it gets published officially +[59:26] in 1960 in this paper by John McCarthy +[59:28] who obviously was one of the uh I I +[59:30] believe he's sort of the person who +[59:32] designed lisp and actually a different +[59:34] person at MIT actually implemented it +[59:36] but that has nothing to do with any of +[59:37] this. Point being, he's obviously the +[59:39] father of Lisp because he's the one who +[59:40] had the idea and he's the one that +[59:42] designed it and he's starting to talk +[59:44] about lisp and saying this is a way that +[59:46] we could do symbolic computation. Now +[59:49] remember lisp doesn't really have any +[59:51] concept of records at this point or +[59:53] anything like that. It's just sequential +[59:55] bags of stuff. So it's like okay we're +[59:57] going to have like a a list of symbols +[59:59] and to the extent that you're ever going +[1:00:01] to do processing on something that's +[1:00:02] like a record it's just up to you to +[1:00:03] kind of remember that the symbols will +[1:00:05] go in a particular order and that's how +[1:00:07] you're doing your processing. So they +[1:00:08] haven't really gotten this idea yet of +[1:00:10] structured data like this is what the +[1:00:12] computer's going to process. They're +[1:00:13] thinking in terms of processing lists, +[1:00:16] right? Because again there's they're +[1:00:18] like no high level languages. We got +[1:00:19] like forran coming in this time. We got +[1:00:21] list coming this time and then these +[1:00:23] experimental languages stuff like that. +[1:00:24] We don't have all these languages that +[1:00:26] we know about today. +[1:00:28] So +[1:00:30] Douglas T. Ross he's also working on +[1:00:33] stuff like this. They have a programming +[1:00:35] language that they're working on for +[1:00:37] this you know computerated modeling +[1:00:39] stuff that they're doing. and he's +[1:00:41] actually thinking what if we did +[1:00:44] structured data like what if we were +[1:00:45] computing on things that actually had a +[1:00:48] fixed size and this is all throughout +[1:00:49] the 1950s they're developing this and in +[1:00:52] 1960 contemporaneous with that list +[1:00:55] paper he publishes a paper and in this +[1:00:58] paper he keeps it classy right out of +[1:01:01] the gate he basically throws shade at +[1:01:03] lisp he's like look lisp is kind of dumb +[1:01:07] why would we compute +[1:01:10] only on things that basically have a +[1:01:13] next and previous pointer or like a tree +[1:01:14] where it just has a left and a right. +[1:01:17] What would give you the idea that the +[1:01:19] things you want to compute on only +[1:01:21] consist of two things? What you're doing +[1:01:23] is you're just using that and then +[1:01:25] you're constantly building up these like +[1:01:27] structures of like two pointer things to +[1:01:30] represent bigger things. Why don't we +[1:01:32] just store the bigger things directly? +[1:01:34] And he knows why. He gets it. He says, +[1:01:37] "Look, not only does it take more space, +[1:01:39] but it also takes more processing power +[1:01:42] because we've got to reconstruct the +[1:01:44] data we actually want by plowing through +[1:01:45] these lists all the time. And +[1:01:47] furthermore, we have to store them by +[1:01:49] keeping all of that interstitial stuff +[1:01:50] in there. And that's no good either, +[1:01:52] right?" So, he is 100% on point. And +[1:01:54] this is published in 1960. +[1:01:56] Contemporaneous with the list +[1:01:57] publication, contemporaneous with +[1:02:00] something like Alol 60. So, way way +[1:02:04] ahead of the curve here, right? because +[1:02:06] that means they had it running +[1:02:07] throughout the 1950s. +[1:02:10] Now, he calls this a plex. Doesn't call +[1:02:12] it a structure. He calls it a plex +[1:02:15] because I'm guessing he's bad at +[1:02:18] self-promotion. He never gets this term +[1:02:20] to stick anywhere. So, you know, we +[1:02:23] don't type plex in front of our thing. +[1:02:25] But to be completely honest, as far as I +[1:02:27] can tell from history, we should it +[1:02:31] should be called a plex. We should pound +[1:02:33] to find Plex to be struck because that's +[1:02:36] where the credit actually goes to. It's +[1:02:38] this guy right here and the other people +[1:02:40] that were on that team. So what does it +[1:02:43] look like? This is one of the great +[1:02:45] things about this era. Everyone +[1:02:46] publishes everything. It's really nice +[1:02:49] and it has to be condensed down into a +[1:02:51] paper because there's no YouTube. So I +[1:02:52] don't have to watch hours and hours and +[1:02:54] hours of things to find out what the +[1:02:55] heck is going on. +[1:02:57] This is an example of a complicated +[1:02:59] plex. This is in the original paper in +[1:03:03] 1960. And what does it have in it? Well, +[1:03:07] it has some data, an x and y coordinate +[1:03:10] for example, right? Just things that you +[1:03:12] might store like you would normally data +[1:03:14] members. It also has pointers already, +[1:03:18] right? These are basically things that +[1:03:19] are linking it to other things. So, +[1:03:21] we've got data members, we've got +[1:03:23] linkage members, and hold on to your +[1:03:26] butts because what is this stuff down +[1:03:28] here, right? Like, what is that? And I'm +[1:03:32] loving this, by the way, when I find +[1:03:34] this stuff in papers, right? Because I +[1:03:37] don't like to just read the abstract. I +[1:03:39] want to read the whole paper. Like, I +[1:03:41] paid my money and I want to see the +[1:03:42] whole movie to the end. Even with the +[1:03:45] end credits, even if the movie sucks, I +[1:03:47] kind of want to know. I'm just curious +[1:03:49] right now. So, I'm looking at this, I'm +[1:03:51] like, "What the heck is that? TRA 562 +[1:03:55] like secret code stuff going on." +[1:03:58] So, what these actually are, and this is +[1:04:01] awesome, +[1:04:02] is check and fast are basically flags. +[1:04:06] And what Ross says is look, when we're +[1:04:08] processing this stuff, think of it this +[1:04:11] way. We could run one subruine and just +[1:04:14] based on what we stick in the plex, we +[1:04:17] could change how we're processing it. So +[1:04:19] if we do want this thing to go through a +[1:04:21] particular path, we set it. And if we +[1:04:24] don't want it to go through a particular +[1:04:25] path, we don't set it. Right? +[1:04:30] Just pausing for effect on that one. +[1:04:32] What's +[1:04:34] 562? What's 467? +[1:04:38] Those are addresses. That's an +[1:04:40] instruction. It's saying what we're +[1:04:41] going to do there is jump to a subruine. +[1:04:44] Those are function pointers. So we +[1:04:47] basically say sometimes we don't really +[1:04:49] want parameterization of what's going to +[1:04:51] happen. We just want a completely +[1:04:53] different thing to happen. +[1:04:55] And there is where you basically have +[1:04:57] your virtual function staring you right +[1:05:00] in the face right there in 1960 +[1:05:03] contemporaneous with lisp. +[1:05:09] So, I'll just say +[1:05:14] our team, +[1:05:16] yeah, I was clapping for him, too. I was +[1:05:20] clapping for him, too. Ryan, team Fat +[1:05:23] Struck, we started in 1960 right here. +[1:05:26] We're We're like We're like the old sort +[1:05:28] of uh thing at a university, like the +[1:05:30] you know, the old sort of uh the club, +[1:05:32] right, that's been going forever. We We +[1:05:35] got roots, man. We got roots. We got +[1:05:37] hardcore stuff on our side. +[1:05:40] All right. So, he throws up an example. +[1:05:43] He's like, "Hey, let's suppose we want +[1:05:44] to model a line because remember he's +[1:05:46] working on CAD. He wants you to be able +[1:05:48] to type in this is the shape of the +[1:05:50] airplane engine and out comes the +[1:05:52] engine." So, we're trying to think about +[1:05:53] things. How do we model lines? How do we +[1:05:54] model surfaces? That sort of thing. He's +[1:05:56] like, "Well, one thing we could do is we +[1:05:59] could take the data for the line and we +[1:06:01] could put it in there. So those are like +[1:06:02] names of things and x and y coordinates +[1:06:05] things for like points and then we could +[1:06:07] have like connect it up with pointers. +[1:06:09] So a line would have a pointer to two +[1:06:11] different points and the points would +[1:06:12] point back to the line and we'd make +[1:06:14] basically a winged edge data structure +[1:06:16] right +[1:06:19] off the charts with what they were +[1:06:20] doing. It's kind of crazy but doesn't +[1:06:23] stop there. So that is at the servo +[1:06:25] mechanisms lab which later gets renamed +[1:06:27] to like electrical systems or something. +[1:06:29] It's a lab that's still around today, I +[1:06:30] believe, but it has a slightly different +[1:06:32] name. I think it might have said it was +[1:06:34] even one of the longest running labs. +[1:06:35] Anyway, so hardcore, but there's another +[1:06:38] MIT uh sort it's sort of like it's not +[1:06:40] on the main campus in Cambridge. It's +[1:06:42] off in Lexington. It's called the +[1:06:43] Lincoln Laboratory. Also very prominent. +[1:06:46] And this is the other side of a story. +[1:06:48] Remember I said we have this thing where +[1:06:50] C Horus is saying, I got these ideas +[1:06:52] from Ross. He was pretty cool. And then +[1:06:54] we also have that Allen uh that Alan K +[1:06:57] part where he's talking about hey +[1:06:58] sketchpad. So we haven't talked about +[1:07:00] the sketch part. We found out about Ross +[1:07:02] and he was hardcore. What about +[1:07:03] Sketchpad? How hardcore is that? Well, +[1:07:06] this is Ivan Sutherland. He's the guy +[1:07:08] who made Sketchpad largely by himself. +[1:07:11] Like he pretty much wrote it again lone +[1:07:13] wolf style. and he comes to the Lincoln +[1:07:16] laboratory in the summer of 1960 uh as +[1:07:19] an intern originally but he ends up +[1:07:21] doing his PhD uh at MIT here. So this is +[1:07:26] what he's doing. And in the course of +[1:07:29] there's these computers called the TX +[1:07:30] series. There's like TX0 and TX2 and +[1:07:33] they're basically made by this guy named +[1:07:36] uh Wes Clark is at MIT and they're like +[1:07:38] they're making the computers, right? I +[1:07:40] mean that's the way this stuff worked +[1:07:42] back then is like the university +[1:07:43] actually had to make computers that they +[1:07:45] would use because nobody knows like what +[1:07:47] a computer even is yet and they're like +[1:07:49] building different versions of them and +[1:07:50] figuring out what the heck's going on. +[1:07:52] And this TX series of computers, they +[1:07:54] were pretty unusual because they +[1:07:56] actually had a display. +[1:07:58] Like we're back in the 1950s, right? So +[1:08:02] the idea that a computer was going to +[1:08:03] draw a picture for you that wasn't on a +[1:08:06] plotter that would like draw on a piece +[1:08:08] of paper is like completely unheard of. +[1:08:10] Like no one's doing anything like that. +[1:08:12] It's very rare. And so there's only a +[1:08:14] few places in the world that even have a +[1:08:16] computer that can display something. But +[1:08:18] the TX series of computers can. And this +[1:08:21] this guy who was architecting them, that +[1:08:22] Wes Clark guy, uh he was very forward +[1:08:25] thinking as well. And he was basically +[1:08:26] saying, "I think there's something here. +[1:08:28] I'm going to make it so it can integrate +[1:08:30] with a light pen that can like see +[1:08:32] what's on the CRT, and I'm going to like +[1:08:34] have the CRT be able to display stuff +[1:08:35] that the computer has." So, he makes +[1:08:37] this new computer called the TX2, which +[1:08:38] is an iteration of TX0. There's no TX1, +[1:08:41] I'm told. I don't know the story behind +[1:08:42] that, but he makes thing called the TX2. +[1:08:45] And obviously when you make something +[1:08:46] like this, it's hard to get time on it +[1:08:48] because it's just there's this one that +[1:08:49] was built. But he makes this and it's +[1:08:52] under a thing for the Air Force, the US +[1:08:54] Air Force, where they don't really care +[1:08:57] what you do with this computer. They +[1:08:59] were funding it not because they wanted +[1:09:01] MIT to compute something for them, but +[1:09:04] because they wanted MIT to figure out +[1:09:07] what happened with large trans like +[1:09:10] large arrays of transistors for +[1:09:11] computing like like if we make big +[1:09:12] computers, what happens? So this is very +[1:09:15] helpful because it means that the +[1:09:18] computing time on the computer isn't +[1:09:21] necessarily being taken up by some +[1:09:23] specific grant thing that they have to +[1:09:25] do. It's more flexible. +[1:09:28] So Ivan Sutherland manages to convince +[1:09:31] Wes Clark that he's got this idea for +[1:09:34] being able to draw on the surface of the +[1:09:36] thing, make like a drawing program. +[1:09:39] Could he have a slot on the TX2? And +[1:09:43] thank God West Clark said yes +[1:09:46] because from then on Southerntherland +[1:09:49] went in at 4 in the morning because that +[1:09:52] was the slot that was open to work on +[1:09:54] this thing. That's the TX2. And that +[1:09:57] right there is the uh is actually +[1:10:00] Sketchpad running. And so he would work +[1:10:02] on this. And I mean when I say work on +[1:10:05] this, you'll notice it's not like a +[1:10:06] keyboard here. You're not like typing in +[1:10:08] code into an editor. It was still like +[1:10:10] had to be manually entered in various +[1:10:12] ways, right? There was actually like a +[1:10:13] secretary who would enter some of it. He +[1:10:15] entered some of it, right? It's like so +[1:10:17] it's very laborious to develop things in +[1:10:18] the 1950s. Again, just to kind of hammer +[1:10:20] that home, these guys did not have much +[1:10:22] to work with, but he's working on this +[1:10:24] sketchpad program. And what you could do +[1:10:26] with it is stuff that we completely take +[1:10:28] for granted today as stuff you could +[1:10:30] just do. You could do things like draw +[1:10:32] lines with the light pen just like we +[1:10:34] would with a mouse. And it's actually +[1:10:36] fairly intelligent. It knows things like +[1:10:38] snapping. Like if you go and you're +[1:10:40] going to connect back to a point, it +[1:10:42] knows that it's it's not stupid, right? +[1:10:44] So it's not just doing random line +[1:10:45] drawing. It's thinking about those lines +[1:10:46] as well. We'll talk a little bit more +[1:10:48] about that because there's a lot more to +[1:10:49] cover there. But Alan K, who I said was +[1:10:52] the person who got us into this in the +[1:10:54] first place. The reason we're looking +[1:10:54] into it, he calls Sketchpad, the +[1:10:57] eventual thesis that Ivan Sutherland +[1:10:59] would publish on it, he calls it the +[1:11:00] most significant single thesis ever +[1:11:04] done. He says that it was like so +[1:11:06] impactful and so important not just to +[1:11:08] him but to everybody and honestly he's +[1:11:12] probably right. Out of sketchpad comes a +[1:11:15] lot of research in computer graphics. It +[1:11:16] comes the whole object-oriented concept +[1:11:18] from Alen K. Uh the the whole idea of +[1:11:21] interacting with computer in this way is +[1:11:23] very very new. CAD and the idea of a CAD +[1:11:26] program kind of comes out of this as +[1:11:28] well. +[1:11:29] Now it's so early in computing. I just +[1:11:33] want to hammer home one more time the +[1:11:35] kinds of things that Sutherland talks +[1:11:37] about if you read about his experience +[1:11:38] with Sketchvad developing at the time +[1:11:40] when he published the thesis. +[1:11:42] No one's ever even thought about like if +[1:11:46] I want to draw a line and then change +[1:11:48] where it is, I don't have to erase the +[1:11:50] line anymore. I could just move where it +[1:11:53] is. This is a completely new concept +[1:11:56] that no one's ever thought about before +[1:11:58] because for the rest of history, if you +[1:12:00] drew a line, you had to at least remove +[1:12:02] that line before you drew it again. +[1:12:04] Right? So, they're literally figuring +[1:12:07] out here in real time the kinds of +[1:12:10] paradigms that we just take completely +[1:12:12] for granted when you sit down to use a +[1:12:13] computer. The fact that you can move +[1:12:14] things around by pointing at them, +[1:12:16] completely new. That's what we're +[1:12:18] talking about here. +[1:12:20] Another example of that is rubber +[1:12:22] banding. +[1:12:24] They were thinking, "Oh, when you draw a +[1:12:25] line, you must have to move the light +[1:12:26] pen along the line to draw the line, +[1:12:28] just like you would with a T-square or +[1:12:30] something like that, right?" And they +[1:12:32] were like, "Wait a minute. We could just +[1:12:34] have the light pen attach the end of the +[1:12:37] line and move it around until you got it +[1:12:39] where you want it and then you could let +[1:12:40] go and that would be where it was." So +[1:12:42] even basic stuff like this was news to +[1:12:44] them. They were discovering it, right? +[1:12:47] So it's really, really early. That's how +[1:12:48] early we're talking about. +[1:12:51] Now, as fate would have it, when he's +[1:12:53] working on this program, who walks in, +[1:12:55] but Mr. Douglas Ross, they were at +[1:12:58] separate laboratories, but they did talk +[1:13:00] to each other a lot. And the reason for +[1:13:02] that was because Ross' group is working +[1:13:05] on CAD. They're not displaying much +[1:13:08] about it, right? They're not working +[1:13:10] interactively, but they're trying to do +[1:13:12] these like machined creations that are +[1:13:14] based on human input. +[1:13:17] So because Sutherland's pretty new to +[1:13:19] this stuff, he talks to Ross and he's +[1:13:22] like, "How do I make stuff like lines? +[1:13:24] Like, how do I do that kind of data +[1:13:25] modeling in the computer? Do you guys +[1:13:27] have ideas?" And Douglas Ross is like, +[1:13:29] "Have I got an idea for you? It's called +[1:13:31] a Plex, right?" And as we saw, Plex is +[1:13:35] pretty awesome. And Ivan Sutherland is +[1:13:37] probably one of the smartest people on +[1:13:38] planet Earth. So he recognizes right +[1:13:40] away this is a good idea, too. So he's +[1:13:43] like, "All right, we're doing it." +[1:13:44] Right? He says, "What I'm going to be +[1:13:47] making this program to do is have a +[1:13:49] bunch of like primitives, right? Like +[1:13:50] I've got lines and things like that that +[1:13:52] I'm going to create. And I don't have +[1:13:54] that many types of things. Like I'm just +[1:13:56] going to have like lines and you know +[1:13:57] later uh actually it was Claude Shannon, +[1:13:59] the father of information uh theory, +[1:14:01] right? Who says you should put circles +[1:14:04] in it too?" So there's all these kind of +[1:14:05] like little answers. If you actually go +[1:14:07] read this yourself, you'll find there's +[1:14:08] so many things I couldn't fit in this +[1:14:09] lecture because it would have been like +[1:14:10] eight hours, right? But anyway, so he's +[1:14:12] saying we're going to have all these +[1:14:13] instances of things, lots of lines and +[1:14:15] stuff like that. So I don't really need +[1:14:17] anything more than just this n component +[1:14:19] thing and I'll just have lots of those +[1:14:21] and that's how we'll do it. This is how +[1:14:22] I'm going to write the program. And here +[1:14:25] is his diagram from his thesis about how +[1:14:27] he's going to structure, right? How or +[1:14:29] how he did structure lines and points, +[1:14:32] right? And there's some information +[1:14:33] missing from this because, you know, I +[1:14:34] mean, if you're sketching things in +[1:14:35] Sketchpad with that light pen and it's +[1:14:37] very slow, right? It's not he can't make +[1:14:39] slides with software like we have today. +[1:14:40] Not that the software I used to make the +[1:14:42] slides was particularly better than +[1:14:43] Sketchpad, but you get the idea. Um, so +[1:14:46] it's not completely documented in here, +[1:14:47] but you know, you can see here it's got +[1:14:49] the line, it's got a pointer to each of +[1:14:50] the points and so on and the coordinates +[1:14:52] sort of sketching that out. And hey, +[1:14:54] it's exactly like that paper from Doug +[1:14:56] Ross, right? And Doug Ross published +[1:14:59] this in 1960s. So Ross and his team were +[1:15:02] already thinking along these lines +[1:15:03] before Southerntherland even got to the +[1:15:05] lab, right? And started working on +[1:15:07] Sketchpad in the later a little bit +[1:15:09] later in the early 60s. So that's how +[1:15:11] this this whole thing ties together. +[1:15:13] Ross and Sutherland are like having a +[1:15:15] huge party here and it's awesome. +[1:15:18] And if you remember, we had these things +[1:15:20] in the Plex that were basically like +[1:15:22] jumps, right? They were like sub +[1:15:23] routines. They were the virtual +[1:15:24] functions at the time or we maybe would +[1:15:26] call them uh not so virtual functions, +[1:15:28] although you could implement that way. +[1:15:29] We just called them function pointers, +[1:15:30] right? And you can do all the same +[1:15:31] things you can do with a function +[1:15:32] pointer. That was something that Doug +[1:15:34] Ross was talking about in his plexus in +[1:15:35] the original paper and it's right there +[1:15:39] in Sketchpad as well. This is how he did +[1:15:42] things like I want to go ahead and draw +[1:15:44] this shape but I don't want to bother +[1:15:46] having actual different data types uh be +[1:15:49] completely specialized having having the +[1:15:50] routines completely specialized. So what +[1:15:51] I'll do is I'll just have like a few +[1:15:54] entries in the data type that say how +[1:15:55] will I display it what's what would I +[1:15:57] jump to to display it to figure out how +[1:15:59] big it was or to move it. So again, +[1:16:02] virtual functions right there. They come +[1:16:04] from the plexes. He puts it in and that +[1:16:06] is how he actually implemented that kind +[1:16:08] of like parametric behavior in this +[1:16:11] program in in Sketchpad. +[1:16:14] Now, +[1:16:16] because we've already got one applause +[1:16:19] line before for this kind of thing, I'll +[1:16:22] just point out there's empty space in +[1:16:25] between these things here. And on the +[1:16:27] previous one, I was like, well, the +[1:16:29] reason that there's empty space on those +[1:16:30] is because, you know, I probably didn't +[1:16:31] have time to to draw it out. And that +[1:16:33] was true for that diagram because I know +[1:16:34] more about the data structure because +[1:16:35] I've spent way too much time looking at +[1:16:37] this program. But in this one, those are +[1:16:41] actually space in the strct. Those +[1:16:45] fields there, there's there's gaps, +[1:16:47] right? So, why are there gaps? Why are +[1:16:50] there gaps in this thing? And I wanted +[1:16:52] to know. So, I'm coming through this +[1:16:53] like what are the gaps about, right? Is +[1:16:55] it just the same as the other one where +[1:16:56] it was like you just didn't draw it in +[1:16:58] there or something? What are the gaps +[1:17:00] about? I found it. At present, all +[1:17:02] generic blocks still carry space for all +[1:17:04] the information in any of them simply +[1:17:06] because of historical reasons. This +[1:17:08] accounts for the spaces seen in figure +[1:17:11] 37. What this means is +[1:17:14] Sketchpad is on Steam Team Fat Struct +[1:17:17] right in 1963. He was still doing the +[1:17:21] same thing that the Plex was doing. He +[1:17:22] was just saying, "Look, I don't really +[1:17:24] maybe I should have gone back and tried +[1:17:26] to figure out some way to compact these, +[1:17:27] but you know what? Uh, we didn't end up +[1:17:29] doing that." And so, he kind of just has +[1:17:30] that mentioned there. It's like, "Yep, +[1:17:32] all of them are the same size and we +[1:17:33] just leave those fields out if they +[1:17:35] weren't going to be there, right?" So, +[1:17:38] bending it a little bit there because it +[1:17:40] in the sketch paper, it's very hard to +[1:17:42] tell exactly the way because he doesn't +[1:17:44] give explicit data layouts for a lot of +[1:17:45] things. It's hard to tell whether or not +[1:17:48] he was using like things that always had +[1:17:51] fat strct or whether it was more like +[1:17:53] semi-istributed unions. So there were +[1:17:54] pairs of things that would have been +[1:17:56] used differently. So it's either team +[1:17:58] fatstruct or team overlay fatstruct but +[1:18:01] it's one or the other. +[1:18:04] All right. So we've come to the part +[1:18:05] where we can build our tree. As far as I +[1:18:07] can tell doesn't go any deeper than +[1:18:08] this. This is where it actually started +[1:18:10] for reals this time. Doug Ross and his +[1:18:13] team this idea of plexes. It goes to +[1:18:16] Ivan Sutherland because he works there +[1:18:17] and he asks us for their advice on how +[1:18:19] to build the stuff in Sketchpad and he +[1:18:21] picks up the Plex concept. It also goes +[1:18:24] to CH horror. That Plex uh concept goes +[1:18:27] to him because they sit on the algo +[1:18:29] committee together. So that's our first +[1:18:31] branch. We then have that horror paper +[1:18:34] was read by Dah and Nygard who decide to +[1:18:37] use it to create their simulass idea +[1:18:40] and both of those you know Simula and +[1:18:43] Sketchpad influence Alan K to create the +[1:18:46] small talk branch of oop. Meanwhile the +[1:18:50] experience with simula influences +[1:18:52] bejornstrip to create with classes and +[1:18:55] then C++. +[1:18:58] Now by the way this is an inheritance +[1:18:59] hierarchy that matches the domain model. +[1:19:06] But there's a fun part of it. +[1:19:09] Some of you may know this, some of you +[1:19:10] may not because I mean, why would you? +[1:19:12] Obviously, we know C++ has multiple +[1:19:14] inheritance. It got multiple +[1:19:15] inheritance. Not right away, but it got +[1:19:16] it eventually. Small talk never did +[1:19:19] single inheritance. +[1:19:21] However, single inheritance will get you +[1:19:24] C++, +[1:19:26] but it won't get you small talk. You +[1:19:28] need two parents, +[1:19:31] right? +[1:19:32] [Applause] +[1:19:35] What can I say? So, that's the actual +[1:19:38] end. Now, we've built our tree. We're +[1:19:40] finally done. We know where this stuff +[1:19:42] came from, +[1:19:45] right? It was long. +[1:19:47] Of course, there is a personal angle to +[1:19:50] this as well. So, I should probably say +[1:19:53] that the reason I decided to go do all +[1:19:56] this, it probably wouldn't be, you know, +[1:19:58] I'm on that thing called the internet +[1:20:00] all the time. And most of the time, I'm +[1:20:03] just going to post something snide as a +[1:20:05] reply and not think about it again. So, +[1:20:08] why did I actually go and do all this +[1:20:10] research just for this? Why didn't I +[1:20:13] just say, "Who cares about these things? +[1:20:15] I don't use those compile time +[1:20:16] hierarchies." And and just, you know, +[1:20:19] post something mean on Twitter. Why +[1:20:20] didn't I do that this time? It would +[1:20:22] have saved me a lot of time. Of course, +[1:20:24] I wouldn't have had anything to present +[1:20:25] today, but it would have saved me a lot +[1:20:27] of time. Well, here's why. Back in 1997, +[1:20:32] which by the way is right around the +[1:20:34] same time that we started this talk, +[1:20:35] right? The looking glass uh stuff that +[1:20:38] they did with entity component systems +[1:20:39] was 1998, which means they would have +[1:20:42] been working on it in 1997. It would +[1:20:44] have been up and running at that time. +[1:20:45] So, it's right at the same time. I'm +[1:20:48] working with a fellow called Chris +[1:20:49] Hecker and I'm brand new. Like I am I am +[1:20:52] literally out of high school so I don't +[1:20:54] know anything. Like I I programmed a ton +[1:20:56] as a kid but you know if you ask me you +[1:20:58] know uh my thoughts on computer +[1:21:00] architecture or something like that I +[1:21:02] obviously would have answered very +[1:21:03] confidently and been completely wrong +[1:21:05] about everything. So he says we're going +[1:21:08] to need a level editor. This is +[1:21:10] basically a game that we're working on. +[1:21:11] We need a level editor that does CSG on +[1:21:14] spheres. So the idea was you take these +[1:21:16] spheres and you build a level up out of +[1:21:18] like unioning them together, right? Like +[1:21:19] a standard CSG modeling kind of stuff. +[1:21:22] But of course I don't really know any +[1:21:24] CSG stuff. I have like really know how +[1:21:26] to do that. So I go using I think it was +[1:21:28] sightseer at the time like nowadays you +[1:21:30] might use like Google Scholar or +[1:21:31] something to search for papers. So I go +[1:21:34] to use like sightseer I think was up at +[1:21:35] the time or maybe there was a precursor +[1:21:36] to it and I can't remember the actual +[1:21:38] one but there were things at the time +[1:21:40] even then this early because the +[1:21:42] internet's you know not the internet's +[1:21:44] only been available to the public for a +[1:21:45] short time really like was arponet you +[1:21:47] know until the the mid9s right so when +[1:21:51] when we're looking at this I go to crawl +[1:21:54] papers and I'm like okay CSG on spheres +[1:21:56] like to try to type some things in read +[1:21:57] some papers you what am I going to do +[1:22:00] and I come across this thing called +[1:22:01] alphashapes and alpha Alpha shapes are +[1:22:03] just the name that someone in a paper +[1:22:05] had given us something that was +[1:22:06] basically implicit services. I don't +[1:22:07] really know why they called alpha shapes +[1:22:08] because it escapes me now. I'm sure I +[1:22:10] knew at the time because I just read the +[1:22:11] paper, but for some reason they're +[1:22:12] talking about these alpha shapes. I +[1:22:13] looked at I was like, oh, if it's like +[1:22:15] spheres, but when you move them +[1:22:16] together, they make this like nice +[1:22:18] smooth join. They don't make that hard +[1:22:20] edge. I was thinking, oh, for levels +[1:22:22] that would be like really cool. That +[1:22:23] might be like way better than if we did +[1:22:25] CSG on spheres because it would have +[1:22:26] this like really cool effect. So it was +[1:22:29] kind of be like on the inside of these +[1:22:31] things which are you know typically +[1:22:32] called metabols and it was going to be +[1:22:35] like sort of the negative space of the +[1:22:37] metabols. So I made a modeler for this +[1:22:40] and I called it mega man which has +[1:22:42] nothing to do with mega man completely +[1:22:44] legally legally distinct from that. It's +[1:22:46] kind of change one letter and maybe it's +[1:22:48] the same but nothing to do with this. +[1:22:49] It's just negative space metabols. And +[1:22:52] this is what it looked like. And +[1:22:54] effectively what you did is you, you +[1:22:56] know, picked things in it. You can see +[1:22:58] those spheres there are metabols. +[1:22:59] They're the kind of spheres you put +[1:23:00] together. And they form these kind of +[1:23:02] surfaces. And we're seeing the inside of +[1:23:04] what you're creating, right? Because +[1:23:05] it's a negative space. So that's why it +[1:23:06] looks kind of weird. You would normally +[1:23:08] see the outside in a metabol modeler. +[1:23:10] But this is what I was working on. Well, +[1:23:12] I I mean, and it's finished. Like you +[1:23:14] can use it. I still have to this day. +[1:23:15] You can model stuff around. It's it's +[1:23:17] pretty janky, but it it does what it's +[1:23:18] supposed to do, right? And so the way +[1:23:21] that you interacted with it is you like +[1:23:22] picked those spheres and you could move +[1:23:25] them around by dragging the mouse and +[1:23:26] that sort of stuff. The same sort of +[1:23:27] things, right, that like Sketchpad was +[1:23:29] doing only, you know, with much better +[1:23:31] hardware and and much more advantages in +[1:23:33] ter of development. Same kind of idea +[1:23:34] because, you know, like Southerntherland +[1:23:36] was so far ahead, right? And so if you +[1:23:39] wanted to create stuff, you might select +[1:23:41] things like here. I don't know if you +[1:23:42] can see it. selected those two metabols +[1:23:44] at the top and then I've just like inst +[1:23:46] there's a thing you could like rapidly +[1:23:47] stamp them down. I kind of just drag +[1:23:48] them and like stamp stamp stamp stamp +[1:23:50] and you can create more of the level +[1:23:51] just kind of like blobbing things +[1:23:52] together. +[1:23:54] So it was a selection based UI like most +[1:23:56] programs are where I select a bunch of +[1:23:58] things and then I wanted the program to +[1:23:59] basically have a nice architecture for +[1:24:01] being able to do that and then present +[1:24:03] the user with the user interface that +[1:24:05] would be appropriate for that selection. +[1:24:08] And this is actually a really hard +[1:24:10] architecture problem if you're not +[1:24:13] experienced which I wasn't because it's +[1:24:15] like well if what you've been told is +[1:24:17] that you make these hierarchies like +[1:24:19] these class hierarchies and things like +[1:24:20] that and what we're really saying is I'm +[1:24:22] going to select all these things that +[1:24:23] are really derived types of things but +[1:24:26] now I want this higher level thinking +[1:24:28] thing to look across everything that +[1:24:30] you've selected and come up with a plan +[1:24:33] for what the unified interaction would +[1:24:35] be across those things. And then when +[1:24:37] you actually want to do the interaction, +[1:24:39] it's got to make sense for what's going +[1:24:40] on. And this is really tricky because +[1:24:42] the inheritance thing doesn't help you +[1:24:43] at all for this. It fights you. You're +[1:24:45] constantly like, "Oh, do I just add a +[1:24:46] bunch of like functions to the base +[1:24:48] class that's anything you might want to +[1:24:50] do to a class? Do you basically fatty +[1:24:52] structure interface, right, but leave +[1:24:54] the hierarchy in place? There's all +[1:24:55] these things you might think to do and +[1:24:57] they just don't work very well." But I +[1:24:59] was, you know, pretty gung-ho at the +[1:25:00] time. Uh, you know, I'm not old like I +[1:25:02] am now. So, at the time, I don't mind +[1:25:03] typing a lot. So, I go to town on this. +[1:25:06] And I'm like, "All right, I'm going to +[1:25:07] try to figure out how to do this +[1:25:09] cleanly, +[1:25:11] quote unquote." +[1:25:12] And we end up with crap like this. Now, +[1:25:15] a lot of times I try to convince people. +[1:25:17] I'm like, "Look, +[1:25:18] everyone thinks that I was like some C +[1:25:21] only programmer. I just don't know +[1:25:23] anything about like huge crazy hairy +[1:25:25] object-oriented programming or anything +[1:25:27] like that. It's just like you don't +[1:25:28] understand." It's like, "No, dude. I +[1:25:31] wrote some of the most ridiculous oop +[1:25:34] stuff you have ever seen when I was like +[1:25:36] 20. I was doing crap like this all the +[1:25:39] time. It was awful. I'm not proud of it. +[1:25:42] But here is what's going on. Right. So, +[1:25:44] the way I chose to solve this problem, +[1:25:47] never mind the fact that like I'm doing +[1:25:49] the implementation inheritance thing up +[1:25:50] there with with a template on the class. +[1:25:53] This if you've ever seen this trick, +[1:25:54] it's an old school. So, it's like +[1:25:56] there's so much stuff in this codebase. +[1:25:57] You would it's a nightmare. But anyway, +[1:26:00] so if you look at what's going on here, +[1:26:01] I have get and set functions like you're +[1:26:02] supposed to have on any proper object +[1:26:06] and you can get the center, you can set +[1:26:08] the center, that sort of thing. Get the +[1:26:09] service radius, set the service radius, +[1:26:10] right? And now what I want to do is I +[1:26:13] want to have some way that these can be +[1:26:14] interacted with in a unified way. So +[1:26:17] what do I do? Anytime you create one of +[1:26:19] these things, I build a parallel +[1:26:22] structure. I create a property list that +[1:26:25] basically is callbacks using this is +[1:26:28] called a rich hickey functor. I'm not +[1:26:31] kidding. It was a callback that you +[1:26:34] could use to do type safe callbacks back +[1:26:36] in the early days of C++. +[1:26:39] I'm trying to tell where is the camera? +[1:26:41] Seriously, like I have done ridiculous +[1:26:44] oop stuff. You if you don't believe me +[1:26:46] after seeing this, I do not know what to +[1:26:48] tell you. We can post more of this code +[1:26:50] if we need to. +[1:26:52] So anyway, so basically when it's +[1:26:54] created, it creates a parallel hierarchy +[1:26:55] that's just it's not actually the +[1:26:57] properties. It's just callbacks that +[1:26:59] would get and set the properties, right? +[1:27:02] And then you know this this is what that +[1:27:04] class looked like, right? Here's the get +[1:27:06] and set callbacks abstracted into a +[1:27:08] property. And then if you wanted to use +[1:27:09] it, you could loop over the properties. +[1:27:12] you could create a modification +[1:27:15] that was typed on the property, right, +[1:27:19] to do the changes you actually wanted to +[1:27:21] do. +[1:27:23] Okay? And that's to support like +[1:27:25] dragging and undo and things like that. +[1:27:28] So this is what it looked like if you +[1:27:30] drew it out. I have a metabol +[1:27:32] and center. The data is in the metabol, +[1:27:35] right? Just like a good object-oriented +[1:27:37] programming uh thing would tell you to +[1:27:39] do. It's encapsulated inside the +[1:27:40] metabol. I create parallel I call them +[1:27:44] property universes. I create property +[1:27:46] universes. All of the center properties, +[1:27:49] all of the radius properties and they +[1:27:51] are callbacks +[1:27:54] to modify or retrieve the data in the +[1:27:57] actual entity here, right? The metabol. +[1:28:00] And then when you interact with it, you +[1:28:02] use modifications to interact. And this +[1:28:05] way when I wrote the code I could think +[1:28:08] about things in terms of the center or +[1:28:10] in terms of the radius. So what I do is +[1:28:12] when you multi-selected I'd go what are +[1:28:14] all the property types that you've had +[1:28:17] and I'll just make interactions that +[1:28:19] work with those property types and I'll +[1:28:20] put up little UI elements that work with +[1:28:22] those property types. If the diagram +[1:28:25] looks familiar to you it's because you +[1:28:26] have a good memory because this talk is +[1:28:28] very long. +[1:28:30] If I had a brain I would have realized +[1:28:32] you don't need that. just put the +[1:28:34] properties in the actual universes +[1:28:37] themselves and use an ID for lookup and +[1:28:39] it's an entity component system. It's +[1:28:42] the same architecture. It's just I +[1:28:44] sucked at it and looking glass was good. +[1:28:47] That's the difference, right? +[1:28:52] So anyway, this was the slide I showed +[1:28:55] at the beginning. This is the slide that +[1:28:57] I did. You see what I'm talking about, +[1:29:00] right? +[1:29:02] My bad, right? This was my bad. I +[1:29:05] screwed up. I say that I don't blame +[1:29:07] myself because I was a kid, but really, +[1:29:10] I mean, I should have thought it +[1:29:11] through. So, anyway, +[1:29:14] in 2024, when I was accidentally on the +[1:29:17] internet, like I should not have been, +[1:29:20] I'm thinking to myself, +[1:29:27] how the heck did Sketchpad do this +[1:29:28] anyway? because they must have had like +[1:29:31] the same problems that I had because he +[1:29:33] could do all this stuff. It wasn't just +[1:29:35] a shape drawing program. I withheld some +[1:29:38] information from you if you've never +[1:29:39] seen Sketchpad before. I apologize. It's +[1:29:41] for dramatic effect. It's worth it. +[1:29:43] Trust me. It could do a lot of other +[1:29:45] stuff than just draw. The just drawing +[1:29:48] stuff is the stuff that like Adobe +[1:29:50] copied or things like that because that +[1:29:52] was the part that they could understand. +[1:29:55] The hardcore stuff only Sutherland knows +[1:29:57] how to do. And here's what that looks +[1:29:59] like. You could say, "I want these lines +[1:30:01] to be like perpendicular to each other." +[1:30:03] And it would do it right. You could take +[1:30:06] a drawing like this and pick a point +[1:30:09] that's not even a point. It's the +[1:30:11] intersection of two lines and not just +[1:30:14] snap, but say I want this radius +[1:30:19] from now on to always have its center +[1:30:23] point, like the circle arc. It's going +[1:30:26] to be drawn around that intersection and +[1:30:28] not for snapping but for always. So that +[1:30:32] if I then go do some constraints on this +[1:30:34] thing which Sutherland's about to do. +[1:30:35] He's going to say make that +[1:30:36] perpendicular to that perpendicular to +[1:30:38] that perpendicular to that which you +[1:30:40] can't do in anything from Adobe right to +[1:30:43] go get AutoCAD or something for this. +[1:30:45] And by the way AutoCAD didn't add it +[1:30:47] till like 2007 or something like this. +[1:30:49] They didn't have it in AutoCAD Flint. +[1:30:51] Right? +[1:30:53] When you tell it those things, you say, +[1:30:55] "Okay, that's what I want my shape to +[1:30:56] be." It'll just solve it for you. And if +[1:30:58] you move it, move the points around, +[1:31:01] it'll solve it again into whatever the +[1:31:04] closest shape is, right? Using like a +[1:31:06] relaxation le squares kind of thing. +[1:31:09] And I'm like, "What the heck?" I +[1:31:12] remember this. It's, you know, because +[1:31:14] I'd seen this demo before. And I'm +[1:31:17] sitting there thinking, you know, that +[1:31:19] whole compile time hierarchy thing and +[1:31:21] Allan Case like he saw Sketchpad and I +[1:31:23] I'd known those parts, you know, all the +[1:31:25] details I had to learn for this talk, +[1:31:27] but like I'm like, what the heck did he +[1:31:29] do? He's working on this like crap +[1:31:32] computer. I get that he's way smarter +[1:31:34] than me, so fair enough. But he still +[1:31:37] had to do something, right? So what did +[1:31:39] he do? What does a really smart person +[1:31:41] do when they're faced with this +[1:31:43] situation? because he's creating stuff +[1:31:45] that people who came after him who have +[1:31:47] like crazy debuggers and wizzywig +[1:31:50] editing and the ability to run things +[1:31:51] quickly and iterate, he they don't have +[1:31:53] to go in at 4 in the morning and enter +[1:31:54] things manually into a computer. +[1:31:57] How did he do it? Because no one did it +[1:31:59] afterwards for decades. +[1:32:04] So let's take a look. +[1:32:06] If we go in and we look at how he +[1:32:08] represented constraints, he represented +[1:32:10] constraints by saying there's going to +[1:32:12] be variables that are constrained. So +[1:32:14] I'm going to have some variables things +[1:32:16] like uh this point or this line that +[1:32:19] sort of thing would be considered a +[1:32:20] variable in the system. Something that +[1:32:22] is like a very primitive element of the +[1:32:24] system. So it could do that. You'd pick +[1:32:27] those and then you would have a certain +[1:32:28] type of the constraint essentially which +[1:32:30] is like what you know what am I actually +[1:32:32] going to be doing with this particular +[1:32:33] constraint. But they're relatively +[1:32:34] generic in this way. +[1:32:36] And then the things you could constrain, +[1:32:38] scalers, points, this is text, digits, +[1:32:40] and dummies. These are the different +[1:32:41] things you could constrain. They're sort +[1:32:43] of all like again, you know, sort of uh +[1:32:45] almost team fat struck there, right? +[1:32:47] They're kind of like all things you can +[1:32:49] reference as a variable without needing +[1:32:50] to know which one you're looking at. +[1:32:54] And so you can remember when we were +[1:32:56] looking, we were talking about here's +[1:32:57] how those lines of the line would not +[1:33:00] necessarily be something that was +[1:33:02] constrained, right? because it's kind of +[1:33:04] a it's a bigger thing than these are. Uh +[1:33:06] but the points would potentially be +[1:33:08] something that was constrained, right? +[1:33:10] So you might say things about them in +[1:33:11] that way. And I don't know all the +[1:33:13] specifics of how the constraints worked +[1:33:15] because he doesn't publish like in the +[1:33:17] thesis it only talks about to a limited +[1:33:18] degree. So I can't give you a perfect +[1:33:20] breakdown of exactly every piece of the +[1:33:22] system, but I mind as much out of it as +[1:33:24] I could. +[1:33:26] And he goes on to talk about how this +[1:33:28] thing was architected so that he could +[1:33:29] solve things. He said the ring structure +[1:33:33] which we have not looked at yet was +[1:33:35] designed to permit rapid constraint +[1:33:37] satisfaction. So what is this ring +[1:33:40] structure? What does he mean by that? +[1:33:41] But he's pinning it on that. He's like +[1:33:43] saying the ring structure was really +[1:33:45] important and that's what's letting us +[1:33:46] do this stuff. +[1:33:48] He also says all references made to a +[1:33:51] particular end component element or +[1:33:52] block are collected together by a string +[1:33:53] of pointers which origin that block +[1:33:56] which is kind of a type of ring +[1:33:58] structure, right? And he says this, +[1:34:00] which really throws you for a loop when +[1:34:02] you're first reading the thesis. In the +[1:34:03] data storage structure, the separation +[1:34:05] of general specific is accomplished by +[1:34:07] collecting all things of one type +[1:34:08] together as chickens which belong to a +[1:34:11] generic hen. +[1:34:14] Now, I will save you the trouble, those +[1:34:16] of you who want to read this thesis +[1:34:19] about what those mean. +[1:34:22] A hen is a sentinel of a linked list. A +[1:34:26] chicken is a link in a linked list that +[1:34:30] points back to the sentinel ex +[1:34:32] essentially, right? +[1:34:35] So +[1:34:37] here is how the data is laid out. Type +[1:34:41] is a chicken. Link quote unquote. +[1:34:45] Specb is a hen. So now when we go back +[1:34:48] to this uh type that we've already +[1:34:50] looked at, we can see them up there at +[1:34:51] the top. Type is the chicken. Spec B is +[1:34:54] the hen. This is sort of the workhorse +[1:34:57] of the structural elements of this +[1:34:59] system. And the way that it works is +[1:35:02] that chicken at the top links it into a +[1:35:05] giant linked list with all of its +[1:35:07] siblings at its level of whatever it's +[1:35:09] doing. And the specb hen is the sentinel +[1:35:13] for the list of all the things that are +[1:35:14] like subordinate to this thing. So it's +[1:35:16] like an up and down kind of a thing +[1:35:17] that's going on there, right? So chicken +[1:35:20] and hen. +[1:35:23] Here is how he actually draws it. You +[1:35:25] can see it's just a like list exactly +[1:35:27] like we expect. Key or hen threw me for +[1:35:30] a long time until I got it. Key or hen +[1:35:33] just means hen. For some reason in the +[1:35:36] paper he has he never says what a key is +[1:35:38] until this one part where he's like +[1:35:40] sometimes I also call a hen a key. +[1:35:46] So anyway, +[1:35:48] okay. He then goes on to present this +[1:35:51] and this is the runtime structure of +[1:35:55] sketchpad. You start with a universe and +[1:35:58] it has a sentinel or hen, right? It has +[1:36:02] a sentinel that has a ring inside of +[1:36:04] which is variables, holders, +[1:36:06] constraints, and topos. Again, not a +[1:36:08] compile time hierarchy, actually a +[1:36:09] runtime set of rings, right? So this is +[1:36:12] not baked into the compilation of this +[1:36:14] program in any particular way. It's just +[1:36:15] how the rings are structured at runtime +[1:36:17] when they are built. There are +[1:36:19] variables, holders, constraints, and +[1:36:21] topos. The ones we care about in this +[1:36:22] case, we don't really care about the +[1:36:24] holders much for understanding. But the +[1:36:26] topos are lines, circles, and pictures. +[1:36:27] Pictures are just like copies of things +[1:36:29] like copies of other drawings, right? So +[1:36:32] the topos are the things that we're +[1:36:33] actually sort of the user interacting +[1:36:34] with. Um, at a higher level, the +[1:36:37] variables sometimes like they see points +[1:36:39] and things like that or text things they +[1:36:40] can edit. The topos are made up of those +[1:36:43] variables, right? A line is made up of +[1:36:45] points and then the constraints are +[1:36:48] things that you apply to them. Now, it's +[1:36:50] important to notice this is sort of you +[1:36:53] could say the opposite of encapsulation. +[1:36:56] What this structure implies is that at +[1:36:58] any time any part of the system can go +[1:37:01] looking at anything. It's almost like a +[1:37:03] complete introspection system for what's +[1:37:05] going on. A topo, for example, that is a +[1:37:09] line is not encapsulated at all. the two +[1:37:13] points that make it up are just floating +[1:37:15] in the breeze over there that you can go +[1:37:17] just grab, right? And you can do +[1:37:19] whatever you want to those points +[1:37:20] without that thing even knowing that it +[1:37:23] happened, right? So, it's almost like +[1:37:25] the most unencapsulated thing that you +[1:37:27] could possibly imagine, which is +[1:37:29] probably why it was so cool. +[1:37:32] But if we draw it, +[1:37:35] oops. Well, it kind of looks like this, +[1:37:37] right? The topos, you have a circle. +[1:37:39] It's got a radius and a center. It has +[1:37:41] pointers out to those actual things +[1:37:44] which we call variables. Those are the +[1:37:45] scalers. Those are the points. And if we +[1:37:47] have something like constraints, it's +[1:37:48] going to operate on them. It just points +[1:37:51] into those things. And all of these +[1:37:53] pointers are typically like birectional. +[1:37:55] Like that ring structure is allowing you +[1:37:57] to walk in both directions if you want +[1:37:59] to, right? But this is the way that +[1:38:01] you're actually like conceptualizing the +[1:38:03] link in those cases. +[1:38:06] Once again, the same diagram more or +[1:38:10] less than what I had to write, +[1:38:13] which is the same diagram more or less +[1:38:15] than an entity component system is +[1:38:18] because you are able to iterate over all +[1:38:21] of the properties you want to work with, +[1:38:23] which lets you implement things like a +[1:38:25] constraint or in my case a modification, +[1:38:27] right? in this generic way that operates +[1:38:31] on the pieces of things or components in +[1:38:33] any component system language in a way +[1:38:35] that doesn't require this sort of weird +[1:38:37] abstraction thought where you're trying +[1:38:38] to figure out how to get things out of +[1:38:40] something in order to work on them. +[1:38:44] That was in 1963. +[1:38:48] So to a first approximation, +[1:38:52] Ivan Sutherland was at the same level of +[1:38:57] closeness to an ND component system in +[1:38:59] 1963 +[1:39:00] as I was in 1997. +[1:39:08] And then people from there +[1:39:10] didn't notice. +[1:39:12] That's the only thing I can figure out. +[1:39:14] I have not found anything except for one +[1:39:17] quote that I'll show you that explains +[1:39:20] why the heck no one realized how +[1:39:22] important this was. +[1:39:25] They didn't think about the fact that +[1:39:27] the power of this system is coming from +[1:39:30] the fact that you can look at these +[1:39:32] components of things and architect +[1:39:35] around that instead of architecting +[1:39:37] around the bag which who cares. Again, +[1:39:41] still object-oriented in its thinking. +[1:39:42] You don't have to claim it's not oop, it +[1:39:45] can still be ubo. It's just where are +[1:39:46] the encaps those encapsulation +[1:39:48] boundaries, where are the boundaries, +[1:39:50] right? Instead of looking at it and +[1:39:52] going, "Oh, the important place to put +[1:39:54] the boundary was around this. That's +[1:39:55] where the power is coming from." They're +[1:39:57] looking over here. They're like, "The +[1:39:59] power of this system was that the +[1:40:02] ability to have virtual functions on it, +[1:40:05] right? The ability to say if I want to +[1:40:07] draw this a different way, I change the +[1:40:08] sub routine." Now, I'm not trying to say +[1:40:11] that isn't useful. It's function +[1:40:13] pointers are good in certain +[1:40:14] circumstances, but what inevitably +[1:40:17] happens is they're only going to get you +[1:40:19] the simple stuff. The only reason that +[1:40:21] even worked for Southerntherland in the +[1:40:23] display case is because his display was +[1:40:26] simple. He didn't have to do things like +[1:40:28] intersecting stuff for hidden line +[1:40:29] removal or doing some kind of calling on +[1:40:31] it or who knows what. So, he could just +[1:40:34] have an abstract display function +[1:40:36] because it never interacted with any +[1:40:37] other part of the system. It's the least +[1:40:39] interesting part of this architecture. +[1:40:41] Yes, it's cool. It's Doug T. Ross's idea +[1:40:45] about Plexes. It's where it comes from, +[1:40:47] right? And that was a great idea and we +[1:40:49] should keep it. But it's not the cool +[1:40:51] part of Sketchpad at all. Right? It's +[1:40:55] the most trivial part of it. So, that is +[1:40:59] the 35-year mistake. Oops. Right? We +[1:41:03] have the answer. We could have been so +[1:41:06] far ahead if we just studied that and +[1:41:08] figured that out because it's so much +[1:41:10] more powerful to think about systems +[1:41:11] that way especially the hardest kinds of +[1:41:14] systems like editors. +[1:41:17] This is the quote I was talking about. +[1:41:19] So you can see here this is Alen K, +[1:41:23] father of small talk +[1:41:26] and this quote breaks my heart because I +[1:41:28] like Alen K. I think everyone likes Alen +[1:41:30] K probably. I don't know maybe not +[1:41:32] probably someone out there who hates +[1:41:33] Alen K. Alan K is very sorry. He was +[1:41:35] trying all sid kinds of cool things. +[1:41:37] Xerox Park is awesome. I'm not gonna say +[1:41:39] something negative about Alen K. I'm +[1:41:40] just not gonna do it. +[1:41:43] This quote breaks my heart because what +[1:41:44] he says in this quote is basically that +[1:41:48] the constraint solver which he obviously +[1:41:51] knew about. So he because I happen to +[1:41:54] know that Alen K read the thesis that's +[1:41:56] documented. Alan K says he read the +[1:41:57] thesis and he paid attention to the +[1:42:00] constraint solver part and he paid +[1:42:02] attention to it enough to know that what +[1:42:04] he called it omnisient he was calling it +[1:42:07] omnisient right this idea that it could +[1:42:10] look at the properties like that and +[1:42:12] work on them and K thinks it's a bad +[1:42:15] thing right he says hey there's this +[1:42:18] thing called Alan Bing's thing lab which +[1:42:20] is another program that was made later a +[1:42:21] first attempt to go beyond touchpad and +[1:42:23] he devised a nice approach for dealing +[1:42:25] with constraints that didn't require ire +[1:42:26] the solver to be omnicient. +[1:42:29] The omnicient part was the good part, +[1:42:31] right? That was the thing that was so +[1:42:34] powerful. It's why it's kind of +[1:42:35] torturous to make things in small talk. +[1:42:37] I have dabbled in it a little bit. It's +[1:42:39] like no, the encapsulation needs to be +[1:42:42] in the right place. You don't want to +[1:42:43] think of everything as these small +[1:42:44] little objects. So why did they why was +[1:42:47] Alen K so focused on that stuff? Why was +[1:42:49] Strus so focused on that stuff? And +[1:42:52] honestly, from reading it, oops, didn't +[1:42:55] mean to advance there or to go back +[1:42:57] there. From reading it, this is my best +[1:43:00] guess. Their backgrounds predisposed +[1:43:04] them not to want this, right? You look +[1:43:07] at where they come from. Strus comes +[1:43:10] from distributed systems. Alan K had a +[1:43:12] degree in molecular biology. They're +[1:43:14] both thinking of little tiny cells that +[1:43:18] communicate back and forth but which do +[1:43:20] not reach across into each other's +[1:43:22] domain to do different things. And so +[1:43:25] they're certain Allen K especially that +[1:43:29] that is the future of how we will +[1:43:31] engineer things. They're going to be +[1:43:33] like microorganisms where they're little +[1:43:35] things that we instance, right? And they +[1:43:38] just talk to each other. So everything +[1:43:39] will be built that way from the ground +[1:43:41] up. +[1:43:43] But the problem with that is it doesn't +[1:43:45] seem to work in practice. It's a great +[1:43:48] idea when thinking about systems that +[1:43:50] are actually separated in that way like +[1:43:52] actual computers talking over a network. +[1:43:54] It makes perfect sense because they do +[1:43:56] look like microorgans. And most of Alen +[1:43:58] K's ideas actually map very well to +[1:44:00] things like the internet at large where +[1:44:02] you really do have to just pass messages +[1:44:04] back and forth. So again, not going to +[1:44:06] say something negative about Alen K. The +[1:44:08] ideas are good and they do have very +[1:44:10] good applications. It's it's smart. It +[1:44:13] really is. But when you're talking about +[1:44:15] code that's working inside one computer +[1:44:18] in the same core memory that's meant to +[1:44:20] work together, it's too limiting. It's +[1:44:22] way too limiting. It's not the right +[1:44:24] model and it forces us to do way too +[1:44:26] much work to accomplish the same thing. +[1:44:30] So just to underscore, +[1:44:34] reading this history actually gave me a +[1:44:36] nice perspective on these things. And I +[1:44:38] think there's reasons why C++ was +[1:44:40] adopted even after all the stuff I just +[1:44:41] said about how the compile time hard +[1:44:43] stuff wasn't very good. One of the +[1:44:44] things that I didn't really appreciate +[1:44:46] was it kind of sounds to me like shrusup +[1:44:48] was really important in getting type +[1:44:50] checking for us. Like C did not even +[1:44:53] type check function calls at the time +[1:44:56] that was making C with classes, right? +[1:44:59] And he recognized because of his +[1:45:01] background in simula. He's like this is +[1:45:03] ridiculous. I think he gave an example +[1:45:05] like if I do square root like sqrt in C +[1:45:08] parenthesis 2 +[1:45:11] that doesn't work right now because it +[1:45:13] passes the integer too and it doesn't +[1:45:14] check that square roots taken a double +[1:45:16] or something right or whatever it was +[1:45:18] taking in that particular version of the +[1:45:19] library he was using. He's like that +[1:45:22] cannot be something that we have to +[1:45:23] catch at runtime. Especially not in +[1:45:25] those days when debuggers are worse and +[1:45:27] everything is worse, right? Iteration +[1:45:29] time is slower. So you get this +[1:45:31] situation where you're like, I kind of +[1:45:33] see why these things took off. Some of +[1:45:36] these things like the compile time, you +[1:45:37] know, encapsulation hierarchies, they're +[1:45:39] coming in at the same time that C++ is +[1:45:42] making positive contributions that +[1:45:44] actually do help you program for real, +[1:45:46] right? And it's not like we can't think +[1:45:48] of uses for things like virtual +[1:45:50] functioning classes like interfaces just +[1:45:53] that bare concept is a place where we +[1:45:55] still use those things today even new +[1:45:57] languages those things. So there there +[1:45:58] is that too if it's used responsively, +[1:46:01] right? It's just that compile time +[1:46:03] hierarchy that was a problem. And this +[1:46:04] is a quote that I also want to include +[1:46:06] just to give credit. He's also on the +[1:46:08] same team. He wants the fast thing, +[1:46:11] right, to be easy for people to do. You +[1:46:14] don't want your definition of good code +[1:46:16] to be slow, right? So anyway, when you +[1:46:19] read through all this stuff, you you're +[1:46:21] kind of rooting for everybody. To be +[1:46:22] completely honest, even after all the +[1:46:24] suffering that C++ has caused me in my +[1:46:26] life, I was kind of like, "Oh, all +[1:46:27] right. I get it. I get it, man. I do." +[1:46:31] So, that's the 35-year mistake is the +[1:46:33] distance between those two years. The +[1:46:35] year in which we could have had the +[1:46:36] entity component system because the +[1:46:38] first person has sort of done something +[1:46:39] that was almost that and the year in +[1:46:40] which we actually got the entity +[1:46:41] component system, which I'm not even +[1:46:44] saying is a good design or not. I don't +[1:46:45] even have an opinion on something like +[1:46:46] that to be completely honest with you. +[1:46:49] But I think it was a really cool idea +[1:46:50] and an interesting architectural idea to +[1:46:52] explore. And so I'm really glad that we +[1:46:54] got there either way. But I wish we +[1:46:56] could have gotten there a little bit +[1:46:57] sooner. +[1:46:58] So unfortunately the mistake if that's +[1:47:01] 35 years, it does unfortunately not end +[1:47:04] there because if you do a search on +[1:47:06] Google right now and you're like, I need +[1:47:08] an oop tutorial. I need an +[1:47:10] object-oriented programming tutorial. +[1:47:12] What will you see? Hit number one, we'll +[1:47:15] have a domain model that has +[1:47:17] encapsulation that matches you or sorry, +[1:47:19] you'll have a compile time hierarchy +[1:47:20] that matches the domain model exactly +[1:47:22] like we don't want. This person imagines +[1:47:24] this is the number one hit. He imagines +[1:47:27] something called a special Iron Man +[1:47:29] that's slightly different from a regular +[1:47:30] Iron Man because I guess in his mind or +[1:47:33] whoever wrote it, I don't even know. It +[1:47:34] might be a team of people. +[1:47:37] There's some kind of a specialized Iron +[1:47:39] Man that I didn't I mean, I don't read +[1:47:40] comics. Maybe that's a thing. Hit number +[1:47:43] two, Java. OOP. This is from W3 schools. +[1:47:47] Again, not only is it a compile time +[1:47:50] hierarchy that matches the domain model, +[1:47:52] but it's one of the ones that you can +[1:47:54] actually find in those early papers. +[1:47:56] Strus talks about vehicle sending cars. +[1:47:58] And if you remember, cars crossing a +[1:48:00] bridge, it could be trucks or buses was +[1:48:02] in Simula day one. It's where they came +[1:48:04] up with that subclassing thing that they +[1:48:06] were going to do. So, we're still +[1:48:08] pushing it today on hit number two. Hit +[1:48:10] number three is three types of bicycle +[1:48:13] that come off a bicycle, right? +[1:48:17] And don't ask me why there's spaces in +[1:48:19] that and not in the mountain. I mean, I +[1:48:21] don't even know. That's the top three +[1:48:23] hits. I stopped looking after that +[1:48:24] because I'm just like I give up. So, one +[1:48:27] thing that we could do to keep this +[1:48:30] mistake from propagating is just get +[1:48:32] this idea out there that compile time +[1:48:34] hierarchies of encapsulation that match +[1:48:36] the domain model are not that good. +[1:48:39] Sometimes they work like with +[1:48:40] distributed systems or maybe +[1:48:42] microbiology, but a lot of times they're +[1:48:44] just more work than they're worth. And +[1:48:47] that would help. It would help a lot. +[1:48:50] And I would bolster that here finally +[1:48:54] the end of the talk with this quote, +[1:48:56] which I think is the best one to end on. +[1:48:58] It's that the most treacherous metaphors +[1:48:59] are the ones that seem to work for a +[1:49:01] time because they can keep more powerful +[1:49:04] insights from bubbling up. Right? We got +[1:49:06] this thing in place. There was this +[1:49:08] compile time hierarchy that matched the +[1:49:09] domain model idea and it was stopping +[1:49:12] all of our other architectural +[1:49:14] development because everyone was saying +[1:49:15] it was going to work and it was going to +[1:49:16] be great and we must be doing it wrong, +[1:49:19] right? But actually that wasn't the +[1:49:21] case. And +[1:49:24] this is a hard quote to find. If you +[1:49:26] search for it, I'm not sure if you will +[1:49:27] find it, but if you read through, you +[1:49:29] will find it. It comes from Alan K. He's +[1:49:32] the one who said it, right? That's him +[1:49:34] sitting at his uh you know I think that +[1:49:36] must be uh one of the original Palo Alto +[1:49:38] computers right the Alto I think is what +[1:49:40] that one is from Xerox Park. +[1:49:43] So that's the actual end of my talk. +[1:49:45] Thanks everyone for listening. I'm +[1:49:47] surprised I was able to remember all +[1:49:48] that stuff for this. You've been a +[1:49:50] wonderful audience and uh I guess now +[1:49:53] Ryan Flurry will be coming up on stage +[1:49:55] to uh interview me and take questions +[1:49:58] from the audience. Is this correct? Sam. +[1:50:02] >> What? Sam, is that true? +[1:50:03] >> I say it again. +[1:50:06] >> The organizer, ladies and gentlemen, +[1:50:12] >> please welcome to the stage Ryan Flurry. +[1:50:14] Everyone +[1:50:23] Okay. Well, yeah, thank you for that +[1:50:25] talk. That was really good. +[1:50:27] >> It was a lot of fun putting together. +[1:50:28] >> Yeah. So, um I guess the first comment +[1:50:33] that I would have is that it seems like +[1:50:36] uh I'm a little bit glad to see that +[1:50:39] people in the six There's two things. +[1:50:41] I'm glad to see that people in the 60s +[1:50:42] were like +[1:50:44] using these techniques that seem to be +[1:50:46] reemergent. It kind of makes it feel +[1:50:48] like there's like uh maybe like some +[1:50:51] degree of gaslighting since then. Like +[1:50:53] there's like all these you rediscover +[1:50:55] these things, they seem to be useful. +[1:50:57] Um, and then for some reason like uh we +[1:51:01] haven't actually +[1:51:04] that information has been lost I guess. +[1:51:06] Do do you find I mean I assume you find +[1:51:08] the same thing to be true. Uh yeah. I +[1:51:10] mean I I guess the problem so I don't +[1:51:13] even know if it's like gaslighting in +[1:51:15] that sense, right? Because it's like I +[1:51:17] don't necessarily know I didn't find a +[1:51:19] lot of evidence that people were like +[1:51:20] intentionally obviously like it wasn't +[1:51:21] like somebody was like I would rather +[1:51:23] promote my thing than this thing in +[1:51:24] sketchpad that I noticed. That quote +[1:51:27] from Alan K is kind of instructive in +[1:51:29] this case. He honestly believed that +[1:51:32] having the thing be omnisient was bad. +[1:51:34] He's saying that this is bad. Right? And +[1:51:37] you see the same thing from Strereip +[1:51:39] saying that this you know switch you +[1:51:41] know this basically switch on a type is +[1:51:42] bad. And so I I think they just honestly +[1:51:45] believed that they they believe that +[1:51:47] these were bad for modularity and in +[1:51:49] their minds because they're so focused +[1:51:50] on the modularity. +[1:51:52] They were just saying this isn't good +[1:51:54] and so it just kind of doesn't get +[1:51:56] propagated. This is this thing that you +[1:51:58] see all the time right? If someone isn't +[1:51:59] a good PR isn't good PR for their thing +[1:52:01] it doesn't get propagated. +[1:52:03] >> Yeah that makes sense. +[1:52:06] So um in your own personal programming +[1:52:09] like journey you started with like +[1:52:11] learning the traditional object-oriented +[1:52:14] sort of or like C++ templatization of uh +[1:52:17] compile time hierarchies of +[1:52:19] encapsulation and so on. you uh I mean I +[1:52:24] I have an idea of where you changed or +[1:52:27] where you developed but I'm curious +[1:52:29] about where you learned to not do that +[1:52:32] and furthermore +[1:52:34] from where you learned it where did they +[1:52:36] learn not to do it did they did they +[1:52:38] learn from the original papers or did +[1:52:40] the simple ideas just reemerge or what +[1:52:42] what is the story there +[1:52:44] >> uh so that's kind of interesting so when +[1:52:48] I was younger like so when I started +[1:52:50] programming when I was very little +[1:52:51] Right. I didn't know any of the things. +[1:52:53] I wouldn't know anything about +[1:52:54] architecture. C++ wasn't even invented +[1:52:56] uh in the in I don't think would it have +[1:52:58] been invented? So C so C with classes +[1:53:01] would have been but C++ wasn't even like +[1:53:03] out in the world the time when I would +[1:53:04] have started in like basic or something +[1:53:06] like that, right? So I definitely uh +[1:53:08] started without any of these notions. +[1:53:10] But then when I first went out into like +[1:53:13] you know professional I mean my first +[1:53:15] job was hardly professional but when I +[1:53:18] went out into the world of like +[1:53:18] commercial programming uh I I definitely +[1:53:22] like thought that everyone was +[1:53:23] presumably right about this. I just +[1:53:25] didn't know. And so I tried programming +[1:53:27] in this model and learned all those +[1:53:29] things because you know it kind of has a +[1:53:30] magic the gathering feel to it. It's +[1:53:32] like you're learning a lot of intricacy +[1:53:34] and it's just magic the gathering. It's +[1:53:36] something people made up that was +[1:53:37] fictional but you you know you don't +[1:53:39] know that. you think it's real, right? +[1:53:40] But you're getting into it in the same +[1:53:41] way you might get into Magic the +[1:53:42] Gathering, like, "Oh, I figured out that +[1:53:44] the template can do this thing +[1:53:45] >> and it becomes its own little game, +[1:53:47] right?" So, I think it kind of went that +[1:53:49] way for me. And at the time, it was very +[1:53:51] obvious that this was stupid. Like, if I +[1:53:53] had actually thought about it, but I +[1:53:54] chocked it up to me just not knowing how +[1:53:56] to do it, right? Which I don't think was +[1:53:57] actually true. I think it was just like, +[1:53:58] "No, these are actually just worse than +[1:53:59] what you were doing." Because what I +[1:54:01] noticed was things that would have taken +[1:54:03] me only a few days before were taking +[1:54:05] like months to like figure out all of +[1:54:07] the ways that I would have to do it in +[1:54:09] order to make it fit these things. And I +[1:54:11] think I was just too stupid to realize +[1:54:12] that probably just means it's just a bad +[1:54:14] approach, right? +[1:54:16] >> Uh so you had a second part of the +[1:54:17] question which was how did I undo it? +[1:54:19] That part is a little more concerning I +[1:54:22] guess because the only reason that +[1:54:24] happened was I happened to then program +[1:54:26] with people who had never done that. So +[1:54:28] they were people who never had the +[1:54:30] experience of being told to do this +[1:54:31] architecture or just ignored it and +[1:54:33] continued to program the old school way. +[1:54:34] And I was like, "Oh, these people are +[1:54:37] very successful and very important +[1:54:39] programmers. So maybe it's not the case +[1:54:41] that I just don't understand it. Maybe +[1:54:43] there's actually something to keeping +[1:54:44] doing this way." The reason that's more +[1:54:46] concerning to me is it's like it means +[1:54:47] if those people aren't around, +[1:54:49] >> if they weren't around, maybe I wouldn't +[1:54:51] never had that experience, right? And so +[1:54:52] you kind of need this generational +[1:54:54] overlap of people who still remember the +[1:54:56] good things about the previous way to +[1:54:58] tell you that the new way kind of sucks, +[1:55:00] right? +[1:55:01] >> And do you know like um when you worked +[1:55:03] with those other programmers, were they +[1:55:06] were they informed by this older +[1:55:07] generation like the 1960s papers of how +[1:55:09] they were doing these things? Did they +[1:55:11] just take those lessons or +[1:55:14] >> No, I think it's just a case of like the +[1:55:18] if you were using programming resources +[1:55:21] from that era of even just the 1970s, +[1:55:25] you wouldn't be seeing like it was more +[1:55:27] academic the places where oop would have +[1:55:29] been talked about, right? Small talk was +[1:55:31] a thing that would have been in research +[1:55:33] stuff, right? And simula was a thing +[1:55:35] with papers and stuff like that. But the +[1:55:37] person who learns to program like you +[1:55:39] know in the game industry and stuff like +[1:55:40] that the person who learns to program on +[1:55:41] an Apple 2 is not being exposed to those +[1:55:43] things right so they just learned in an +[1:55:45] environment and using reference +[1:55:47] materials that did presumably kind of +[1:55:49] come through that culture but it wasn't +[1:55:51] like they were you nobody was like oh +[1:55:53] yeah Doug T Ross man and plexes like +[1:55:55] that's that's the stuff right it's like +[1:55:57] no like so I think it's just more that +[1:56:00] they hadn't have had that that idea +[1:56:02] pushed down on them in a way that they +[1:56:04] believed. +[1:56:05] >> Okay. Um, so, uh, I had it in my head, +[1:56:10] but I got to check my notes here. Um, +[1:56:13] so I think that I'm I was curious about +[1:56:16] I have a collection of like not exactly +[1:56:19] related questions or discussions like +[1:56:21] >> hit me. +[1:56:22] >> So, one of the thing you introduced this +[1:56:24] subject by saying like one of the +[1:56:26] arguments that people will use to +[1:56:28] promote like sort of object-oriented +[1:56:30] these or I shouldn't say +[1:56:31] object-oriented, I should say compile +[1:56:33] time hierarchies. If someone out there +[1:56:35] wants to come up with a catchy moniker +[1:56:36] for that, it is hard to say. So, we need +[1:56:39] something like oop for that, right? And +[1:56:41] uh and it would be nice because again, +[1:56:42] like I said, I think it's pretty +[1:56:44] important +[1:56:45] >> to draw that distinction because like +[1:56:48] like Mach who I quoted at the beginning +[1:56:50] of the thing who did that entity +[1:56:51] component system, he's like he's +[1:56:53] thinking of it in terms of +[1:56:54] object-oriented. He's not thinking this +[1:56:56] is not object-oriented, right? So you +[1:56:58] can still you can easily call yourself +[1:57:00] an object-oriented programmer and want +[1:57:01] object-oriented principles to apply to +[1:57:03] your codebase and just not think about +[1:57:05] that compile time thing. And it seems to +[1:57:07] work pretty well. +[1:57:09] >> Yeah, it kind of seemed like um the +[1:57:11] object-oriented part of drawing +[1:57:13] boundaries, it doesn't actually it's not +[1:57:15] um it might be descriptive of a system, +[1:57:17] but it's not prescribing like where to +[1:57:19] put those boundaries. Exactly. +[1:57:21] >> Yes. Exactly. And also furthermore, it's +[1:57:23] something I think we could all agree +[1:57:24] about, right? I don't know that a a +[1:57:26] hardcore object-oriented uh person like +[1:57:29] certainly not Alan K probably would +[1:57:31] never agree that making like an API +[1:57:33] boundary around something was that +[1:57:35] object-oriented if the thing was fairly +[1:57:37] large although he might but we can all +[1:57:40] agree that that's a thing we want to do +[1:57:42] like I don't consider myself an +[1:57:43] object-oriented programmer but I +[1:57:45] consider that to be a good thing to do +[1:57:46] and I think that's certainly a point of +[1:57:47] commonality and I think most +[1:57:49] object-oriented programmers would call +[1:57:50] that an object-oriented thing to do even +[1:57:53] though it really predates that you could +[1:57:55] just think of objective programming one +[1:57:57] of the principles is sort of +[1:57:58] crystallizing that idea into one of +[1:58:00] their core concepts and I think that's a +[1:58:02] good core tenant to have right to do +[1:58:04] that at the appropriate size that's +[1:58:06] where I tend to part ways like what that +[1:58:08] size is +[1:58:09] >> so on the large team subject you were +[1:58:12] digging through all these historical +[1:58:14] papers and records and everything did +[1:58:16] you actually find any research about +[1:58:17] what people actually do for large teams +[1:58:20] >> so one of the things is I was focused on +[1:58:22] figuring out where these ideas came +[1:58:24] from. So I didn't go looking for where +[1:58:26] the I don't want to call them excuses. +[1:58:28] It's too disparaging, but where the +[1:58:31] justifications came from, right? So I +[1:58:34] what I can tell you so I don't know +[1:58:36] that's another that'd be a whole another +[1:58:37] topic. This thing took two hours or +[1:58:38] something like that, right? So that's a +[1:58:41] whole another question. It would be very +[1:58:42] interesting to answer. But what I can +[1:58:45] tell you is during the course of the +[1:58:47] development of these core ideas, I never +[1:58:50] once saw anyone talk about that. And +[1:58:54] they were always like one person doing a +[1:58:57] team doing things by themselves or two +[1:58:59] people developing things by themselves. +[1:59:01] And to the extent that like larger teams +[1:59:03] would have been involved at all, it +[1:59:04] might have been on the simulus side. +[1:59:05] like some of their opinions may have +[1:59:07] been influenced by uh you know in ways +[1:59:10] that they didn't directly like they +[1:59:11] didn't attribute any of those things to +[1:59:13] it but maybe they were seeing people use +[1:59:15] simul in the world had something to do +[1:59:17] it but I don't think there were that +[1:59:18] large teams working on simula either I +[1:59:19] don't know +[1:59:20] >> yeah it's kind of interesting alone that +[1:59:22] the the history of computing it's always +[1:59:25] large team or small teams pushing large +[1:59:27] improvements like successively so it's +[1:59:29] interesting to optimize for large teams +[1:59:31] that in that way but +[1:59:33] >> well and you might even say it creates a +[1:59:34] bit of a problem because it means that +[1:59:36] like if the innovation happens in small +[1:59:38] teams, but we do need large teams uh of +[1:59:40] people to do certain things, it's like +[1:59:42] it's kind of hard to figure out where +[1:59:43] the innovation in that comes from +[1:59:44] because if our risk comes these few +[1:59:46] people doing something, they're not +[1:59:48] having the same experience as a large +[1:59:49] team. So maybe it's like small teams +[1:59:51] doing something on the side of a big +[1:59:53] team is where we get some of that +[1:59:54] innovation. I don't know. +[1:59:55] >> Yeah. Um, so I'm kind of curious about +[1:59:59] like so a few uh programming ideas that +[2:00:03] a lot of people use like that you +[2:00:05] regularly use in your in your +[2:00:07] programming came up. One being like +[2:00:09] discriminated unions or tag unions um as +[2:00:12] sort of like forming this like mutually +[2:00:14] exclusive branching structure um as +[2:00:16] opposed to uh like the fatstruct model +[2:00:19] where it's like a comp just it's one +[2:00:22] unified type. I'm I'm kind of interested +[2:00:25] to hear like what you think about like +[2:00:29] um both of those things are you've said +[2:00:31] are like good in their respective +[2:00:33] situations. I'm curious about like when +[2:00:35] you know that introducing boundaries of +[2:00:38] mutual exclusion like in a discriminated +[2:00:40] type is useful whereas the uh the the +[2:00:43] sort of uh large fatstruct thing stops +[2:00:46] being useful in those cases. +[2:00:47] >> So I don't really think of them as +[2:00:48] distinct. I think of them as sort of the +[2:00:50] same things. I'm just trying to use +[2:00:52] terms that other people think in to +[2:00:53] communicate that. So the way that I +[2:00:55] normally think about it is there are two +[2:00:57] types of situations I might find myself +[2:00:59] in. One is where the domain model itself +[2:01:03] like literally the thing is telling me +[2:01:06] clearly that these things are mutually +[2:01:08] exclusive and that might be a place +[2:01:10] where I you know have more in common +[2:01:13] with the oop side of things because I'm +[2:01:15] like I see why you guys are thinking +[2:01:16] about if that was true about this thing. +[2:01:19] So in those cases I would use a +[2:01:20] discriminated union because I prefer to +[2:01:22] write code in like a verb oriented way +[2:01:24] not an object-oriented way. So I but I'm +[2:01:26] just doing the flip side of what they're +[2:01:27] doing with their virtual function in +[2:01:28] those cases right I just think it works +[2:01:30] out better in my way but that's just you +[2:01:32] know that's my personal opinion. It also +[2:01:33] has to do with what type of system +[2:01:34] you're making whether or not people are +[2:01:36] going to be adding types to the system +[2:01:37] more frequently or whether they're going +[2:01:38] to be adding actions. I tend to find +[2:01:40] that people add actions more frequently. +[2:01:41] That's why I focus on that. But either +[2:01:43] way +[2:01:43] >> that makes sense. +[2:01:45] So if I can see that this is by +[2:01:47] definition mutually exclusive then I'm +[2:01:49] discriminated union and the reason for +[2:01:51] that is exact same reason for true strip +[2:01:53] and everybody else to catch errors. I +[2:01:56] don't want to be using I don't want to +[2:01:58] make that a fatty strruct where I'm +[2:01:59] accidentally doing code that's going to +[2:02:01] do both things. So I try to basically +[2:02:03] replicate that simul style thing or +[2:02:05] really it's it's Tony Horses right sir +[2:02:07] Tony idea of of that I try to +[2:02:10] replicate that and it's just +[2:02:11] unfortunately C++ has doesn't really +[2:02:12] have good support for that like I said +[2:02:13] Santa very is not very good in my +[2:02:15] opinion the real thing that Tony Horror +[2:02:18] wanted would would have been great so I +[2:02:20] would love that feature the fatty +[2:02:22] strruct qua fatty strruct and like I +[2:02:24] said I mix these two together so I don't +[2:02:25] think it's that distinct to me but the +[2:02:27] idea of like feature flags or something +[2:02:29] like that right like I'm going to hit +[2:02:30] this bit and then it means that this +[2:02:31] path might be taken. What the Plex guy +[2:02:33] uh right what what Doug T. Ross would +[2:02:35] have called those like switches, right? +[2:02:39] That to me is for mixin as they call it, +[2:02:41] right? When I know I'm combining lots of +[2:02:43] things together, right? Like a tasty +[2:02:44] stew that's going to be delicious and +[2:02:46] it's going to taste fabulous when you +[2:02:47] use these entities, right? That's that's +[2:02:50] when I reach for that. And I think those +[2:02:51] are really they're very simple. You can +[2:02:53] teach them to someone in an afternoon +[2:02:56] and they can apply them pretty directly +[2:02:58] right away. And that's one of the +[2:02:59] reasons why I think they're so much +[2:03:00] better than things like the compile time +[2:03:02] hierarchies where, you know, I've seen +[2:03:03] programmers tie themselves in knots and +[2:03:05] spend months trying to do something that +[2:03:06] literally that approach would it would +[2:03:07] take in 30 minutes. +[2:03:08] >> Yeah. +[2:03:08] >> Right. Yeah. +[2:03:10] >> And I I'm I'm a little confused about +[2:03:12] the uh like +[2:03:15] exactly what so looking glass you +[2:03:17] introduced them as using like sort of +[2:03:18] the faststruct model, but it sounded +[2:03:20] like they ended up with a entity like +[2:03:22] component system thing where they split +[2:03:24] everything out into like they they +[2:03:26] pulled out common parts of entities and +[2:03:27] put them isolated their storage. Did +[2:03:29] they make that transition or did they +[2:03:31] use one early and then the second later? +[2:03:33] >> Uh can I ask a question to the audience? +[2:03:36] >> Yes. Sam, how much time we got? +[2:03:39] >> We still have time right now. Maybe +[2:03:42] Well, it depends. There are multiple +[2:03:44] paths that could be taken. And the the +[2:03:47] the split point is in about 25 minutes. +[2:03:51] >> Uh, how badly do you want a complete +[2:03:54] version of that answer versus a +[2:03:56] summary answer? Because I can answer +[2:03:58] that very accurately. +[2:04:00] >> Okay. Um, yeah, let's go with the +[2:04:03] accurate one. Okay. All right. +[2:04:06] [Applause] +[2:04:13] deleted scenes to keep this talk uh +[2:04:17] somewhat under two hours, which +[2:04:18] hopefully we did and now won't do. So, +[2:04:22] I'll skip some of this just to keep it +[2:04:23] relatively quick. So, inside Ultima +[2:04:26] Underworld, an entity was basically a +[2:04:29] fatty strruct overlay. So the way that +[2:04:32] it worked is you had an entity and then +[2:04:34] if there were two separate things like +[2:04:36] hit points and fuel that were generally +[2:04:39] mutually exclusive, meaning an entity +[2:04:41] probably can't have both of them because +[2:04:43] fuel is used only for like lanterns and +[2:04:46] and lanterns don't have hit points, then +[2:04:47] we'd put them in the same place, +[2:04:49] >> right? That was that was uh Ultima +[2:04:51] Underworld, right? And of course, this +[2:04:54] is, you know, rough because it's like it +[2:04:56] means that when you're accessing one of +[2:04:57] these, you're secretly also accessing +[2:04:59] the other, right? because they're in the +[2:05:01] same place. And so you could have an +[2:05:03] error where you were doing something +[2:05:04] where like you're checking the fuel or +[2:05:06] you're checking the hit points. In this +[2:05:08] case, like you're checking the hit +[2:05:09] points, but you're secretly checking the +[2:05:10] fuel. And then you delete the entity, +[2:05:12] you know, because that's what it was +[2:05:13] thinking, right? And this is Mach. He +[2:05:15] didn't his picture didn't make it in. +[2:05:17] I'm glad I get to show him now. He's the +[2:05:18] guy who did a lot of the implementation +[2:05:20] on the dark object system. He came on +[2:05:22] the scene in Ultima Underworld 2 and +[2:05:25] he's the one who coined that phrase that +[2:05:26] that quote I put up. That's him, the +[2:05:28] compile time harchy. He's the one who +[2:05:29] crystallized that, right? He comes on +[2:05:32] cuz the uh in the earlier earlier ones +[2:05:34] like it was Doug Church and Dan Schmidt +[2:05:36] and a bunch of people who did Ultima +[2:05:37] Underworld one. He comes on of +[2:05:39] Underworld 2 and he actually literally +[2:05:42] had the that bug that fuel bug. He wrote +[2:05:44] a thing for damage where if you threw an +[2:05:46] empty lantern at a wall, it would enter +[2:05:49] the damage system because it was +[2:05:50] supposed to take damage from hitting the +[2:05:51] wall. And it would be like, "How many +[2:05:52] hit points does the lantern have?" It'd +[2:05:53] be like zero. It's like, "Well, I guess +[2:05:55] it's out of here." And so empty lanterns +[2:05:57] thrown at walls would just disappear. +[2:05:58] Nice. +[2:05:59] >> Right. And so he had to fix that bug by +[2:06:01] doing exactly what you'd expect. He'd +[2:06:02] have to like check, you have to manually +[2:06:04] add that code. +[2:06:05] >> Yeah. +[2:06:05] >> And so, you know, they didn't like this +[2:06:07] because remember these guys and again, +[2:06:09] much like, you know, Ivan Sutherland and +[2:06:11] Doug Ross, these guys were super smart +[2:06:12] MIT people and and Sutherland's also +[2:06:14] Carnegie Melon and Caltech, right? It's +[2:06:16] like kind of nuts going through the +[2:06:18] whole gauntlet there. Uh the folks at +[2:06:19] Looking Glass are MIT graduates. They're +[2:06:21] super super smart guys. They do all this +[2:06:23] amazing stuff. So, they don't want to +[2:06:25] they don't want to have this happen, +[2:06:26] right? they just don't know what else to +[2:06:28] do because they have these like really +[2:06:29] hardcore memory constraints. +[2:06:30] >> Yep. +[2:06:31] >> And furthermore, they talk a lot about +[2:06:33] the um the sort of uh trade-offs you +[2:06:36] have to make. So, if you have a fuel +[2:06:38] system that needs to store stuff and you +[2:06:39] have a combat system that needs to store +[2:06:40] stuff and you do make space for them, um +[2:06:42] it means that if you do, you know, if +[2:06:44] you're using that overlap, it means that +[2:06:47] if you then decide you need an entity +[2:06:48] that has combat and fuel because we +[2:06:50] wanted to add that, it's like crap, I've +[2:06:52] got this overlap, I can't do it. So now +[2:06:55] I have to make a trade-off like maybe I +[2:06:57] shrink the amount of data that the +[2:06:58] combat system can store and that sucks +[2:07:00] right because now I'm forced into this +[2:07:02] this decision I didn't want to have to +[2:07:03] make and that's just you know what the +[2:07:05] kind of situation they're working on +[2:07:07] working under the kind of constraints +[2:07:08] they're working under when they go to do +[2:07:09] System Shock which is the RPG. So they +[2:07:12] do Ultimal Underworld one two and they +[2:07:14] do System Shock. I'm just following +[2:07:15] their lanes. They also they have +[2:07:16] Pteranova and Flight Unlimited which I +[2:07:17] won't cover because they're not the same +[2:07:18] uh in terms of like lineage really for +[2:07:20] the teams and how they were uh doing +[2:07:21] RPGs. This is just the RPGs from looking +[2:07:23] glass. Um, so yeah, it kind of looks +[2:07:26] like that. I'll skip this because it's +[2:07:28] not part talk. Uh, they go to an +[2:07:29] outlinking kind of structure. So what +[2:07:31] they do is they say, "All right, we we +[2:07:32] kind of want something better than that. +[2:07:33] So we're going to do is we'll have our +[2:07:35] entities. We have a little bit more +[2:07:36] memory to work with now. So we'll have +[2:07:37] the entities have their shared part up +[2:07:39] front that everyone roughly has. So it's +[2:07:41] kind of fatty but not that fatty. And +[2:07:44] then everybody gets one pointer out to +[2:07:46] something, right? and we'll try to make +[2:07:48] those things be things that don't have +[2:07:50] to combine together, but it's still a +[2:07:51] limitation, right? Because they can't +[2:07:52] have two of them, which they would have +[2:07:53] liked to have had. So that's how they +[2:07:55] got there. That's that's what system +[2:07:56] shock was. It was like one outlink per +[2:07:58] entity that could extend it. +[2:08:00] >> Got it. +[2:08:00] >> And now that solves their growing +[2:08:02] problem, right? It's like we can just +[2:08:03] grow things arbitrarily and they don't +[2:08:05] like overlap some unrelated system or +[2:08:07] something like that, but it doesn't +[2:08:08] really allow them to combine them in +[2:08:09] that way that they would have liked. So +[2:08:10] it's still almost the same limitation. +[2:08:12] It's just more of a memory optimization +[2:08:14] at this point, right? +[2:08:15] Um, but it also catches this error +[2:08:18] because now you sort of have a +[2:08:19] discriminated union going on. So you +[2:08:21] can't access fuel off the base entity +[2:08:23] because it doesn't have it. So you have +[2:08:24] to do something like this where like if +[2:08:25] it's a light source I can get the light +[2:08:27] source or better yet I can only return a +[2:08:29] light source pointer if it was a light +[2:08:31] source. And so then I it's kind of more +[2:08:33] foolproof that I can just check one +[2:08:35] pointer and good to go. Right? Again I'm +[2:08:37] blowing through these but yeah this was +[2:08:38] me making fun of standard variant. Yeah. +[2:08:40] Um, so, uh, Flight Unlimited, this was +[2:08:43] I'm just going into this because it it +[2:08:44] sets up the entity component system +[2:08:46] thing. Flight Unlimited actually had, +[2:08:48] uh, it was the first thing to use C++ +[2:08:50] really heavily in the company. And so, +[2:08:51] they were using new and delete like +[2:08:52] you're supposed to do in C++. And +[2:08:54] unfortunately, that totally fragmented +[2:08:56] memory. Totally like thrashed out memory +[2:08:57] and fragmented memory. So, uh, I don't +[2:09:00] know if this is well known, but +[2:09:01] basically Fight Unlimited is a game +[2:09:02] where you like fly around, you know, in +[2:09:03] the thing and and whatever. It was very +[2:09:05] popular flight at the time, actually. +[2:09:07] Uh, and you'll notice that in the +[2:09:08] cockpit here there's gauges, but there's +[2:09:11] no fuel gauge, right? There's no fuel +[2:09:12] gauge on there. It's just it's other +[2:09:14] stuff. There's no fuel gauge at all. But +[2:09:17] sometimes it would say out of fuel would +[2:09:19] just be like out of fuel, right? And +[2:09:21] what out of fuel was was actually the +[2:09:23] memory is too fragmented. So what it +[2:09:25] would do is it would say out of fuel, it +[2:09:28] would clo it had like a an executable +[2:09:30] that was sort of running as sort of a +[2:09:32] batch restarter for the main executable. +[2:09:34] it would just close the whole rest of +[2:09:36] the executable. So you save the game +[2:09:38] state, close the executable, reload the +[2:09:41] game state, and you know, then you were +[2:09:43] there you're back to good. Uh this is +[2:09:46] Tom Leonard. So thief of dark project +[2:09:48] comes on the heels of this. This is Tom +[2:09:49] Leonard. He's actually the guy who as +[2:09:51] far as anyone can remember that I've +[2:09:53] been able to, you know, that I've been +[2:09:54] able to get the solid story about. He's +[2:09:56] the guy who actually comes up with the +[2:09:58] idea of sort of the entity component +[2:10:00] model switch. And I didn't really call +[2:10:02] again too much stuff getting cut that +[2:10:03] we're going into now. So, you know, I +[2:10:05] guess six of one half dozen the other. +[2:10:06] But the idea of saying, okay, instead of +[2:10:09] entity.get hit points, we're going to +[2:10:11] say hit points.get entity. This is a big +[2:10:14] like that's a big switch if you never +[2:10:15] thought about it before, right? He's the +[2:10:18] one that like Mock says I think it was +[2:10:20] Tom who came up with that. And the +[2:10:21] reason is so that the types line up. +[2:10:23] It's like now instead of having like +[2:10:25] either tons of functions like get a hit +[2:10:27] points like thing, get a this that are +[2:10:29] on you know an entity which would suck. +[2:10:32] Now, we just ask the actual thing, the +[2:10:34] hit point system, and it's only going to +[2:10:35] return one type, which is like a hit +[2:10:36] points type to us, right? +[2:10:39] Um, and so anyway, this is what they're +[2:10:41] thinking about when they make the entity +[2:10:42] component system, and it comes from all +[2:10:44] of those experiences that they've had. +[2:10:46] They want to avoid fragmentation because +[2:10:48] they just had to make a thing that like +[2:10:49] restarts the game, right? Which was uh +[2:10:52] Flight Unlimited. They want arbitrary +[2:10:54] sized properties, right? Because they +[2:10:55] don't want to make those trade-offs +[2:10:56] between combat systems and fuel and +[2:10:58] whatever. They also had additional +[2:11:00] things which is like they wanted +[2:11:01] designers to be able to create types at +[2:11:03] runtime which the so they kind of want +[2:11:04] bags of properties that they can have +[2:11:06] designers create and they want designers +[2:11:08] to be able to do things like create +[2:11:09] domain mile um uh domain model +[2:11:12] hierarchies in the editor because +[2:11:14] they're thinking in terms of the domain +[2:11:16] model and it's just not implemented that +[2:11:17] way. Right? So they they do those +[2:11:18] things. +[2:11:19] >> And then finally the how fast is the +[2:11:21] fastest case thing. Uh that was from +[2:11:23] Doug Church. He was like, "Okay, if +[2:11:24] we're doing all this pie in the sky +[2:11:26] stuff, we have to figure out some way +[2:11:27] that it's still going to be as fast for +[2:11:29] like physics compute and stuff as what +[2:11:31] we used to do." And so what he did there +[2:11:33] was he was basically forcing them to go, +[2:11:34] we have to consider some way that this +[2:11:35] is all going to work. That was the +[2:11:36] system boundary drawings part. So that's +[2:11:38] the really fast part of this. And by the +[2:11:40] way, this is what it looks like inside +[2:11:42] the dark uh object system if you want to +[2:11:44] create a property type, right? It's like +[2:11:46] I said, it's still oop looking, right? +[2:11:48] Like like you could pass this by an oop +[2:11:50] person and they would be fine with it, I +[2:11:51] think. So, it's like again, not not oop, +[2:11:54] it's just not that uh hierarchy thing, +[2:11:56] right? Yeah. So, so there you go. I +[2:11:58] think that's everything. +[2:12:06] All right, let's see what else I've got. +[2:12:09] Um, +[2:12:12] yeah. So I guess um +[2:12:15] one interesting thing about what you +[2:12:17] were saying is that what it has to do +[2:12:19] with like the the object-oriented the +[2:12:22] original object-oriented work came from +[2:12:24] these like distributed systems and +[2:12:25] everything and I know you've talked a +[2:12:27] lot about in the past like Conway's law +[2:12:29] and how like introducing these +[2:12:31] boundaries +[2:12:33] or it's not introducing these boundaries +[2:12:35] it's the fact that when these boundaries +[2:12:37] arise they cause friction or difficulty +[2:12:39] and I guess um would you characterize +[2:12:42] this object-oriented thing is like +[2:12:44] creating those boundaries unnecessarily. +[2:12:45] So they didn't arise from the problem +[2:12:47] and so they're causing they're causing +[2:12:49] difficulty in that way. +[2:12:50] >> Um I would sort of say that I guess the +[2:12:54] only the only like caveat I can think of +[2:12:57] there is I think that the part where you +[2:13:00] said the problem ar like the problem +[2:13:03] doesn't arise from it or whatever or the +[2:13:04] or the you know it doesn't arise from +[2:13:06] the problem I think is how you phrase +[2:13:07] it. I think a person who thinks in terms +[2:13:10] of object-oriented programming and is an +[2:13:12] afficionado of that would claim that it +[2:13:15] is arising from the problem because the +[2:13:16] domain model looks like this right and +[2:13:19] so I don't agree with that but I don't +[2:13:22] know what they would agree with right +[2:13:24] and so from my perspective I agree with +[2:13:26] you these are things that just because +[2:13:28] as a human you're going I like to +[2:13:31] categorize things into groupings because +[2:13:33] that's something that we do right +[2:13:34] linguistically +[2:13:36] it's all quantum physics at the end or +[2:13:38] something, right, bro? So, it's like +[2:13:40] these are arbitrary categories that +[2:13:41] we're drawing. There's no reason to +[2:13:43] think, you know, just like I don't think +[2:13:45] the laws of the universe think of you as +[2:13:48] Ryan Flurry in a computational sense, +[2:13:51] but I think of you that way, +[2:13:53] >> right? +[2:13:53] >> It might not make sense for you to have +[2:13:56] the computational version of Ryan Flurry +[2:13:58] be about Ryan Flurry instead of just a +[2:14:00] collection of things that produces to +[2:14:02] the end user the effect of Ryan Flurry. +[2:14:04] Right? to me anyway that's sort of the +[2:14:07] difference there right it's like I don't +[2:14:08] see that the model inside the computer +[2:14:10] may have very little to do with the +[2:14:12] model experienced by the user which +[2:14:14] again is in direct conflict with like +[2:14:16] what Alan K wanted to do he wants and +[2:14:20] again you have to remember the mindset +[2:14:21] he also comes he wants to do education +[2:14:23] he wants to teach people about computing +[2:14:25] he wants it to he wants it to feel like +[2:14:28] you're programming in the same way that +[2:14:29] you see the real world and in some ways +[2:14:32] I think if we could just get to the +[2:14:33] point where and maybe he does think +[2:14:35] about this now. I'm not sure. Just get +[2:14:37] the point where he says thinks, "Oh, +[2:14:39] well that's just that's just when you +[2:14:40] use an application. That's what it feels +[2:14:42] like. It's not what it is under the +[2:14:43] hood." Then I think I'd be right there +[2:14:45] with him. Right. +[2:14:46] >> So, +[2:14:47] >> interesting. +[2:14:49] >> Um, all right. I'll check my list and +[2:14:51] then +[2:14:52] >> maybe if anyone in the audience has +[2:14:55] questions, then I will ask. But I'll +[2:14:57] check my list first since I'm up here +[2:14:59] talking about it. +[2:15:01] Um, okay. I had two pages. Uh, +[2:15:06] I did that one. +[2:15:12] Oh, yeah. I guess another thing. So, I +[2:15:14] guess I some of these are like not +[2:15:16] exactly questions, but they're like I +[2:15:18] formed a mental model given your talk +[2:15:20] and I want to run it by you and see if +[2:15:22] it makes sense. So one of the things +[2:15:25] another thing that I guess is implied by +[2:15:28] uh introducing these boundaries between +[2:15:30] parts of your program when when you +[2:15:33] could have not done that in the in the +[2:15:35] architecture but you did for one reason +[2:15:37] or another. Um the interesting thing is +[2:15:41] that you were talking about sketch is it +[2:15:43] sketchpad? Yeah sketchpad. it you have +[2:15:46] some layer which is like quoteunquote +[2:15:49] omnisient like it knows it it has full +[2:15:51] context of what's actually happening and +[2:15:53] in my mental model I'm like that's +[2:15:54] similar to when like an actual like +[2:15:57] civil engineer or something is like +[2:15:58] going and building a bridge like they +[2:16:00] they're not like how do I build a bridge +[2:16:02] without knowing what the landscape looks +[2:16:03] like kind of thing. So it's like um in +[2:16:08] that in that so a lot of the design +[2:16:09] decisions in C++ or in in all of the +[2:16:13] other paths that you that you iterated +[2:16:15] it seems like they're about like +[2:16:16] removing context or trying to find the +[2:16:18] minimal set of context but I assume like +[2:16:22] that doesn't seem help I haven't found +[2:16:23] that to be helpful +[2:16:25] because of you what you have taught +[2:16:28] basically but but I'm but I'm curious +[2:16:31] >> I kind of feel like you're on your own +[2:16:33] orbit now and you totally know exactly +[2:16:35] what it is, right? I mean, like, yeah, +[2:16:37] >> honestly, you're one of the best system +[2:16:39] architects I've ever seen. Full full +[2:16:40] disclosure, right, folks at home. +[2:16:42] Seriously, like it's insane. So, you +[2:16:44] don't need me to tell you what to do. +[2:16:46] >> All right. Well, thanks. I I appreciate +[2:16:48] that, but um uh so I guess uh you know, +[2:16:54] I think that's probably it. I'm having +[2:16:56] to turn through these two pages here. Uh +[2:16:59] but +[2:17:00] >> well to answer that question though like +[2:17:02] about the like removing that context, +[2:17:04] >> right? I do think like that's part of +[2:17:07] why it's frustrating to maybe look at +[2:17:10] the history a little bit. Yeah. Because +[2:17:11] what it looks like to me from like the +[2:17:14] the bird's eye view is like instead of +[2:17:17] asking how do we achieve code reuse and +[2:17:20] modularity while preserving our ability +[2:17:23] to solve the hardest problems, +[2:17:25] >> it looked more like it was like let's +[2:17:27] just redefine the problem to be simpler +[2:17:29] and solve that. Yeah. +[2:17:31] >> And to me that that was one of the big +[2:17:33] things about the sketchpad thing as well +[2:17:34] where it's like okay you had working +[2:17:37] examples of this that are pretty well +[2:17:38] documented. I mean if I can go figure +[2:17:40] out most of it now looking back at the +[2:17:43] than at the time when you could have +[2:17:44] actually talked to Ivan Sutherland fresh +[2:17:45] off of the implementation where he +[2:17:46] remembered it all right. +[2:17:48] >> Um and so it does really feel like I +[2:17:50] feel like there's a failure to engage +[2:17:52] with the hardest problems. And I think +[2:17:54] one of my takeaways from it, which you +[2:17:56] know, from reading the history, which is +[2:17:59] not it it didn't really change my mind +[2:18:01] about this, it just reinforced kind of +[2:18:02] like my feeling about it, which is I +[2:18:04] think when you're designing new things, +[2:18:06] you should focus on the hardest stuff. +[2:18:08] >> You should say what solves the hardest +[2:18:10] problems because we can always then take +[2:18:12] that and scale it down and remove things +[2:18:14] from it or dumb it down for an for +[2:18:17] people to use in cases where that aren't +[2:18:19] as hard. But it's almost impossible to +[2:18:22] take something that only solves simple +[2:18:23] problems and scale it up into something +[2:18:24] that solves hard ones. And so that was +[2:18:26] that's really the thing. And I don't I +[2:18:28] don't blame anyone in this uh that I +[2:18:31] covered here for that at all because the +[2:18:34] conditions they were working under are +[2:18:35] awful, right? I mean, they have no they +[2:18:37] have none of the benefits we have today. +[2:18:39] They were working with computer systems +[2:18:40] they barely got time on half the time. +[2:18:42] It was hard to debug, all that stuff. +[2:18:43] And they're having to invent all this +[2:18:45] stuff themselves, right? They have +[2:18:46] nothing to fall back on. So it's +[2:18:48] nobody's fault. But going forward, it's +[2:18:50] like when we have good tools, let's +[2:18:51] attack the hardest problems and that +[2:18:53] will be where we get our really good +[2:18:54] architectures. That's my feeling about +[2:18:56] it. Anyway, +[2:18:56] >> do you blame uh Y Combinator at all for +[2:18:59] like the internet or +[2:19:01] >> I'm about to blame them when I see what +[2:19:02] they post about this talk and somehow +[2:19:04] managed to miss all of the good +[2:19:06] arguments you might have about it and +[2:19:07] argue about something else like whether +[2:19:09] or not that was the right use of +[2:19:10] discriminated union, which 100% will +[2:19:12] happen, right? And you're just like, +[2:19:13] "Guys, who cares?" Like that does not +[2:19:16] matter right now, right? But okay. +[2:19:18] >> Yeah. Because I think like actually +[2:19:19] programming that tends to be one of the +[2:19:21] harder problems is know like well I +[2:19:23] don't know you've said it you've said it +[2:19:24] a hundred times already in the talk but +[2:19:26] where you draw those boundaries because +[2:19:28] it's not that modularity stops being +[2:19:29] useful it's that it it's a wall you're +[2:19:32] introducing that makes something more +[2:19:34] difficult and so if you put that right +[2:19:35] into the middle of your of the hard +[2:19:37] problem like you say yeah +[2:19:39] >> and I think the that is the fundamental +[2:19:41] struggle it's why architecture is so +[2:19:43] hard and it's also why architecture is +[2:19:45] potentially difficult to reuse +[2:19:47] architecture not like reuse inside an +[2:19:49] architecture. And it's because when you +[2:19:52] draw those encapsulation boundaries +[2:19:54] properly for a particular problem, you +[2:19:56] save orders of magnitude of work when +[2:19:59] you do it properly. And the where you +[2:20:01] draw them could very well be different +[2:20:04] for different types of things you're +[2:20:05] trying to solve. And that makes it hard +[2:20:07] to say, okay, here's an architecture +[2:20:08] that just works across things. or one of +[2:20:10] the reasons the compile time hierarchy +[2:20:11] thing I think is a bad idea is not just +[2:20:13] because I don't think it's very useful +[2:20:15] in general but it's also because it's +[2:20:17] procrustian it's like this +[2:20:18] oneizefits-all approach that I don't +[2:20:20] think really even fits that many +[2:20:22] problems but it certainly doesn't fit uh +[2:20:24] all problems right and so teaching +[2:20:26] architecture I think it would be better +[2:20:28] to focus on more flexible thinking and +[2:20:31] thinking about drawing the encapsulation +[2:20:33] boundaries with intent not with a a +[2:20:35] fixed model in mind and if that intent +[2:20:38] leads you to a very unus usual placement +[2:20:40] of the boundaries. As long as you can +[2:20:42] prove that it's actually getting you +[2:20:44] that leverage and not introducing cuts +[2:20:46] in places where it makes programming +[2:20:48] difficult, then then you should do that. +[2:20:50] You should follow that sort of weird +[2:20:52] structure because that is probably +[2:20:54] right. +[2:20:55] >> Yeah, that makes sense. Um, okay. Well, +[2:20:59] I've I think I've exhausted all the all +[2:21:01] the questions or discussion topics. Um +[2:21:04] or they would be rehashing things that +[2:21:06] you like I wrote them down and then you +[2:21:08] covered them in the talk and I was like +[2:21:09] okay um so I'll ask the audience does +[2:21:12] anyone have +[2:21:13] >> should we also should we just cut now? +[2:21:15] Is that good time to stop because the +[2:21:16] >> Well, we we can do one we have maybe +[2:21:18] five minutes. +[2:21:19] >> Okay. Okay. Shoot. Sorry. Sorry +[2:21:21] everyone. Um okay. Uh Rafael, do you +[2:21:24] have a do you have a question? You can +[2:21:26] just speak out. +[2:21:26] >> Yes. like um if we had the solution in +[2:21:29] the 60s and we saw the power of like +[2:21:32] sketchpad and like why was let's call it +[2:21:35] dark oop still able to gain foothold and +[2:21:39] catch on and suppress the good solution +[2:21:41] was it because was it a successional +[2:21:43] knowledge transfer problem or was it +[2:21:45] just because dark oop is such a catnet +[2:21:47] for programmers because lots of +[2:21:49] interesting problem how do I represent +[2:21:51] that or like or or was it something else +[2:21:53] like why does it catch on +[2:21:54] >> I mean it's very speculative to try and +[2:21:56] Yes, something like that. Obviously, uh +[2:21:58] I think you touched on some of the +[2:22:00] answer there, which is that like I do +[2:22:02] think people want to divide things into +[2:22:04] hierarchical categories kind of +[2:22:05] naturally. I mean, we did that with the +[2:22:07] natural world when we were trying to do +[2:22:08] biological classifications long before +[2:22:10] we had really any basis to do so like +[2:22:12] before we knew about, you know, DNA or +[2:22:14] anything like that or or how, you know, +[2:22:17] uh those things might have happened. So, +[2:22:18] I think it's a natural thing for people +[2:22:19] who want to do to make those +[2:22:20] classifications. So, there's some of +[2:22:21] that and thinking that there's this easy +[2:22:25] sort of model that just goes from what +[2:22:27] you see, it's like wizzywig +[2:22:28] architecture, like what I see in the +[2:22:29] real world is just what the code looks +[2:22:30] like and we're done, right? Um, so think +[2:22:33] there's a little bit of that, but I +[2:22:35] think the real story is just that +[2:22:37] history is very messy and in order for +[2:22:40] something to gain traction, somebody has +[2:22:42] to like champion it. Someone has to do +[2:22:44] the work of implementing it into a +[2:22:45] system and doing a good job of that, +[2:22:47] right? One of the reasons we got the +[2:22:50] sort of compile time hierarchy thing is +[2:22:52] because that's what stretrip kind of +[2:22:54] took away from simula. It's what he +[2:22:55] implemented first into a language that +[2:22:57] became very popular. And he wasn't +[2:23:01] trying to do anything nefarious, right? +[2:23:02] He wasn't trying to do anything dark. +[2:23:03] He's just like, I like this typeing +[2:23:05] thing. I use simul was kind of cool. He +[2:23:08] did the work, right? Um I mean, you +[2:23:11] could say that about uh things that we +[2:23:12] see happening today as well. It's like, +[2:23:14] you know, in order for something like, +[2:23:16] you know, Rust or something to gain +[2:23:17] popular, somebody has to build Rust +[2:23:19] first. Somebody has an idea of what it's +[2:23:20] going to be. Is that idea good or bad, +[2:23:23] who knows? But in order for it to even +[2:23:25] get judged in the marketplace, somebody +[2:23:26] has to do that. And the bottom line is +[2:23:28] nobody who looked at Sketchpad was +[2:23:30] thinking in terms of architecture other +[2:23:32] than what I said, which is like the like +[2:23:33] virtual dispatch basically. And you know +[2:23:35] I didn't go into the talk but Allan Kay +[2:23:38] was he was predisposed also to think +[2:23:40] about that virtual dispatch as being +[2:23:42] very important because the other +[2:23:44] references that I didn't mention uh but +[2:23:46] they were in that quote I said we're not +[2:23:48] going to cover them. They're like the +[2:23:49] Burrows 5000 series computers. Uh, and +[2:23:52] the there's this Air Force this guy who +[2:23:55] wrote a file system thing where you put +[2:23:57] the like way to way that you use the +[2:24:00] files in the file system were sub +[2:24:02] routines that were stored in front of +[2:24:03] the files in the file system. So it's +[2:24:05] kind of like a virtual like dispatch +[2:24:07] thing. +[2:24:08] The Burough's 5000 system also had this +[2:24:11] kind of virtual dispatch where there +[2:24:12] were like tables and things. And so for +[2:24:14] Alan Kay, who we didn't really cover in +[2:24:16] here, there the other three hours of +[2:24:18] slides, they're all there, right? But +[2:24:20] what he actually was seeing was he was +[2:24:22] seeing commonality there. He was like, +[2:24:24] "Oh, the Burrows 5000, that Air Force +[2:24:27] thing that I thought was cool. Uh, +[2:24:29] Simula and Sketchpad are all doing this +[2:24:32] dispatch table thing, and they're all +[2:24:34] like making classes with these +[2:24:35] dispatches on them." And then he's +[2:24:37] thinking molecular biology and this +[2:24:38] messaging like you're going to respond +[2:24:40] to these messages. That's what these +[2:24:41] dispatches are. or they're like how +[2:24:42] you're responding to different messages +[2:24:44] and he just goes down that path because +[2:24:46] he's he's thinking that that's the core +[2:24:48] thing, right? Because he's presupposed +[2:24:50] to see it because he's encountered this +[2:24:51] idea multiple times and so he's +[2:24:53] predisposed I think to think that that's +[2:24:54] where the power of Sketchpad comes from +[2:24:56] because like let's face it, would we +[2:24:59] have recognized that power at all if we +[2:25:01] hadn't had all of this experience? And +[2:25:03] like you know I it I just randomly kind +[2:25:06] of stumbled upon this like oh wow wait +[2:25:07] okay like that's really kind of +[2:25:09] interesting sort if I had never seen an +[2:25:10] ND component system before would I ever +[2:25:12] even have thought of that? Probably not. +[2:25:14] >> So I think it's just it's a really hard +[2:25:15] it's a really big ask. It's a tremendous +[2:25:17] ask to ask someone who's like inventing +[2:25:19] C++ or inventing simula to somehow get +[2:25:22] all of that. It's it's just not it's +[2:25:24] just not plausible, you know. It's not +[2:25:26] plausible. It's a hindsight thing. +[2:25:28] >> Yeah, +[2:25:28] >> I think. Sure. +[2:25:30] Um uh we have a question right here. +[2:25:33] >> So it seems to me that the pattern is +[2:25:35] always the same. Like you kind of come +[2:25:37] from school. It was my pattern too and +[2:25:38] it seems that it's yours, right? You +[2:25:39] learn a certain way and in school +[2:25:41] everything is kind of tied to business +[2:25:43] stuff, right? So it's it's very easy to +[2:25:44] think about you have a client with an +[2:25:46] invoice with items, right? And usually +[2:25:48] it's not even it doesn't go that deep +[2:25:50] into very high hierarchies, but we kind +[2:25:53] of just learn that pattern and then we +[2:25:55] just start using it. And you have a +[2:25:57] hammer that is a melee weapon that is a +[2:25:58] weapon and whatever. And then we have to +[2:26:01] have the luck of finding somebody along +[2:26:03] on our path that kind of snaps us out of +[2:26:05] us and shows us a different path. But +[2:26:07] also these people are kind of +[2:26:10] disappearing from the industry. So my +[2:26:12] question is like how do we fix this +[2:26:14] problem? How can we improve this? +[2:26:16] Because it kind of feels like you're +[2:26:18] trying to get smokers from stop smoking +[2:26:21] long after they're smoking. You know +[2:26:23] what I mean? So you're +[2:26:24] >> Well, I guess I would say you're at the +[2:26:26] right conference. I I mean that's like +[2:26:29] right I mean I don't know you start +[2:26:31] doing stuff like this and you try to go +[2:26:33] through the history and show how it +[2:26:34] happened and stuff like that and that's +[2:26:36] that's it you know I mean that's the +[2:26:38] best you can do is put these ideas out +[2:26:39] there uh suffer the hacker news thread +[2:26:42] that you will then have to uh endure +[2:26:44] right or whatever else has to happen and +[2:26:46] then you hope that maybe some of those +[2:26:48] ideas get picked up and people think +[2:26:50] about it more critically I think we're +[2:26:51] out of time correct +[2:26:53] >> there is coffee we're going on break now +[2:26:55] we'll be back at 20 or dense. +[2:26:59] >> All right. Uh well, hope I I will be in +[2:27:02] the audience uh anxiously watching this +[2:27:04] talk. This is this is from Tearown, +[2:27:06] right? +[2:27:06] >> Uh I think so. Yep. +[2:27:08] >> Okay. I'm excited to see this one. I'm +[2:27:09] really looking forward to it, Dennis. +[2:27:11] >> All right. So, we'll be back here at 20. +[2:27:13] >> Thank you, Ryan. +[2:27:14] >> Yep. \ No newline at end of file