Hewitt, Meijer and Szyperski: The Actor Model (everything you wanted to know...)

Source

Eric! Hey Charles, how are you doing? Great, man! Laying those next rocks! Yes! Yes!

What's going on? Okay, so here we are with, you know, three academics: Clemency Sparsky, Carl Hewitt, and what we're going to do is talk today about actors. Everything you always wanted to know about actors but were afraid to ask.

Excellent! We can now ask the questions to the guy who invented actors. Because actors — people talk about actors here and we're afraid to ask. Excellent! We can now ask the questions to the guy who invented actors. People talk about actors here and there, but they use the term in a very informal sense.

Carl has a very precise definition of what an actor is, and that's what we're going to extract from his mind today. Clemence is going to help me with that. We'll dive in. Yes, that's right.

Okay. Good job with that, too. Right on. So, Carl, what is an actor? It's not somebody who's just kind of in a TV show or like us right now.

The actor is the fundamental unit of computation. As the fundamental unit of computation, it has to embody three things. It has to embody processing because you have to get something done. It has to embody storage because you need to remember and store things, and it has to embody communication.

An actor is the fundamental unit, the primitive unit, that embodies all three essential elements of computation. I'm ready to speak here, sorry. I started to count with one. Yes. Okay.

You're getting old. Yes, too long out of the Netherlands. It's like Dijkstra is kind of... Yeah. So now, okay, this is great.

An actor embodies these three things. Now, people often, when they talk about actors, refer to things like mailboxes, message queues, concurrency, and locks. So how does that fit into this picture? That's a very good question. The first thing is that we have to be reminiscent of E.O.

Wilson, E.O. Wilson famously said that one aunt is no aunt, right? Well, one actor is no actor. They come in systems.

And so, in order to communicate in systems, they must have addresses so that one actor can send a message to another actor. There's no reason an actor, like Factorial, can't have an address for itself; this is how we implement recursion. Okay. However, the actors are very abstract because, beyond this, all we have are certain fundamental properties of actors. For example, the first property is that everything is an actor.

Okay. And then you say an actor has a mailbox. Well, a mailbox is an actor, so now the mailbox needs a mailbox. Yes, this is a disaster.

Now we need a mailbox for the mailbox. This is a disaster. We're going down the rabbit hole, that's right. Ha ha ha ha! I'm going to use this again.

That's right. Roman numerals. What can they do? All they can do is create some more actors. They can send.

Messages to actors that it has addressed before can specify how they will handle the next message they receive, and that’s it; everything else has to be done outside of that. Okay, so the third thing again is that you designate how you’re going to handle the next message you receive. Okay, good. Does that have something to do with continuations? Well, no, because continuation was an old idea for the von Neumann machine. A continuation is the lambda expression that you execute after you finish executing the current one.

So that's a single-threaded kind of idea, whereas this has to do with concurrency. If you're a checking account and you have a balance of $5, you might receive a deposit message for $6. Now your balance is $11, right?

So you say that when I process the next message, I will do so with a balance of eleven dollars. I won't change any of the names I have now; the change will only apply to the next message that comes in. Okay, I have a clarifying question.

So here you mention that when deciding how to proceed, it states that you kind of designate what to do with the next message. However, in this message loop, there is no loop. Where is the ability for an actor to run and do many things in parallel? Can it only send messages to other actors, create new ones, and perform other similar actions? Okay. In an anomaly-first approximation, it processes one message at a time.

Okay. But implementers know how to pipeline messages in certain cases. In situations where you're going to process the next message in exactly the same way you're processing a concurrent message, such as with a factorial calculation, you can handle all of them simultaneously. Therefore, you can be processing an arbitrarily large number of messages at the same time for a factorial. However, conceptually, you process one message at a time, while the implementation can allow for greater concurrency.

That's right, yes. Okay, so is it okay if I write that down? Because I'm looking for the conceptual model, right? The conceptual model, that's right. Yes, we are looking for the conceptual model.

So conceptually, okay, so now, of course, the question is: I put an asterisk on that because the loopholes are large. Okay, so I'll... Yes, right. So now, the question is, what happens if an actor sends a message to itself, maybe directly or indirectly? Would it go into a deadlock? Well, okay.

