 The T2 Tile project is building an indefinitely scalable computational stack. Follow our progress here on T Tuesday updates. They used the same music as last time. You know, there's like a serious chunk of a undergraduate degree in computer science in that 90 seconds that we just saw. There's, you know, data structures, algorithms, modular design, all kinds of stuff in a spatial form. And all it's what this project is all about. Taking existing ideas and re-understanding them in a context where number one, we have an actual explicit spatial layout that matters. We do not have long distance communication. That's what makes space matter. And number two, we have so much space that we have to deal with things failing. That is the project. So what I want to do now is dig through a little bit of the computer science that there is in the video that we just saw. And then that'll be mostly it. Okay, so let's give it a shot. So part of what you saw there, and we'll look at a few little static examples in a sec, is a stream communication system where we have two piers, which I've made a left pier and a right pier that can exchange packets, some sort back and forth between them. And that's done with the QStream API. This is QStream 12. It's the second major version that I've worked on in the last two weeks. And it all boils down to these two functions, get next site number and is pier. And get next site number, which you say true if you want the left pier in the leftward direction, or I'm sorry, if you want the next step in the stream in the leftward direction, or false if you want the next step in the direction in the rightward direction, and then a predicate pier that you can call to say, are we done? Is this the left pier or is this the right pier? And with just those two bits of information, then the QStream package provides the services that you call advance every time you have an opportunity during an event to let it take care of its own business. And then you can send, you can say send from the left, here's a payload receive from the right from the left, here's a payload place to put it, and so on. And this is the emerging API for best effort computing that seems to be working out nicely. They all methods return a bull, they can all fail. So one level of best effortness, one level of seeing the impact of not necessarily having everything being perfectly lined up and guaranteed correct, is that every method may say, well, sorry, I just can't do it. You can try again later. But I can't do it now. And that's how the stream API works. And actually, even in the case of get next SN, which is an exception, because it returns a site number instead of a true, a true or false, there's a special site number that means I couldn't do it either. And so we took that stream QStream 12, and made some tests with it. So here's one that implements test stream 18, that implements the left and right next steps by explicitly having data members inside itself or saying this is the left, my left site number, use my right site number, and they have some behavior to create links of these things spread out in space. And here's an example of it. This is actually test stream 17. It's an earlier version, but it's similar stuff. So we have these streams that have blue and red packets in them when they're moving through the system. And it works great. And the beauty of having a nice API, a nice general API is that you can use it in many different circumstances. So here's test 18 that also inherits, so saying colon or plus means this I inherit from, I can provide the services that these various things name has QStream 12 minute, and it has B2D plate. And now instead to perform, there it is, to do get next site number, instead of looking at a data member that says where it is, it just says, well, if I'm not on the border of a plate, then there is no next site number. So that's the error condition SN.max of that means you shouldn't have called me there is no next SN. But otherwise, if you want to go left, I'm going to figure out the counterclockwise border site. And that's where we should go. And if you want right, then I'm going to figure out the clockwise one. So the and everything else remains exactly the same. And here's an early example of test 18, that's got two of these guys down in it that are connected to each other just by their coordinates. And it works really well. Here's a case where I was debugging the way I'm using the border scanning provided by QStream in this fashion is just to say, we're going to send a patrolman around to see how much clearance there is all the way around to decide if we can move or grow. So this is before there was proper interlocking and the zillions of packets going in both directions around the ring, which is completely legal as far as the QStream is concerned. But it wasn't actually what I wanted to do for this particular application. And so what we saw at the very beginning of the video that started this episode, there was those those purple pink purple dots that were kind of going around. And those were packets, those were border patrol packets going out. And what were they doing? They were measuring clearance. So this is when I was debugging it. We've got all of these things. These are the borders. There's one of the packets going around. It's just it's not like it changes the element type. It's the same thing. It just knows that now it's got a particular packet that's destined to go leftward or rightward. In this case, they're all going rightward. And we have these various obstacles. So here the clearance is three, and then here it's infinity. And then here clearance is two, clearance is one, clearance is zero and so on. So the idea is once you get all the way around, you record inside the packet the minimum clearance to the northeast, south and west, and you report it in and report it into who? Well, last time we had a stack operator that I put up just outside the stack plate that we were working on that issued commands to the stack. Well, one of the things I figured out in the last two weeks is it makes a lot more sense to reserve a column inside the plate for the operator. So the first column right here, so this is that's is one one in plate coordinates. This is one two and plate coordinates one three one four. In this particular thing, I'm making a convention for these kind of plates. I mean, plates are being used for lots of things. They're super great. But in this particular case, where they're being used for containers, data structures that contain things that have operations like, you know, insert and remove all that kind of thing, reserving the first column for the operator has worked out great. And now in fact, we have multiple operators. So there's a plate operator whose job it is to deal with the the kinesis the body of the plate itself, the size of it, its position, its clearance to the neighbors, because basically, whether we're using us using a plate for a stack or a map or a who knows what, we're still going to want to have all those basic take care of the body, don't bump into things grow and so forth. And so we take that out of the thing and we give it to the plate operator. So it's got room inside it to remember all for inner clearances how much what's the minimum amount of space inside the thing, which is important if the thing ever wants to shrink. At the moment, my code doesn't know how to shrink, but it's there. And the outer clearance, which is that what we saw is there zero one two three four or more four or more is all just represented by four in the outer directions. And so that's where the reports go in. And that's where the commands to do things like move and grow that we saw in the opening video get issued by the plate operator. So last time it was this stack, this nice little thing where you know you put things in the left hand side and they would automatically shift down to make room so that you'd have room to put in another thing if you wanted to. And then when you remove them, they would pop back out again. And there's the stack operator sitting on the outside of the plate. And we had a lot of stuff about figuring out where's the best place to put it because you need to be able to reach into the plate to the position to put items down to get them pushed and popped. Again, moving the operator inside the plate not only makes it easier to move the plate because the things that want to move with it are inside it. It also gives it better access. So the event window the four in each direction that the operator is at it can reach deeper into the plate as well as still reaching outside the plate to remove stuff and so on. So there it is. It's just got it's half full, whatever it is. And this was the picture from Wikipedia of what a stack is. It's got action at one end, you can push at the end and then pop again at the same end. And that's great. But there's a lot of other data structures that you might want. And one of the ones that's a real workhorse is the deck, the double ended queue, which is like a stack in that you can push and pop at one end if you want to, but it's double ended. So you can actually insert and remove from either end. Well, now how are we going to do that in a spatially distributed computation with the stack? Whoops, our stack here. We have the one end where we push and pop from so all the items can automatically just kind of flow to the left to be a bit but not too close, you know, available for popping but leaving room for more pushing is what the stack is all about. But if we want to pull them out the other end, there might be nobody there. Well, so what we do is we just turn it around. At least two common ways to officially implement a deck. Yeah, that's if you're assuming we're still in CPU and RAM, but we've moved on. So here's the deck, it's two rows. And we can push and pop on the bottom row or the top row. So we've got three in the bottom row, I have three items and one item in the top row, they're reached one by two little mini plates. And the way we do it is we write rules. Well, so here's one that's got more stuff in it for in the bottom for in the top this one, the bottom is nearly full. The top is much looser, more spread out, and so on. And the key is we want we're going to have to balance things out. This one's very nice because you know, so back here, this guy, we'd really like to take this item and stick it up on the previous one, right? Oops, I can't do that. So that it's balanced out. So we in fact make rules for that where the yeah, here they are. So the rule first rule is, you know, if we have an item, and it's crowded against another item, and there's empty space to the right, go ahead and move it to the right so that we have a space in between it. That's where the springiness comes from. But on the other hand, if we have two empty spaces to our left, then we move the item to the left. And that's where the automatic closing up after a pop happens. Two more rules for the deck is if we have, like on this case, the bottom here, if we have an item sticking way out, and in the other row, we have a whole bunch of empties, then we take the rightmost empty and we pop, we roll it up to the top, and a symmetric rule to roll it down. And you know, this notation is not important to understand. This is not actual code. This is just from my notes file. But folks that might know about Splat. These are like Splat rules, but there's no at sign. In a Splat rule, the way it's actually implemented, you have to say who's having the event. That's the at sign. And in this case, nobody is saying who has the event, because they all work in terms of plate coordinates. So the way these rules are implemented, it could be a guy who's like down here someplace. Not even part of the rule, as long as his event window spreads over the entire thing, and he'll recognize this, he'll say, oh, hey, I see two empty spots followed by a guy, I could move that guy to the left and that would be the propagate the remove rule, I will do it. And this increases the performance quite a bit. And it also means that those empty spaces, the border and the gaps in between the rows, those are the ones that are actually doing the work. The items here, those two things, you know, they don't actually move themselves at all. They're just passive. They're getting slapped around by the events happening all around them. It's kind of cool. So I did this rule with the roll down where it would make sure it was only strictly downhill, only if we had an item with all three empty in the other row, did we actually do it so that it was clear that we were better off taking one that was in this row and moving it to the other row. But that, and in this kind of case, it worked good, because, you know, here's an item, here are three empty spaces above it, so we can apply the roll rule and move that guy there. But this happened a lot, that one of the roll, one of the columns would be, its springs would be very loose. And the other one, its springs would be much tighter, but they would, so they would end up looking identical and nobody could move. And even if this thing shrunk up a little bit so it had one there, it still wouldn't look like it could move. And that was a problem. I had a bunch of stuff where, I mean, it still kind of worked, but it got, everything got blocked until the loose one got so loose that got enough removes out of the loose one that it started to go back and then finally the crowded row could move on through. But in the meantime, there had been unable to do further inserts on the bottom row here because it looked full. So I figured this went out, this was nice. The idea, let the last bean bounce back and forth, instead of saying, no, I'm only going to move an item from one to the other. If it's a strictly downhill move, if I see it's clearly making things better. Now, even if it's just going straight over, it's not actually going any further. And so you let it do it. And it gets up here. And then if it gets another event, it might be just as well to go bouncing back and forth. It's a weird oscillation, which I thought is necessarily, it's got to be bad. It's got to be stupid, but it's not. So what happens is, is it moves back and forth on both sides. But when it's on one side, it's much more likely to trigger a compression on the loose side. Because now there's going to be two next to each other. So the rule for moving to the left will be available. Whereas when it's on the tight side, it's less likely to be able to do anything anyway. It's all crowded. It's still all crowded. So this worked very well. And now we always get these things where they're lined up pretty well smoothed out. And very little, you know, the demo that I'm doing in this case is pushing and popping from both ends, but it's mostly pushing in the bottom and mostly popping in the top, as if it's like a pipeline. And we're feeding stuff through the pipeline with occasional burps back and forth. And this does a great job keeping the rows even. And here's the case when I was still debugging the Q stream communication going around the border where the thing is actually fairly full of something. What is it? What is it actually full of these green over blue? Those are little pairs. What are they? Well, you know, it's the plate operator. Well, so the plate operator is the one that we saw that was doing the sizes. And here it's actually measured the inner clearance. There's zero clearance from the west, zero clearance from the north, four from the east, three from the west. Why is it zero from the west and north? Because the plate operators are right up there in the corner. So, you know, we're never going to be able to shrink from the west and north, unless we do something pretty radical. What is in these data structures? What is in the deck? It's a thing called a single quote. And this is, I love this too. You know, all right, so single quote, it's an BDD plate to that's a specialization of a plate. It's got the payload and so on. And then what is it? It's payload, its payload is 48 bits. And it's got very little in it, except for the payload, because 48 bits is pretty big when you only have 71 bits to play with in general. And why 48 bits? Because 48 bits is half of 96 bits. Well, who cares about 96 bits? 96 bits is the size of an atom. The fundamental size and the movable piece machine of every atom is 96 bits. If you don't use them all, they just float a long wasted and you cannot go bigger. So with two instances of single quote in a little one by two mini plate, two atoms of single quote can hold one atom of anything. That's why it's called quote. An atom, when an atom exists as an atom in a site in the event window, it can do stuff. It can have events. It's live. It can perform computations. But by quoting it and splitting it into two pieces and putting them in single quotes, now it's inert. Now it's data. It's not program anymore. It's like taking an ASCII byte, a dollar sign, a quote sign, anything and expressing it in hexadecimal. Now hexadecimal takes two bytes to express one byte of underlying data. That's what this does. And what this allows us to do is say, well, how could you express this? I wish to tell you to do this and do this and do this. How could we actually say, do this, do this, do this? We could say it by sending three atoms, each quoted. Say, do this means I send you a single quote and when you decode it, so we have services to quote an atom into a single quote pair and to take a single quote pair and turn it back into an individual atom, then it becomes live again. Then it's capable of having events in the event window and often goes about its business. So the program data distinction is absolutely real here. And that's what those things are in the deck, that light blue, the turquoise and blue colors, those are single quote item pairs, one by two little mini plates that the atom deck is storing. And that's what I've designed the deck to do. It stores each item is one atom and you can do anything you want with it. You put them in, you put them out. You can use a deck as a buffer when you're shifting stuff through. If you need to collect it up for a little bit before downstream is ready for it, stick it in a deck. And once the thing's ready, it can pull them out and so forth. So we can ship streams of atoms around in a safely quoted form as code, as program, rather than as executing objects. It's fun. All right. That's it. That's what was in that video. I mean, there's actually a whole bunch of other stuff too, but I want to take the time. I'd love to take the time, but I won't have time to talk about it. So what I'm going to do these days is I'm going to try to put the coolest stuff first, because that's what you're supposed to do. Every, you know, right journalist writing a story, you put the most exciting stuff in the headline and the next most exciting stuff, you put it in the first paragraph. And if anybody reads the rest of the paragraphs, well, then you're lucky. So instead of having top stories, which are all full of boring old stuff, well, I mean, they're not necessarily boring, but they're not widely interesting. I'm going to have the insiders report at the end of the episode of all of the stuff, which is important from the bigger perspective, because this is where the stuff that I'm supposed to be on the comm- that y'all are supposed to be helping keep my feet to the fire, saying, hey, last time you said blah, where's blah? So first off in the insiders report today is, you know, okay, where are the T2 tiles and all this? The things that we saw this time, the things that we saw last time, that's in the MFMS simulator has nothing explicitly to do with actual T2 tiles. Well, the T2 tiles, whoops, here we go. The T2 tiles, I've got them set up in another room now, and they've been running the original plate tectonics demo for days. And I've got a camera, you can see it's kind of fuzzy, but it's not super terrible. There's still lots of issues about how to record the T2 tiles, actual T2 tiles in ways that look half decent. But as I was reviewing the time lapse, my setup just automatically generates 50 to 1 speedups, and then I can go from there to higher levels of speedups in post-production. I found this, which was followed by this, and this, and this, and this, and nobody was messing with it, it was just sitting there quietly. So they got a fatal error, the engine restarted, and the entire thing is like one of those machines that you turn it on, and all it does is turn itself off. It's got the location, it's got the actual issue, where is it here? T2 Event Window, CPP, Line 968, incomplete code. I'm well familiar with that particular site, because it's a part of the code that's supposed to be dealing with a timeout. We've done all of this great work, and we're waiting for the guys to tell us that they have recorded the information that we told them about this event, and we waited, and we waited, and we waited, and they never came back and told us, and we didn't know what to do. That's what happened there. And I'm not 100% sure, but I'm pretty well sure that actually what happened is once things get really rocking, and that was a case where there was a big plate that was just across the edge of the border. The first row of a big plate was now spread across the upper two tiles, the rest of the plate was in the lower tile, and that would create a tremendous amount of intertile events going in both directions, because all three tiles are now having events that will create significant changes that will cause significant traffic. I'm pretty sure what's happening is packets got lost, packets got dropped, the buffering through the system, something filled up just temporarily, something had to get tossed, and the cash update protocol not ready to deal with it. This goes all the way back for folks that haven't been here quite as long as other folks, back to 2019 at least, as far as the software that's controlling the T2 tiles to do events back and forth. And this is the simple view that it's got. One tile says, I'd like to do an event. Can you give me a lock? Other tile says, yes. Then it says, okay, I'm about to give you the cash update. Here's the cash update. Here's the cash end. Here comes the saying, hey, I got your cash update and so forth. This is the happy path back and forth between two tiles. When tile A ends up having the right to hold an event that includes stuff that tile B can see. And what does not appear here anywhere at all is what if some of these packets get lost? What if the update in packet gets dropped? What if the cash update act packet gets dropped? There's no support for it because I didn't think it was going to be necessary. But I think it is going to be necessary. I think we're going to have to go back, redesign this again, make it more like the internet, make it more like the TCP stuff where there's, if there's a timeout, if there's no acknowledgement, come back, you actually wait and be willing to send it again. It's going to be a big tear up. But I've had in the back of my mind, I didn't want to talk about it, that it was going to be necessary. I think it's going to be necessary. The state machine is going to have to get redone. My only hope is that having lived with it for a long time and had a sense of how it worked, the redesign will go smoothly. Also, I was supposed to be doing foundation stuff. I did a little bit of foundation stuff. The nerd emails will be going out. Oh, notice that's future times. The website is getting a refresh. It's going to have a news button. If you go to livingcomputation.org, it's not there yet, but it will be there soon. And we are starting, and I have two minds about this in the grand scheme of things. We are getting further into bed with Google. Google has a program called Google for Non-profits where they'll let you get email handling and documents and spreadsheets and all kinds of stuff that they have for free. If you go through this process of establishing that you are a proper non-profit and so forth. I did that process and Living Computation Foundation is now going to get more googly for better and for worse. That's it. All right. So next episode in two weeks, what I want to show you is the replication that we had in that opening video. It just said ship packets through the deck and once you've received your hundredth packet, spawn two seeds that grow a new atom deck and so forth. And that was fine. That was fun. But what I want to show is a have, you know, one of the things you can do with a deck is have a ring. Have code just going around and around in a circle. Pop it off one end, push it on the other end and use that to take quoted atoms which we will unquote and have the atoms that are in the ring of code turn into real atoms and get executed. And with the result that the thing makes a copy of not just the atom deck and the operators, but the ring of code itself. So we have a code replicator, which is usually where, you know, people that are working on artificial life and the sort of, you know, mechanics of replication. That's where they want to get to as fast as possible. Now with robust indefinite scalability stuff we've delayed getting there. I want to be there next time. Didn't do a big recap of everything. That made me feel sort of tired. I feel like I've been recapping all the time. I'll do it at some point. But right now I was excited about the the plate tectonics and the data structures. It feels like I'm making progress rapidly and I just had to go with it. Hope you guys are doing all right. Sorry for yakking on so long. Hope to see you next time.