The next thing we have is the notion of a future. Okay. Future. We all have a future. We all have a future.

We hope, right? The idea of a future is that you can create an actor for any result while it's still being computed. You don't know whether it's finished computing, starting, or whatever. But now, you can have an address for something.

It's like when you buy a futures contract for a bushel of wheat, okay? Yes. It’s for a bushel of wheat, not right now, but in the future, okay? If a drought happens, the future will change, and you might get an alternative instead of a bushel of wheat. Well, these futures work in the same way.

But they are actors; you pass them around. For example, you say, "Future of the factorial of 100 million," and you think it might take a long time to compute the factorial of 100 million, but you get the future immediately. Okay. You can pass it around, store it, and send it in messages. Now, if you want to send yourself a message to get back to, you can put the message to be sent to yourself in this future, send it to yourself, and now you don't deadlock.

Okay, good. All right, that sounds good. So, Clemens, yes, I'm wondering...

If we designate what to do with the next message, how is that different from creating a new actor? Ah, because I'm the checking account, and I have a balance of $5, and I get a deposit of $6. Right. A new actor with a balance of $11 would be no good because they expect the old actor to have a balance of $11.

All right. So designating what to do with the next message is the next step for me. That's right. Yes. The way I look at it is that, because I think where they say each actor—I didn't write that down—each actor has an address that I can refer to. Each actor has an address that I can communicate with and send messages to.

If the actor was a chicken and I chopped off his head, you wouldn't get a copy of the chicken without the head, and the other one still has its head. So I think the actor actually kind of... But the actors are very powerful chickens. The actor has to agree to chop off his own head. Yes, exactly. That's what he said.

All you can do is send him a message saying, "You know, please commit seppuku." Okay. And then you can send back an exception, saying, "I don't think that's a good idea." So, would the address of an actor be equivalent to its identity?

No, because you can have one actor and one address for a whole bunch of actors if you're replicating behind the scenes, and one actor can have many addresses that forward to one another. So there's a many-to-many relationship among actors and addresses. Is actor identity discoverable? What do you think you mean by identity? If I hold... Can I hold actors as values?

No, all you have are addresses. You compare two addresses to determine whether they are equal or not, but that tells you nothing. So, how do I know, at any level of examining my system, whether I have one actor or multiple actors behind an address? You cannot tell. I cannot tell.

Because, for example, when you do a search on Google, Google has one address: Google.com. Right? It's not the same Google everywhere that is processing your search request, even though you sent it all to Google.com. The same is true for Bing, by the way.

The same is true for Bing. He meant Bing. I meant Bing. I meant Bing. That's right.

We're kidding, right? Yes, of course. He meant Bing. I meant Bing.

I meant Bing. That's right. We're kidding, right? Yes, of course.

That's just beta reduction, right? That's right. But speaking of that, can you have two addresses that, you know, are kind of proxies for the same actor? Absolutely. One of them might just forward messages to another actor.

And you can't tell, okay, whether you're talking to a forwarding actor, a proxy, or someone behind the scenes. Because all you can do with a message and an address is send a message, period. Now you can use encryption, and you can still do authentication. If you create an actor and have the address of that actor you created, you can have a pretty good idea of who that is. So now I have a question about that to continue a little bit on what Clem has said. Let's talk a little bit about these kinds of addresses of actors and about creating more actors.

Because how can you be sure that I didn't just cook up some address? You know, I could randomly generate something and say, "Okay, now I'm going to send a message to this address that I made up out of thin air." So, where do these addresses come from and how are these actors created? Well, basically, within a system like, for example, the CLR, which enforces address integrity, you can rely on the CLR. Between the machines, you use encryption. What you do for your address is send it out encrypted, and when it comes back, if it doesn't match one of your addresses, it's no good.

Okay, so you're saying it's like in the CLR. If everything is implemented correctly, I cannot take an integer and cast it to an object. That's right. So, in that sense, addresses seem to be like capabilities? That's right.

Yes, yes, they are. In fact, you know, the original work by Dennis and Van Horn was one of the inspirations for the actor model. However, they had a very kludgy way of doing it because they had no protection in an address space. They had to put the magic stuff out to the side, and it was just incredibly awkward. If you can maintain the integrity of the addresses, you get capabilities for free.

An address, I think, is a much better name for "capability" because it indicates what you have the right to do, namely send it a message. That is the only fundamental capability. The other inspiration was the work that Vint Cerf and Bob Kahn were doing on the internet, specifically with packets. We say packets are nice, but we need messages. However, these messages will obey the same rules as packets for efficiency reasons.

So if I send Eric two messages in a row, I send you M1 and M2, you might receive M2 before you receive M1 because it's more expensive for the system to try to enforce that constraint. And that's why the U.S. mail system says that if I drop two messages in the mailbox for Eric, he can receive them in any order. I dropped one in today and the other one later. Usually, that is the case, actually. Yes, right.

That's right. I can do it in random order. Yes, that's right. So let's talk a little bit more about that. I'm going to kind of draw the picture here.

So we have two actors, let's say Actor A0 and Actor A1. Let's say that Actor A0 sends messages to Actor A1. You mentioned that if Actor A0 sends Message Zero and Message One, they can arrive in any order. That's correct. Can messages be dropped?

Can they disappear, or are they always guaranteed to arrive? It's best efforts. Best efforts. Best efforts. Now, what does best efforts entail?

Okay. The other question is, if you're going across machines, best efforts entails that you're going across machines, so you'll need to persist the message to some kind of stable storage. This allows you to resend the message if you don't receive an acknowledgment back. On the other hand, if you persist the message and a terrorist attack blows up this machine, the message is gone.

Even though you persisted with it, let's go back to the basic axioms. We didn't discuss persistence and so on. In this conceptual model, the messages are: Is this channel reliable? What are the properties of the channels between the actors?

There are no channels, and this is very important between the actors. There are no channels, and this is very important—no channels.

No channels. Head. You talk directly. There's no chance. You don't have to go through some intermediary called a channel.

Unlike concepts such as Communicating Sequential Processes and process calculi, we have to use an intermediary. The intermediary has a significant problem: if two entities are trying to retrieve something from the channel, only one of them is supposed to get it. This requires going through a large amount of overhead, such as a cumbersome mechanism known as a two-phase commit, just to retrieve your message. The actor model, on the other hand, simplifies this process and operates with a more straightforward approach.

You can implement a channel with a put and a get message to it if you want one, but that's not part of the core functionality. A channel would be another actor. Suppose you wanted to actually sequence these two actors. In that case, you would create another actor called Sequence, which takes parameters m0 and m1, and you send the sequence to this actor. These two actors can also be futures, allowing them to manifest themselves whenever they're needed.

So I understand. I apologize for using the word "channel," but I mean there must be some kind of ether or something. No, it's just photons. There's no ether. Or photons, but these things must communicate. So I was looking for the properties of the communication, in a very abstract sense.

So, so, so. It tries very hard to deliver every message. But can it duplicate messages? No, a message will be delivered at most once.

At most once. Okay, one or zero times and in arbitrary order. And it could take a long time. If this message goes through a mail server in Timbuktu, it might be like one of those messages to Queen Victoria that are discovered behind a closet in the mail at the post office when it's torn down and are delivered 100 years later. Yes, or like a message in a bottle that kind of floats over the sea.

That just floats over the sea. That's right. Yes, that's right. Yeah. So another thing that you often talk about is non-determinism.

You already kind of talked about that with channels. You know that two people have to kind of get it out. Now there's a race, so how does that fit in the picture? And arbiters, you know, that's another kind of beautiful thing. So how does that fit into this picture? The first thing to do... And these are not actors on TV; the arbiters are not like those in a tennis match, right? That's right, they're not. But the ones in the tennis match might be made out of these.

The ball is out—that's the thing about it. We'll get to it in just a second. The arbiter does decide, and there's nothing before the arbiter decides. So, we want to distinguish between non-determinism and indeterminism. Non-determinism is what we have with the original Turing machine. That's when you flip a coin; it comes up heads or tails. If it's heads, you go one way. If it's tails, you go the other way, right? That's the kind of thing you had on the Turing machine, the non-deterministic Turing machine, and it's not sufficient, okay?

Because it doesn't provide you with indeterminacy. Indeterminacy is what occurs when outcomes are determined by how things unfold. It wasn't someone flipping a coin to make a decision; it was a result of how it worked out. Okay, how can this be?

Well, if I'm sitting here, sending my... suppose I start off as a very simple actor. I have a count of zero, and I start off by sending myself a start message and a stop message. If I receive a go message and a stop message, let's write this down.

A "go" message and a "stop" message. Then we come in with a "start" message. So when I receive a "start" message, I send myself a "go" message and a "start" message. Yep. So when I get a "start" message, I send myself a "go" message and a "stop" message.

If I receive a "go" message, I increment the counter by one and send myself a "go" message. If I receive a "stop" message, I then stop and report the current count. Now, this is something that no non-deterministic Turing machine can do because this system can stop with a count that is arbitrarily large. It was not predetermined how large the count was going to be; the size of the count depended on how long it took for the "stop" message to arrive.

Nobody ever flipped a coin. It was just how long it took. So this is a way to move, okay, from non-determinism and non-determinacy to indeterminacy. Does that also have to do with the fact that this message is, in some sense, out of the system? That it interacts with the environment and is not like a closed Turing machine? It's not closed, right? Because that was where we started off.

Yes, there is something called the state. Yes, the state of the computation is fixed. Yep.

And that's why it's possible to prove, and my colleague Gordon Plotkin provided a very nice proof of this, that if you have a state machine model of computation, then it must have bounded non-determinism. In contrast, this has a configuration model. We have the local state of this entity, the count, but the configuration out here has a stop message that's traveling in photons. It's not sitting still anywhere.

So this is a configuration-based model of computation, which is more powerful because it incorporates communication than the state-based approach. Yes, that is an interesting point. Recently, many people believe that Turing machines define computability. However, you're suggesting that interaction with some kind of open environment fundamentally changes what computation means. This distinction is crucial because it differentiates between non-determinism and indeterminism. Is that correct?

That is correct, yes. Robin Milner acknowledged this in his Turing Lecture, where he pointed to the actor model of computation as the inspiration for his development of process calculi. However, the emphasis was different. He aimed to create nice algebraic equations, so he introduced channels to facilitate his algebraic equivalences.

But the actor model didn't, because the actor model wanted to remain faithful to physics' touchstone, not algebra. Physics states that you don't introduce an intermediary, as it acts as an unnecessary source of overhead. Another model that is also inspired by physics is Petri nets. So, how do actors relate to Petri nets? Good question.

Petri nets also do not relate to physics. Let me just briefly explain what a Petri net is. A Petri net is a game played with tokens. In this game, there are elements called places and transitions. You can place tokens (often represented as pennies) on the places. If you have tokens on all the input places of a transition, you can remove these tokens simultaneously and place one token on the output place.

Well, we're still to follow Dijkstra and call upon the law of the excluded miracle. The excluded miracle is that these two pennies at different locations can both disappear at exactly the same time because this one might actually be the input place of another transition over here, and this one could be the input place of another transition over there. So, you actually have to steal both of these at the same time, and the actor model will not let you do that. In this case, you're saying these kinds of tokens will be somehow entangled. That's right. And that's something that you do not allow. Do not allow.

Okay. Not express synchronization? Uh, well... Oh, sorry. No, no, it's okay.

It's okay. So, what is your name? Welcome. Welcome. Come around here.

Yes, come around here. Why don't we push the table? Yes. Hi, I'm sorry for barging in like this. No, that's okay.

Why don't you go in front of the camera? Here we go. My name is Shaz, and my question is about what you described concerning Petri nets, which is essentially synchronization. You said that it cannot be expressed in the actor model. So I was wondering, can you not express synchronization in the actor model?

It would be a disaster if we could not. Yes, we already know the outcome, but we need to explain it. Let's think about the checking account. A checking account is not something you can manage in functional programming because the checking account exists in a state where there can be many parties involved. We don't know who is going to make the next withdrawal from this checking account, possibly from an ATM somewhere on the planet.

The way the actor model deals with this is that an individual actor processes one message at a time. However, it is indeterminate which message will be processed next. For instance, you might have someone in Tokyo depositing $7 while someone in England is withdrawing $8, and the account might only have a balance of $2. The outcome—whether you get your money or not—depends on the order in which the messages arrive, which is indeterminate. In a sense, the synchronization is built into the rule that one message is handled at a time.

That's kind of the fundamental point of synchronization. That's right, yes. And that's where the arbiter comes in. Yes.

Okay, good. Because we know how I love the Arbiter. It's like the Muller C element. That's right, my favorite.

Yeah, my favorite. Okay, so here is the arbiter. I have examples of this. There’s a very nice volume coming out commemorating the 100th anniversary of the birth of Alan Turing, whose machine cannot do this.

But we commemorate him because he was a great man nevertheless. He liked tapes. Yes. In there, I actually have pictures of some of these arbiters and examples in that volume, and you can already order it on Amazon.com. Hector Zaniel is the editor of that volume, and Roger Penrose wrote the preface.

Okay, so what's an arbiter? An arbiter is something that you cannot create using only AND gates, OR gates, and other Boolean components. It has the following properties: it has two inputs, I1 and I2, and two outputs, O1 and O2. So here's the deal.

You start off with both of these at zero. You're allowed to put in both of these at the same time, but only one of them will come out as one. Only one of these things will rise from zero to one. Not both of them, just one. So, is the ball in or is the ball out?

But it cannot be both. It cannot be both, that's right. Yep. And so this is the magical circuit. It consists of cross-coupled gates inside it.

It's a very small thing. Our computers are becoming absolutely chock-full of them. The processor systems have them, which makes things indeterminate. Now, it's more difficult to debug our programs because it used to be that we would input the same data and run it again to get the same bug. Now, we enter the same input, and it does something completely different due to all this indeterminacy inside.

So, can I ask two questions? One is: Isn't this thing behaving like flipping a coin? Where it says, you know, like the coin, it's either heads or tails? It's not. For one thing, we don't know how long it's going to take.

When you flip a coin, this can take an arbitrary long time to decide. Yes, but in practice, it’s like the arbiter at a tennis match. We said we were going to make him out of arbiters. The arbiter at a tennis match can take as long as he wants to make his decision about whether the ball was in or out, but he must decide. Yes.

Okay, so that is a very important property—that it can take unbounded time to complete the process. That's right, but with an exponentially decreasing probability. So, the probability that it hasn’t decided yet decreases exponentially. In practice, these systems work just fine. Now, my second question is this: When we look at the network card inside your computer, if two packets come in at the same time, is there an arbiter in your network card, or how does that work?

How does that machine decide which message came in before the other one? There is an arbiter, okay, but it's an arbiter between what’s going out and what’s coming in. That’s where the arbitration takes place. The original concept of the arbiter was developed when they connected the Turing machine, the Von Neumann machine, to the teletype. This created a significant issue because the computer already anticipates which instruction it is going to execute next, right?

So, you want to have a piece of code to process the character and a piece of code to do what it was going to do before. Now you've just invented concurrency, and you need an arbiter to decide which piece, which value of the program counter to pick next. Is it going to be from the interrupt handler, or is it going to be from the program that was running before? Yes, but this is interesting because you mentioned Dexter before. Didn’t Dexter do a lot of work with interrupt handlers in the THA? That's right; he helped invent this.

Yes. And then he forgot about it? And then ideology took its course. Ah, okay. He could not bring himself to believe in unbounded non-determinism.

He said to himself, "There must be some bound." And then he convinced Tony Hoare. So in the first version of Communicating Sequential Processes, the semantics specified bounded non-determinism. Now, unfortunately, this is a disaster for concurrent systems because if you're a server and Clemens and I are both trying to send input to you, right? If you can make an arbitrary choice, you could always choose me. Of course, I would.

Of course, I would. Right, but with an arbiter here, you see, with an arbiter, which produces bounded non-determinism. So then, in the second version of CSP, the semantics were changed because they wanted to be able to prove that you could actually make a server using CSP that would work and not starve customers. Okay, so this actually has practical importance to it.

Okay. So I'm still fascinated by these addresses. Yes, because how do you kind of... we talked about the community between two actors. How do you know? How do you find them? This is something you abstracted away from. Given an address, how do you find the actual actor? Because, like on the internet, there's DNS, right? If I have that, I can find the actual machine. How does that work, or is that something we don't need to know in this kind of abstract theory? That's right, so the actors are, in fact, very abstract.

Any implementation that obeys the axioms is state-of-the-art. Okay. The achievement of abstraction is to reach the next higher level, where you can operate at a more advanced level without having to worry about lower-level concerns such as locks, queues in front of your actors, and other lower-level implementation details.

But then they also provide, and this is the aspect that has taken the longest time, numerous opportunities to improve engineering and optimization. This is becoming extraordinarily important with the many cores because, as soon as you have a thousand cores on your chip, the world changes. The programmer who writes the program now knows nothing about the environment in which it runs; they don't know what the load is, how many cores there are, or what its priority is. They know nothing. Therefore, the code must now be written at a higher level of abstraction so it can be adapted at runtime to the current circumstances. Yep. So, Clemens, I have a question for you to tie this together, because you wrote a book on software components. Indeed.

Yes, exactly. And that book is also available on Amazon.com, of course. Well, let's get your name on here. Yes.

Yeah, all right. So one of the things that I like about this model, and what I don't see in a lot of the discussions about REST, is that it really gives you a very abstract understanding, as Carl says, of what these things do. However, they don't delve into how the mechanisms work or what happens inside, except to indicate what to do with the next message. In contrast, when you talk about software components, there is a greater focus on the interfaces and the behavior of what happens inside. So, how does that relate?

Is that like a complementary view? In your view, you also talk about callbacks and so on, which have the same kind of notion of deadlock. Can you elaborate a little bit on that? Well, I view actors as a computational model.

That basically allows me to understand how things behaviorally unfold and come about. In that sense, I think it's orthogonal to theories of composition, where you might say, if I have two subsystems and I want them to interact in a way that I understand and perhaps only partially understand, what are the constraints on the composition? How can I predict what would happen if I were to compose them? And I should be able to do this across many different computational models, Actus being one of them. So that's a good question. If I look at this, I wonder, why would I ever want a different computational model?

Because this, to me, is akin to category theory. I'm not saying this just because Carl is here, but if you want to build something minimal, this is all you need and nothing more, nothing less. So, why would you? Well, that's a good question. That's a very good question. But there is a moment we have to be careful about, because Gödel said exactly those same words about Turing's model of computation.

He said, and I quote this in my paper, "This is the end. Nobody could ever conceive, okay, of a model of computation beyond that of the Turing machines. This is the end. Nobody could ever conceive, okay, of a model of computation beyond that of the Turing machine. This is the end."

Famous last words. Right. But there is an art to making programming languages for actors. I mean, it's very easy to screw it up. You can screw it up by violating some of the fundamental principles.

Right. And you can also screw it up by not taking them seriously. For example, there's a funny story here concerning Dijkstra. There is a sense in which Dijkstra got it completely wrong. He wrote a famous paper titled "Go To Statement Considered Harmful."

Yes. From the actor's point of view, the go-to is completely innocent. Yes. It's a parameterized procedure call. Yes.

Okay, pure and simple, right? We have the body right there. It's like designating the thing with the next message without doing anything. No, no, no. That's completely different.

Is that not the same as a go-to? That is not. Nope, nope, nope. Oh, good, so we need to think more about that. Let me explain.

Explain more. Okay, right, so then I can explain the relationship. However, there was a guilty party that Dijkstra overlooked: the assignment command. That is the harmful party if we're going to consider something as potentially dangerous. The assignment command in these many-core systems is excruciatingly expensive.

It can require a signal to go to the other side of the chip for a global assignment command, which is just extraordinarily expensive. Maintaining all this state that you're multiplexing, of course, is also extraordinarily expensive. So, what do you do in an actor system?

Is this part? This is where the assignment command comes in. What you do is process your message. You're purely functional and purely referentially transparent until you figure out what the response to this message is going to be. Then you say, "Ah, the answer is x," and there's this thing called "also." For example, for the checking account, you say the answer is the balance, and also, the balance becomes the balance plus the deposit.

But that's for the next guy; that's for the next message that comes. That's not for us. Yep. So throughout the body of our message, balance is balance. Here, we're returning the balance.

It's an expression-oriented language, so you don't have to say "return." You return the balance. Also, you perform the assignment. What I meant is that if you do the same kind of value now, it's like you're creating a tail recursive call, which is similar to a "goto."

But maybe I'm thinking too far ahead. Well, right. I'm not chasing the states, but I'm just kind of reflecting. But here we are changing. Yes, yes, but if I don't change the balance, I wouldn't change the state.

Right, so it's not a tail call because you're actually changing the state, right? And because of optimizations, it's also not an event loop, which is the other way to misunderstand things. Good. Now, another thing that you talk a lot about is inconsistency. So I'm super inconsistent.

You know, there’s a downside to this. So, why is it important that we don’t try to be consistent or enforce consistency in our world? The first issue is that we can’t. We now have these large information systems; everybody has them, starting with our operating systems—whether it’s iOS, Linux, Windows, or SQL—where you work. We have these large software systems that are full of inconsistencies, and we have teams of programmers, sometimes numbering in the thousands, managing them.

And they have to be able to reason about this and think. You can't pretend that it's consistent because the program manager can open a drawer and say, "Here's 10,000; we already know about the inconsistencies." Similarly, the information available on the internet is all inconsistent, right? So talking about truth is just crazy. Yes, is Elf alive or dead?

Well, that's the thing about Schrödinger's cat, right? Yes. The cat can be half dead because there is cyanide in there. It was supposed to be an alpha particle, right? But if the cyanide particle has gone off and you reach in there, and the cat only has a little bit of the cyanide, we can resuscitate the cat, okay?

Yes. There are things that are clear that go quite far up, but the fundamental situation is that we don't know much, and some of it is wrong. That is the situation in which we find ourselves. It's kind of useless to deny it, because then your emperor has no clothes. It's also a bit irrational to be in "Darth Vader mode," thinking you're going to wipe them out, because you can't do that either.

We had this symposium, and you participated very nicely. You should tell us where we can download the proceedings. Yes, yes, yes. You can find it at robust11.org. There are proceedings available there, and if you look it up, it's under "Inconsistency, Robustness, 2011."

You will find a web page, and there will be another one. There will be another one focused on consistency and robustness in 2014. We are just about to post the call for papers for that one. Great!

And we have the ability to add text to these videos in the description. Okay, yes. But I like the real-time effect. It's nice. Yeah, okay.

All right. I don't know. Do you want to finish? Yes, we have one more.

Okay, we had a good time. I have a takeaway. I'm noticing that it seems like you are modeling local arbitration but not global consensus. You’re essentially claiming that global consensus would be an illusion because it can't really be established. To achieve it, you would have to freeze the universe, basically.

While local arbitration is something you can do, it is indeterminate. However, you can develop a locally meaningful view of your world, which may be completely different from anyone else's perspective. That's correct. In fact, regarding others, all you know is what they have told you. By the time the news reaches you, they may not even exist anymore, much less the circumstances they are discussing. Consequently, you always receive old news from others.

And now, because of Moore's Law, old news can be on the other side of the same chip you're on. It's very local. Very local. Perfect. Yes.

All right. Well, thank you so much, Clemens and Carl. I hope that everyone now truly understands what actors are. Carl has a whole bunch of papers on his website, and maybe we'll learn more about this.

Thank you so much. This was wonderful. Yeah, thank you, Eric. Thank you very much.

And this was wonderful. Yeah, thank you, Eric. Yes, thank you very much.