HomeVideos

Shift-M/56: Douglas Crockford about JavaScript, OOP, JSON, Misty, and actors

Now Playing

Shift-M/56: Douglas Crockford about JavaScript, OOP, JSON, Misty, and actors

Transcript

717 segments

0:00

Okay, so let me start right away. I can tell you a quick story that I wrote a very short article

0:09

on Reddit just a few weeks ago, where I criticized how people use JavaScript these days, especially

0:16

the classes and type annotations in TypeScript. And one of the commenters and readers posted a

0:22

message under the article, which was saying exactly this, I quote. He said, "I missed the crock for

0:30

times." What do you think he meant by this? I have no idea. I didn't hear a lot of that sentiment

0:38

during those times, so I'm not quite sure exactly what that means. I think he was talking about

0:44

different JavaScripts. The JavaScript we had like 10 years ago and the JavaScript we have now,

0:50

and I think he missed the times when we were using the best parts of JavaScript according

0:55

to your book and to your vision. Yeah. Since then, the language has gotten a lot dirtier.

1:01

They just keep adding more and more crap to it. But the good parts are still the good parts,

1:09

and you can still program as though they didn't add any of the new crap, and you can still write

1:16

very good programs in JavaScript. Actually, in 2023, you said in one of your talks that JavaScript

1:22

is a smelly language. And I wonder which forces strongly prevented us from using the clean version

1:33

of JavaScript. What made JavaScript dirty and smelly according to you? Many of the people using

1:39

JavaScript came from other languages, and they were very resentful because they didn't want to

1:45

be using JavaScript. They wanted to be using the old languages. They didn't want to have to be

1:48

learning a new language. And so they used stuff that looked like the old stuff they were doing.

1:55

So if they were doing C# or Java or whatever, they wanted something that looked like that in

2:04

JavaScript. And so that put a lot of pressure to add class to the language and other things.

2:14

This tendency we're seeing now, all of the languages are borrowing features from each other.

2:19

It's like eventually they all want to evolve into the same language.

2:23

And you kind of wonder, why do we have all these languages? But maybe the end of all this evolution

2:33

is there's one language that eats up all the other languages. But that's not really a design path.

2:41

So we go along aggluting features, and the features are often not orthogonally meaningful.

2:49

There have been a few new languages like Rust. There's some brilliance in Rust.

2:55

I think there's also brilliance in Go. But for the most part, all the other languages are trying to

3:01

copy each other. I know that TC39, which was the JavaScript standards group, had a lot of Python

3:09

envy. They wished that JavaScript were Python. Even though at the time JavaScript was much more

3:17

popular than Python, they still wanted to be working on that language and not on the language

3:22

they were working on. Maybe there's a reason for that. They want features that they miss and they

3:27

actually... I mean, there's a practical reason for that, I think. The industry just demands this.

3:35

Yeah. So my contention has always been there's a functional subset in JavaScript, which is brilliant.

3:42

It's kind of like Scheme with dynamic objects. And that is such a brilliant design. There's this

3:52

wonderful, brilliant thing hidden inside of JavaScript. And I've been very successful just

3:58

writing to that subset. And I don't need any of the other stuff. And in fact, the other stuff

4:05

is sort of a burden because it gets in the way. But I'm not the majority, certainly, far from it.

4:16

Well, let's imagine we design a clean language or we get back to JavaScript, originally remove all

4:22

the classes and all the stuff which was added later, and we get to a cleaner language. Do you

4:27

think it's in general possible to have a clean language in the industry and keep it that way

4:33

for a long time? Or any language would be killed no matter what, or could be turned into Java

4:39

eventually, no matter how clean it starts? Yeah. I think it would be dead on arrival

4:44

if it had to be thrown into the ecosystem with all the existing languages, which already have

4:51

lots of publications around them and lots of user groups around them and a lot of legacy.

4:58

But if that language were positioned such that it's solving a new class of problems

5:06

that the other languages do very poorly on, then I think there might be a chance.

5:11

There are many, you know, pure languages and clean languages like Smalltalk,

5:16

Excel, for example, they remain niche languages. They never became standards or, you know, industry

5:23

standards. Yeah, it's a real shame. The Smalltalk 80 was maybe the best designed programming language

5:30

in the history of languages. They spent almost a decade in design and testing of that language

5:39

and refinement and going through many versions until they finally arrived at 80, which was

5:44

really, really good. I think it failed in the marketplace for two reasons.

5:49

One is the early implementations were not very fast. Eventually, that goes away. Moore's law

5:56

makes that irrelevant. So, you know, if we'd just been a little bit more patient,

5:59

that one would have fixed itself. The other was it required that you understand how to think

6:08

in terms of object-oriented programming. And as a transitional language, that's a really hard thing

6:15

to do. So instead, we went with C++, which is an awful language. There's very little defensible

6:24

about C++, but it allowed you to be working with an object-oriented programming language without

6:30

understanding anything about object-oriented programming. You could still write in Fortran.

6:37

You know, it provided better support for the old paradigms than for the new one.

6:43

And people said, "Yeah, that's the one we want." And we're still stuck with it. It hasn't died yet,

6:50

which is amazing. And they've been adding features faster than anybody else. That language

6:55

has been growing and growing and growing. Is there something wrong with us, people,

7:00

or the object-oriented paradigm in general? Maybe the paradigm is wrong.

7:05

I think the paradigm is wrong. I think object-oriented was an important step forward.

7:12

You know, it got us past the procedural. But it shouldn't have been the last step forward,

7:18

right? There should have been another step after it, but we're stuck. We haven't been able to move

7:24

past it. And so, you know, that's a problem. So I think there is a new paradigm out there. And it's

7:35

kind of obvious, if you look at how the world works, what we're doing now, that none of the

7:41

languages do well. So I think there are opportunities to move on, but we're not quite there yet.

7:50

Maybe not the paradigm is wrong. Maybe we just teach it the wrong way. Maybe the schools need

7:56

to be fixed. Or the books. I don't know. I'm the last guy who wants to criticize schools or books.

8:05

So I think it's just that, in general, industry is trying to solve the wrong problem.

8:17

Or trying to solve a problem in an old way and not in the new way. So, for example,

8:26

all of our current programming languages start from the von Neumann machine. The von Neumann

8:34

machine was the first modern description of a digital computer, where you've got a memory

8:43

with addressable cells in it and an instruction processor that can take values from the cells

8:50

and modify them and put them in other cells. And those cells can contain numbers or characters

8:59

or instructions. And that's how all the machines work. We're still making von Neumann machines of

9:08

a type. And Fortran, being the first really successful high-level language, was very much

9:18

about supporting the von Neumann architecture. And all of our languages since then, or almost all of

9:26

them, have been adding features to Fortran. So there's a lot of Fortran. Even some Fortran

9:34

syntax still survives in C. And C has been copied in the syntax of almost all the other languages.

9:41

So at some level, we're still writing Fortran. The problem with the von Neumann architecture,

9:47

and it's a problem shared with the lambda calculus and the Turing machine, is that they assume that

9:55

all of the computation is happening in one machine. And that's not the world we live in anymore.

10:01

Computation now happens in a lot of machines. We've got clients and servers. That's the most

10:07

obvious place. But even in the servers, you often have dozens of machines involved in every

10:14

transaction. Stuff's going all over the place. And our languages don't understand that. They

10:22

can't cope with programs being distributed. They assume that everything's happening inside of one

10:27

memory space. So I think the next paradigm should be one which allows us to more effectively

10:37

effectively deal with running stuff in many places at once.

10:42

And even beyond that, when we first opened up the barriers between machines and let them

10:51

start communicating with each other, that's when all the security problems were discovered.

10:58

Because if you allow me into your machine, there's no limit on what I can do in your

11:04

machine, and if you allow me in, there's a chance that someone else is going to get into.

11:09

And we're still struggling with that.

11:11

We've been dealing with that for, let's see, I think it started in the 70s, so it's been

11:17

going on.

11:18

The problem is almost as old as I am.

11:22

And we haven't solved it yet.

11:24

And we're seeing terrible consequences.

11:26

Like last year, I was, was it last year?

11:29

I think so.

11:30

I was trapped in Berlin when Delta Airlines melted down because of a security problem

11:36

in Windows.

11:40

That was a huge software failure, and it was all about security.

11:45

It's all because we don't understand how to make machines work together securely.

11:49

We've been adding band-aids and ad hoc stuff, but obviously it doesn't work because we still

11:54

see these meltdowns from time to time.

11:57

Technologies are getting breached all the time, all of our passwords are out on the dark net.

12:05

Governments are now attacking each other because of all of these insecurities that are baked

12:10

into the architecture.

12:12

So I think we need to rethink how all of that stuff works and come up with a way of allowing

12:19

programs to work cooperatively with each other and other machines without compromising each

12:25

other.

12:26

We have a student in front of us who is 17 years old, and we start teaching programming

12:31

to that person.

12:33

And we start telling that poor young person that there are many machines and everything

12:39

runs in concurrency and there is no one central line of commands.

12:45

And then we give these students the language which is concurrent, which is parallel.

12:50

Do you think they will understand that?

12:51

Or they will say, no, please give us the traditional Fortran or JavaScript or C++, which is easier

12:57

for us to understand because it's just sequential.

13:00

So the student doesn't want legacy, doesn't want tradition, that means nothing to them.

13:06

They have no value on legacy.

13:08

So they are the ones who might accept the new paradigm.

13:12

The problem is with all the old guys, that they've been doing this thing their whole

13:17

career and they don't want someone at some point saying, okay, you've got to start over

13:21

now.

13:22

You are now at the same level as that 17-year-old.

13:23

They go, whoa, no, that's not what I want.

13:28

And that's why in order to introduce a new paradigm, usually we have to wait for a generation

13:36

of programmers to retire or die before we can get critical mass on the next idea.

13:41

When JavaScript was introduced, according to my knowledge, it was meant to be a functional

13:47

programming language with the syntax which resembled Lisp.

13:52

But then they said, no, we cannot accept that in the browser because it's too complex.

13:56

So let's make something which is more traditional like Java and then we get JavaScript, right?

14:01

Not too complex, but too unfamiliar.

14:06

So in the browser, the first programming language was Java.

14:15

And Java was the most successful introduction of a new programming language in history.

14:20

It took off almost immediately.

14:23

Everybody loved it.

14:24

It was basically a rewrite of C++, but it got rid of the pointers and was a lot cleaner.

14:30

And it was strongly embraced.

14:35

And it was the first programming language in the browser and it failed hard.

14:41

It just didn't work.

14:42

It was too slow, it was too cumbersome.

14:45

It did not fit the problem at all.

14:47

It was just appalling.

14:50

Eventually they figured out that it still had a mission on the server and it did that

14:55

a while.

14:56

But I think the web would have died and been replaced by something better, except that

15:04

there was also JavaScript.

15:06

And JavaScript was powerful enough that it could do all of the things that you wanted

15:11

an executable internet to do.

15:14

And JavaScript succeeded in spite of all of its defects just because it was the only language

15:24

in the browser.

15:25

It was your only choice.

15:26

So if you wanted something interactive in the browser, you had to learn JavaScript.

15:33

That was a fluke, that was a one in a billion thing.

15:41

You can't depend on that ever happening again, I don't think.

15:45

But still the syntax was not made Lisp-like, it was made Java-like.

15:50

Yeah, well the problem with the Lisp syntax isn't that it's complicated, it's actually

15:55

extremely simple.

15:57

It's just it's weird and unfamiliar.

16:02

With a good IDE to balance all the parentheses for you, it's in the noise, it doesn't matter.

16:10

But at that time the IDEs were not powerful enough to do that well.

16:14

So they made it look like Java, which was a source of confusion because a lot of people

16:21

thought, "Well, I can just, this is Java, right, so I can just write Java in it."

16:26

And that didn't work.

16:28

So sometimes it's easier if you're going to something which is completely different other

16:34

than something that's kind of like what you're used to but is not in ways you don't quite

16:40

understand.

16:41

There was a huge difference between Java and JavaScript to my knowledge is that JavaScript

16:47

has objects and Java has objects and classes.

16:52

And it seems that they both call themselves object-oriented languages, but fundamentally

16:58

they are very different.

17:00

The presence of classes makes a difference as far as I understand.

17:05

Well, although JavaScript now has classes too and sort of always did.

17:13

If you understood what a class actually was, you could create classes in JavaScript and

17:18

a lot of people did.

17:19

And I showed people how to do that.

17:22

So in that respect they weren't that different.

17:24

The main difference between them, I think, is that JavaScript had a type system which

17:32

was not strong enough to protect you from making errors but was annoying enough to impair

17:39

your productivity.

17:42

JavaScript didn't have the type system so you're kind of on your own but you could also

17:49

be much more expressive.

17:50

It was much more dynamic.

17:53

You could do things like load little pieces of program individually and the browser just

17:58

kind of put them all together.

18:02

That's how the web works and you could argue that's a stupid way for the web to work but

18:06

that's how the web works and it works.

18:09

You could never do that stuff with Java.

18:11

It's not dynamic enough.

18:13

In one of your talks you said that the ability to extend an object in runtime which exists

18:19

in JavaScript and doesn't exist in Java is one of your favorite features of the language

18:26

which makes the language beautiful.

18:28

Do you still think that way?

18:32

At that time I was an advocate of prototypal inheritance which is something that JavaScript

18:38

has which is fairly unique.

18:41

I've decided I'm not an advocate for that anymore.

18:47

I think inheritance in general, it was a bad idea.

18:51

The thing about inheritance is basically I've got this thing and I want another thing which

18:56

is similar to it but slightly different and so I'll have this one inherit from that one

19:01

and I just list what the differences are and that's a really quick way to get started.

19:07

But when the inheritance chains start getting long, it gets really complicated.

19:13

You've got all these things kind of forking out and if you have a design error at one

19:20

level that design error propagates into everything else, it's just a mess.

19:28

In retrospect I think that's a really bad way to construct stuff.

19:33

Like that except any kind of exception-based thing I think looks really good in the small

19:40

but doesn't scale.

19:43

What I'm advocating now is having two flavors of objects.

19:48

One is data objects.

19:51

We have got objects just with lots of data in them and they're malleable and you can

19:56

update them and do whatever you need to do to them.

19:58

That's where you keep your state and then you have objects which are frozen which only

20:03

contain functions and those functions close over one of those objects.

20:10

Those functions can also take other objects as inputs and so they do the work of classes

20:19

and that they give you the encapsulation but instead of building by inheritance, you build

20:25

by composition so you can have lots of different things that you're aggluting into one of these

20:30

things and it's all hidden inside of the closure of functions.

20:35

I think that's a brilliant way to do software construction and JavaScript is sort of unique

20:42

in the way that it provides that.

20:44

Can we call these objects pure objects?

20:50

Purity arguments often go to dark places so I'm not sure I would call them pure.

20:59

In some languages, you would call it a struct or you would call it a hash table or a dictionary

21:05

or something.

21:06

It's just some collection of key value pairs and that turns out to be a really powerful

21:12

idea.

21:14

the languages have a thing like that. Now one of the weaknesses in Fortran was it didn't have one

21:20

of those things. But since C, we've had them. The problem with C's struct is that they're not

21:27

dynamic. So you're stuck with a brittle structure. But in most of the more recent languages,

21:35

the things are more dynamic. So you can update the number of properties within the object and

21:44

grow it or shrink it, do what you want, so that they're very adaptable. And the JSON format

21:52

was designed for supporting those sorts of objects and allowing us to transport them from one language

22:01

to another. But still we have functions inside objects. And some people misunderstand object-oriented

22:08

programming. They just understand objects as storages for functions. And then they make

22:14

these functions long, like very long sometimes. They just become procedures, which are no different

22:20

from Fortran procedures. Yeah, exactly. You can always write Fortran in any language.

22:25

So some people say that functions and control flow structures and if-then-else-for-while loops,

22:34

they are sort of things that destroy object-orientation.

22:39

That we should not have them at all. And that would make our languages pure object-oriented.

22:46

That doesn't make sense to me. So we need these statements and control flow.

22:54

Well, functions should be the interfaces to the objects. And how the function accomplishes its

23:04

work is nobody's business. A function should be a black box. And inside of it, you pass it an object

23:10

and it's going to do some work on the object and give it back to you. You shouldn't care how it

23:17

goes about that. So if it wants to use ifs and loops, I think that's fine.

23:22

And how can we prevent these long, long functions or procedures? How can we teach programmers not to

23:30

do that? Keep them small. Separate your scope into smaller objects.

23:34

I don't know. People have been struggling with that problem since Fortran. One of the features

23:42

in Fortran was subroutines, which allowed you to break your program into smaller programs or

23:49

smaller pieces of program and have them call each other. And that was a brilliant idea.

23:55

The initial motivation was for efficiency so that you could reduce the amount of memory that you're

24:01

using. If you're doing the same thing in two or more places, you could put it in a subroutine

24:06

and you save all that memory. And that was really important when we measured memory in K,

24:13

particularly when it was one or two digits of K. That importance has gone away now since

24:21

memories are so incredibly big, which is great. It's really nice that memories are really big.

24:26

Unfortunately, our programs get even bigger somehow

24:30

because there are no limits on how big we make things. And so we don't have to think

24:37

efficiently anymore. But the more important value of subroutines was it allowed us to break things

24:44

into pieces that were easier for us to understand. So you take a bunch of functionality and you put

24:51

it in a thing and give it a name. And that name should be enough to give you an idea of what that

24:56

thing does. And then you can call that wherever you need to. Maybe you only call it in one place.

25:01

That's fine. So you can break the program down into little boxes and you can understand the boxes

25:08

one at a time. You don't have to understand the entire program at once. And that was really

25:14

valuable. And it's still really valuable. And I think that's still one of the major benefits

25:19

of functions. We stopped calling them subroutines. We call them functions now, but it's the same idea.

25:24

So how do we teach people to use functions properly? I don't know.

25:30

We've had Fortran since the 50s. We should have figured this out by now. But it's still a struggle.

25:43

Objects also play the same role. They help us decompose larger scope into smaller pieces and

25:49

then give these pieces names. And then we know what's going on in these objects without looking

25:54

into it because we know the name. Yeah. So the best features of the languages,

26:00

I think, are the ones that help us understand what the programs are doing.

26:05

And I think all of the other features are distractions. So the objects love the objects.

26:16

The functions, I love the functions. You can get rid of just about everything else. I'm happy with

26:21

that. I can build applications out of the objects and the functions. And there are also actors,

26:28

which you talk about for quite often recently. And they are supposed to be replacing objects,

26:35

according to a few of your presentations. I don't see them replacing them, but I

26:41

see them as a more powerful paradigm. So actors were invented in the early 70s,

26:47

about the same time that small talk was being invented. In fact, the two almost have a common

26:55

origin. And the actor paradigm was inspired by small talk, or an early version of small talk.

27:07

When Alan Kay talked about small talk, he said, "You've got objects that send messages to other

27:13

objects." And people at MIT heard that and wondered, "What's this message passing thing?"

27:23

And developed a programming paradigm based entirely on message passing. And it was brilliant.

27:28

But it went nowhere. It was not adopted. Although a subset of it turned into the Scheme language,

27:37

which wasn't very popular, but was extremely influential. All the language designers know

27:45

Scheme and are very much influenced it. In fact, the best parts of JavaScript come from Scheme.

27:54

But Scheme didn't quite get the actor model right. But the thing that's brilliant about

28:00

the actor model is that all the computation is based on message passing. And we have experience

28:06

with message passing in the browser. That's how events work. An event is a message from the UI

28:14

system that gets sent to an object, and the object decides to highlight a field, or I'm going to

28:21

clear the page, or I'm going to do whatever I'm supposed to do with this.

28:24

We can take that same idea and apply it to the network so that we can send messages over the

28:30

wire. And that's really powerful because that's a way that we can have our programs communicating

28:38

with other programs. I've got an actor on my machine, there's an actor on another machine,

28:43

or I don't even need to know where the other actor is. It might be on my machine, it might be

28:48

on the other machine. I talk to it in exactly the same way. And so that's a primitive on which we

28:56

can build distributed systems. So I think the actor model should be the next paradigm.

29:02

You remember Corber.

29:04

I do, yeah.

29:07

That was the same direction, I think.

29:10

Well, they were trying to figure out a way of representing

29:17

specifications of data structures to allow programs on different systems to be able

29:22

to communicate with each other. And it turned out to be extremely complex.

29:27

It didn't fly.

29:29

Eventually it failed. It was largely replaced by XML, which was attempting to do the same thing.

29:36

It came at it from a completely different paradigm. They said, "Let's assume that the

29:43

stuff that our data structures are actually documents, and we can pass documents back and

29:49

forth." But that turned out to be crazily complex. So I do a query of a server,

29:56

and it would send back a document, and now I have to query the document to find out what I want to

30:01

find out. It was grossly inefficient and weird. So I came up with JSON, which was a subset of

30:09

JavaScript objects, which we just say, we pass an object back and forth, and that most of our

30:18

languages, while they might be incompatible in lots of important ways, they all have something

30:25

that we call a number, and they can all agree that they can represent a number as a string of digits.

30:30

And they all have a text, and we can say for the purpose of communication, the text is

30:37

a quote mark, and some characters, and an end quote. And we've got true and false, and we can

30:44

have an array of stuff, which is just a sequence separated by commas. And we can have key value

30:51

pairs inside of curly braces. All the languages can understand. Yeah, we can make sense out of that.

31:00

And so JSON, very, very lightweight, just says, "Okay, you can make one of those,

31:06

send it to another machine, and they can make sense out of it." And that's been incredibly

31:12

successful. When I first introduced JSON, there were a lot of people who said that cannot possibly

31:20

work. It cannot possibly work. XML is really complicated for a reason. That complexity is

31:29

there, and someday you're going to understand why that complexity is there. It turned out we never

31:35

understood why it was there. It was just complicated. It's because they were trying to solve the problem

31:40

the wrong way. JSON was just as simple as you could make the thing, and it worked. Every language now

31:51

can understand.

31:52

how to read and write JSON, which means that you can communicate with any program, no matter

31:59

what language it's written in.

32:01

And that's pretty neat.

32:03

And the particular flavor of that language comes out of JavaScript, you know, JavaScript

32:10

kind of...JavaScript has become crazily complicated, but there is a beautiful, clean core to JavaScript,

32:24

which is universal, and everybody understands that universal bit now.

32:29

I think the intent of XML was to have a document which, when you open it, you don't need to

32:38

ask a question, what is it and where it's coming from, you know everything about it

32:42

because it has proper meta information, like the link to the schema, link to the region

32:47

of that.

32:48

So it's like a universal document format, which apparently was not that needed in many

32:54

systems.

32:55

Because JSON is specific, if you get the piece of JSON document, and if I don't know where

33:01

it's coming from, I have no idea what to do with it.

33:04

So JSON is okay if the sender and receiver, they both understand what's going on.

33:09

But XML is something that if I open the XML document coming to me from I don't know where,

33:14

I still can understand what's going on because there's a lot of meta information there.

33:18

Well, the main information you get there is in the tags.

33:25

But you also have to go through a big transformation, you know, you can't really represent arrays

33:31

in XML.

33:33

You can have lists of things nested together, but it doesn't say that it's an array necessarily.

33:41

So you have to do a transformation, and you have to deal with the difference between elements

33:46

and attributes.

33:47

You know, if this time it's an attribute, this time it's an element, do they mean the

33:53

same thing or not?

33:54

So there's a lot of unnecessary complexity at that level.

33:58

JSON was designed specifically to allow languages to talk to each other.

34:04

And XML was not designed for that.

34:06

It was designed for formatting documents.

34:10

And they said, well, as long as we went to all this trouble, maybe we can also use it

34:14

for this other thing.

34:15

But it turned out JSON works better.

34:18

If we imagine these actors who talk to each other on different computers, then it seems

34:23

that all the actors, they need to be subscribed to some sort of event bus and listen to messages

34:28

and send messages, receive messages.

34:31

That's what's supposed to be there?

34:34

Not necessarily a bus.

34:36

So every actor has an address.

34:40

And you can only send a message to an actor if you know its address.

34:45

If you don't know its address, you cannot send a message to it.

34:49

That is where the security of this comes from, that we can restrict the way in which addresses

34:56

become known.

34:58

And so if you're an outsider, there's no way you can acquire an address.

35:02

So there's no way you can get into the system.

35:05

And so I can send messages directly to an actor.

35:09

And it might be on another machine, it might be many hops away.

35:12

I don't know or care.

35:15

It just gets there.

35:17

So messages will get delivered to the actors on arrival.

35:24

If the actor is busy, they'll get held in a queue and will eventually be delivered in

35:29

arrival order.

35:31

And the actor can then decide what to do.

35:35

So it's not a strict call return protocol.

35:42

Most of our protocols now seem to be call return, like HTTP.

35:48

So that makes it hard for some kinds of applications where you want the server to tell you that

35:52

something happened.

35:53

But if you don't ask the server to tell you if it happened, there's no way for it to tell

35:57

you because the client has to initiate all the messages.

36:02

And also the client has to wait for a reply, even if he doesn't care about the reply.

36:08

So in an actor system, an actor just sends a message and he can send several messages

36:14

to several different objects and all the messages go out.

36:20

We can do call return semantics if you want to.

36:22

So a message comes in and I can send a reply to that message.

36:26

But generally it's just one message.

36:29

So that allows us to do things like flow-based programming where I've got a network or a

36:37

graph of actors and each one will receive a message, do some work on it, and then forward

36:43

it to the next object or next actor and they'll keep going.

36:47

So I don't need to get returned on the first one, I just send it to the first guy, he takes

36:54

care of it and so on, it all gets done.

36:57

So we cut the number of messages flying around in the network by half because we don't need

37:03

the reply messages generally.

37:06

And there is no guarantee that the reply may come?

37:09

There's never a guarantee.

37:12

There's some people who talk about guaranteed message delivery.

37:16

That's a myth.

37:17

That's impossible.

37:22

Something could happen on the machine.

37:24

There might have been a bug in the actor, the system might have crashed, there might

37:31

have been a bomb in the data center that blew everything up, or a power failure.

37:37

You don't know why the message didn't come back.

37:41

But there are reasons for why a message can't come back, it cannot be guaranteed.

37:46

So another part of the paradigm is that we have to be ready to deal with failure.

37:54

If we're programming in a world where everything is guaranteed, eventually when the failures

38:02

come they're going to be catastrophic.

38:04

So instead you need to have failure built into the paradigm.

38:10

Failure is always an option.

38:12

I think Erlang did a brilliant job in showing us how this can work.

38:18

And I think we take that idea that when things go wrong we can selectively restart the stuff

38:25

and get back to a clean state and recover.

38:30

That's the best we can hope to do.

38:33

The callbacks which we have in so many places in Node.js, it resembles the actor model to

38:39

me.

38:40

It's a start, yeah.

38:43

You also have no guarantee, right?

38:46

You just call the function, provide a callback, but you don't know whether the callback will

38:50

be ever called.

38:52

That's right.

38:54

It's a subset of the paradigm.

38:56

So browsers and Node, because it's based on the browser model, are the first step toward

39:03

it.

39:04

So I think if we ever do get to full-blown actor systems, web developers will be the

39:08

first to embrace it, because they're already doing some of it.

39:13

There's some new stuff they'll also have to learn, but they will be in a much better position

39:21

than everybody else.

39:22

I've heard so many complaints from programmers about that.

39:25

They say all of these callbacks, they just increase complexity of the design.

39:29

Because every time you call a function you need to think about providing the callback.

39:33

Instead of doing the traditional call, call, call, just the sequential, the Fortran style.

39:39

Yeah.

39:43

That perspective led to the invention of, what were they called, remote procedure calls

39:50

or remote method invocations, where the idea is we want to be able to call a subroutine

39:58

on another machine, but we want to hide the fact that we're doing that.

40:03

We want to make it look like an ordinary subroutine call.

40:06

And I'm saying subroutine just, I don't know, because I like the word subroutine.

40:17

The problem with that is that you've got big performance problems, because the calling

40:24

program is blocked until you cross the network and stuff happens and the reply comes back.

40:31

You don't know how much time that's going to be.

40:33

And so you're building huge delays into your program, which you cannot see by reading the

40:38

source code.

40:40

And that's really problematic if you want to have any kind of performance.

40:45

That program cannot be doing anything useful while it's waiting for that remote procedure

40:50

call to resolve.

40:53

The bigger problem is that call can fail.

40:57

The message may never come back and so it's going to hang forever.

41:01

And in that state there's no way that it can recover from that.

41:04

And so that's a huge error.

41:08

So I think that's just a bad paradigm.

41:11

So instead of trying to hide the realities of the universe, we should instead learn to

41:17

embrace the realities of the universe and learn how to deal with these temporal events

41:24

as they are.

41:25

When people started doing event handling in JavaScript, there were a lot of people who

41:32

were really resistant to it.

41:35

When they wanted to, say, read a text field, they wanted to just stop and do a read statement

41:45

and have it stop until someone typed something in.

41:48

But if you have a dynamic UI, that cannot possibly work.

41:52

You don't want to stop because they might instead want to click on a button instead or type

41:59

in a different field.

42:00

We want people to have the freedom to do whatever they want.

42:03

You don't want to be locked into a particular sequence of blocking events.

42:09

And so there are complaints that this is an unnatural way, using an event loop and events

42:18

to do UI is unnatural.

42:21

It's an inversion of control.

42:22

It's not the way God wants us to write programs.

42:25

It's just wrong.

42:26

But it turns out it's exactly right.

42:29

having these independent events so that, you know, an event handler is basically a callback,

42:37

right? So, you know, if you think about it right, it is not all that complicated. You

42:43

just say, "I want to hear from this and this is what we'll deal with that when it happens."

42:49

You just, we're going to take that and apply it to everything.

42:53

Yeah. It works perfectly for the UI programming, but if it's just a simple script, which for

42:58

example, supposed to read the content of a file and then save it to another file and

43:03

then read another file and then save it to another file. Just four simple steps, which

43:08

supposed to go one after another. Then in the callback fashion, we need to go into four

43:14

levels of nesting because we provide one callback and inside these callback, we call another

43:19

operation and then provide another callback. So you can imagine how it's going to look

43:23

on the, on the screen. It's going to be deeper and deeper nesting and people complain about

43:27

it. And they, and what they do and they use promises, which you know about, which you

43:32

also, I mean, you know how promises work in JavaScript.

43:36

Yeah. Promises were invented at a company that I started. So I know all about promises.

43:42

So the problem with the nested callback thing is it's the wrong way to, to do this stuff.

43:48

So if you do things the wrong way, then it's easy to get frustrated. So I completely understand

43:53

that. So the right way is you take each of those steps in whatever the process is going

43:59

to be, and you put each of those steps in a separate function. So each of those becomes

44:04

a black box. Okay. Which is the right way to do stuff anyway, right? That's what we

44:09

invented subroutines for. That allows us to, you know, clearly say, you know, this is depth

44:15

one, you know, that the name of the function might be step one and it's going to do this.

44:21

And each of those steps will return a function that takes a callback, which I could explain

44:33

that better another time. But basically we've got these four boxes which represent those

44:39

steps that you want to do. I have a, a JavaScript package called pronto, which contains a function

44:49

called sequence. So you say pronto sequence and the four black boxes, just put them in

44:59

an array and pass it to that. And it will manage taking the calling one and taking its

45:05

result and passing it to the next one and so on, sort of like a pipe. There's also one

45:10

called parallel, which does the same thing, except it calls them all at once and returns

45:15

an array of the four results and you can put these together in lots of interesting ways.

45:24

So we separate the units of work from the flow, from the control flow. The reason the

45:32

nested event handler thing doesn't work is we're mixing all that stuff up. And so the

45:38

flow and the work get all messed up. It's worse than using go-tos, which were the way

45:46

we used to do it wrong. So taking a more functional approach, it's possible to end up with programs

45:56

that work better, that are much more flexible and are easy to read and maintain. You don't

46:03

need promises, you don't need async/await. My biggest problem with async/await is that

46:09

people are trying to make their programs look like they are linear when they are not. And

46:15

so they don't understand how their programs work. They put async/await into the program

46:24

and hope that that makes it work, but they don't really understand what it's doing. And

46:29

any time you don't understand what your program is doing, that's when bugs happen. Things

46:36

can go wrong. It might just be performance problems where it takes a really long time

46:40

and you can't figure out why. Or it might be that you got the flow wrong in ways that

46:45

you don't understand because you don't know what steps the program is actually running

46:49

in.

46:50

By listening to you now, I think maybe the async and this await keywords was a mistake

46:56

in the language.

46:57

I think it was. Concurrent programming turns out to be a really important way of dealing

47:05

with lots of stuff going on. And people have been trying to do asynchronous programming

47:12

or concurrent programming well for a long time. And there have been a number of bad

47:19

approaches to doing it, like threads and synchronization, which is the way Java tries to deal with this.

47:26

I think it was a terrible mistake because that leads to deadlocks and races. And the

47:33

hardest bug I ever had to find was a race to two things happening at the same time.

47:42

Because you can't look at the code and see what happened. It's about the interaction

47:46

of things that you don't see. So, you know, debuggers don't help you, tests don't help

47:52

you. That's really hard. So, that's a terrible way of doing things.

48:00

I think if the flows are fairly simple, then the callback is effective. But if the flows

48:07

are more complicated, like you described, then you need something like the pronto package

48:13

that I'm describing. I think that provides the best way of putting this stuff together.

48:20

It's readable and maintainable.

48:22

And your MISTI project, the language which you designed, it doesn't have all these problems

48:28

of JavaScript. It's more pure actor model?

48:34

So it depends on your perspective. So MISTI is my actor language. So it's my interpretation

48:42

of how to solve the distributed programming problem. And I started with JavaScript because

48:51

I think there's a lot of value in JavaScript. But I started by fixing every design mistake

48:58

in JavaScript, at least according to my understanding. And I believe my understanding is the correct

49:05

one. So the syntax is quite a bit different. It doesn't have semicolons in it, for example,

49:13

because JavaScript is a language that has semicolons but doesn't completely require

49:22

semicolons and that ambiguity is a source of bugs. So that was bad. So the correct way

49:28

is to either require semicolons everywhere or not require them anywhere. And so that's

49:34

the approach I took. So my language looks more like Python than it looks like JavaScript.

49:41

But try to simplify all of that as much as possible. And then use that language to create

49:50

actors. So you've got MISTI programs and MISTI programs compile into executables which run

49:58

in actors. And my goal is that I can take a distributed system, put it all in one machine

50:09

for development, and then for deployment we can put it off in all the other machines with

50:15

no code changes. And I think I can do that. So it's horizontal scalability by design.

50:25

And it supports the flow-based model. There are lots of ways that you can use it. But

50:34

the key thing is that you can have communication between things which may be remote. And so

50:42

you get a lot of natural parallelism if you design your programs correctly. Now, you're

50:47

not guaranteed to get that improvement. For example, if you're still stuck in a A, B,

50:53

C mentality, then I'll do A and then I'll send something to another machine and it'll

50:59

do B and it sends it to another machine, C. If that's all you're doing, you're making

51:04

things slower, not faster, because you're paying for the network time. So you want to

51:10

figure out a way to allow for multiple things to be happening simultaneously. And so this

51:17

language doesn't require you to do things that way. But if you do, then you can get

51:22

huge improvements in performance. This reminds me a little bit about data flow evaluation

51:27

concept. Very much so. Yeah. In hardware. Yeah. So this is data flow in software. But

51:34

yeah, it's the same idea. You know, thinking about how... So in this case, the data is

51:42

flowing through messages, but it hopefully will tend to flow to where it is needed, where

51:50

it can be acted upon, and then further flowed to where it's next needed. But usually data

51:56

flow is in the hardware. That's how they design CP. Yeah, that was an early imputation of

52:02

it. But if you think of it just in terms of how data flows, instead of hardware flowing

52:08

within one box, we now have software flowing across many boxes. That's the same basic concept.

52:17

In this MISTI project, the language is already in production mode, or it's still experimental?

52:22

It's still experimental. So the reason I call it MISTI is because it is vaporware. It's

52:28

a long way from being releasable. I can't guarantee that it'll ever be released. But

52:36

I'm working on it. And I think I'm doing it correctly. And hopefully someday you'll

52:42

get to see it. So for the programmer, it will not be obvious that two actors are located

52:50

at different machines? Right. So the place where MISTI differs from

52:58

languages like Go that are also trying to solve a concurrency problem, actors do not

53:05

share memory with each other.

53:07

So that there's no shared memory.

53:09

So each actor could be in its own machine by itself, you know, virtually it would be

53:14

like that.

53:15

So even if two actors are on the same machine, they can only communicate by sending messages

53:20

between each other.

53:22

Having that isolation means that we can easily then move to the network.

53:28

Because in a network, you can't share memory, right?

53:31

Well, there have been people who actually have tried to do that, where they try to simulate

53:38

shared memory over the network.

53:40

I think that's a really wrong-headed approach.

53:43

So instead, actors go the other way and say there's no sharing of memory at all, ever.

53:50

So even if two actors happen to be on the same machine, they are never allowed to share

53:55

memory.

53:56

That machine reminds me of enterprise Java beans, which had a similar idea.

54:02

You just talk to an object, but you don't know where the object actually is.

54:05

Maybe it's somewhere else on another machine.

54:08

But again, it didn't fly.

54:11

Yeah, it had other problems.

54:14

It was never about concurrency at that time, it was just about talking to objects.

54:17

So it's not about data flow, it's just, okay, here's my object, I don't want to see where

54:21

it is, I just talk to it, I just call a method and it goes over the network.

54:25

And then execute it somewhere else.

54:27

An amplification of the idea behind networking, right?

54:30

You've got an address of a machine, you can send a message to that machine.

54:36

We can treat objects the same way, we can treat actors the same way.

54:40

But then JSON and web services, they just replaced all this and no enterprise Java beans

54:46

anymore.

54:49

So JSON also has a role in this networking too.

54:54

So sometimes when people are designing distributed applications, they'll be thinking about it

55:02

in terms of APIs.

55:06

And so they'll come up with protocols that are extremely chatty.

55:10

For example, say you want to do like a remote canvas.

55:16

So I want to have my machine right on a canvas on another machine.

55:22

So one way you could do that is I send the command over, open a canvas and it sends me

55:30

back a canvas token and I say, okay, using this token, set the pen to black, move the

55:37

pen to zero, draw to that, so on, you know, I send all these commands one after another.

55:45

And I wait for a round trip on each one of those.

55:48

That's going to be extremely slow because you've got all this network overhead going on, right?

55:55

The correct way to do that is I create a JSON message.

55:58

The JSON message says, okay, make a canvas and set the pen and do all this stuff.

56:04

So I send one message, it goes, okay, boss, and then it does all the stuff much faster.

56:12

So if you think about the remote application just as another flavor of a local application,

56:20

you'll get the performance things wrong.

56:23

But if you have tools available to you like JSON, you can almost eliminate the cost of

56:32

all the network I/O because you can put a lot of information into a single message.

56:38

In one of your talks, you said that one of the drawbacks of JSON is the lack of support

56:44

for blobs for binary data inside.

56:47

Yeah, that's a problem.

56:50

I didn't do blobs because JavaScript didn't have blobs and my design criteria was it had

56:56

to be a subset of JavaScript.

56:59

So for the networking layer of MISTI, I have a different language, which is called Nota,

57:11

which is a slightly more binary-flavored form of JSON, which knows about blobs and knows

57:19

about some other secret things that I need in order to implement the MISTI protocol.

57:28

So it's not strictly textual.

57:31

So it's going to be faster to encode and decode, probably going to be quite a bit smaller.

57:38

Like protobuf, which is popular.

57:40

A similar kind of idea.

57:43

This one I designed specifically for MISTI.

57:46

I'm not advocating it as a replacement for JSON because I think JSON is fine for most

57:53

of what it does.

57:54

In fact, the MISTI system will also use JSON at the higher levels.

57:58

So when the actors talk to each other, they'll be talking in JSON, but when the network is

58:06

talking between the machines, they'll be talking in Nota.

58:12

One last point, which is the most interesting for me.

58:15

In one of your talks, you said that the future hardware has to provide support for objects

58:21

and for actors.

58:25

And that's not happening so far.

58:26

We don't have that.

58:27

We don't have hardware for GPU, for network PU.

58:33

We have something for large language models, but nothing for actors, objects, or something

58:38

like that.

58:39

So is it coming?

58:41

So I have a friend who is designing an actor CPU.

58:47

So every instruction is a message send, except extremely low level.

58:57

It's a really interesting architecture.

58:59

I don't know if that's the future or not.

59:03

I'd like to see it be.

59:06

But everything I want to do in MISTI, I can do with today's hardware.

59:11

So that's not a requirement for my project.

59:14

If someday we do get that new actor hardware, I think that's going to be really interesting.

59:19

But it's not, in my view, a requirement for going forward.

59:25

Because you said the von Neumann architecture, it was invented 70 or 80 years ago.

59:31

And all the languages which we use now, they are all based on this hardware, which is sequential,

59:38

which is instruction by instruction going forward.

59:41

And it doesn't know anything about objects.

59:43

It doesn't know anything about even function calls.

59:46

It's still based on subroutines and procedure calls.

59:50

Yeah.

59:51

I think that's why I still talk about subroutines, because basically, that's what the hardware

59:54

is doing.

59:58

But that works.

60:00

I can build an actor language on top of that.

60:04

And a lot of the system security will come from the language itself.

60:10

So the language will not allow the actors to get into each other's memory.

60:15

And that by itself improves the security situation by a lot.

60:25

It enables the remote stuff, but it also makes each individual actor a security block by

60:34

itself.

60:35

No direct memory access into the actor?

60:39

No.

60:41

The only way you can communicate with an actor is to send it a message.

60:45

And if it chooses to respond to you, then you get what it decides you get.

60:51

And you can't compel an actor to give up its secrets.

60:57

Because in any language, modern language, mainstream language, even though they declare

61:03

encapsulation and object-oriented flavor, it's still possible to get directly into the object

61:09

and see what's going on there.

61:11

Yeah.

61:12

And often, that's by design.

61:14

You got things like package scope, which allow you to see into something that you shouldn't

61:19

be able to see into.

61:21

And often, those sorts of features are thought of as features, as useful tools.

61:30

And they are useful, but there are certain uses you don't want to encourage.

61:36

And so you have to be more careful in how you design stuff so that the bad uses aren't

61:43

benefiting from the things you put in for, hopefully, good uses.

61:48

Let's try to give our listeners some call to action.

61:50

Do you need help in the MISTI project?

61:53

Do you need contributors?

62:00

Not yet.

62:01

Eventually, I will.

62:02

I'm not quite there yet.

62:05

I have a plan.

62:07

I've got the parser working.

62:09

I'm partway through the code generator.

62:11

I think I've got the architecture all nailed down.

62:15

So I'm kind of going through the development chain now.

62:19

Once I get to the part where it can generate Intel code, which is executable, at that point,

62:26

I think I'll start asking for help because we'd like to see tools around it.

62:34

We'd like to see optimizations on my instruction path because I'm doing quick and dirty stuff,

62:42

and eventually, we want to have production quality stuff.

62:44

And so all of that needs to be cleaned up.

62:47

And I could get to it eventually, but if we could get a community interested in it, that

62:51

could go faster.

62:54

MISTI will have a policy machine built into it, which makes decisions that build time

63:01

about what sub-programs, programs are allowed to link with and what secret powers they're

63:09

allowed to have.

63:10

That machine is also written in MISTI and can also travel across the network, so that

63:18

makes it possible to have remote administration of software libraries on different machines.

63:26

All sorts of interesting ways to go and it kind of explodes in the possibility space.

63:33

Definitely a community would be great at working that stuff out.

63:36

I'm not there yet.

63:37

OK.

63:38

Thank you very much.

63:39

Thank you.

63:40

This has been fun.

63:41

Yeah.

63:42

Very good questions.

63:43

Thank you.

Interactive Summary

The discussion begins by criticizing modern JavaScript, particularly the addition of classes and type annotations, contrasting it with its "good parts" from a decade ago. The speaker attributes this "dirtiness" to developers from other languages pushing for familiar features, leading to languages borrowing from each other. The conversation then delves into the challenges of designing and maintaining "clean" languages, citing Smalltalk 80's market failure and C++'s "awful" success as examples. The core argument is that current programming paradigms, rooted in the von Neumann architecture, are ill-suited for today's distributed, multi-machine computation and the inherent security problems. The speaker advocates for the Actor model as the next paradigm, emphasizing message passing, distributed systems, and no shared memory for enhanced security and scalability. He critiques traditional approaches like RPC and modern constructs like async/await for obscuring the realities of distributed and asynchronous operations, preferring explicit handling of concurrency. Finally, the speaker introduces his experimental Actor language, MISTI, which aims to fix JavaScript's design mistakes and provide horizontal scalability by design, operating on the principle of actors communicating solely via messages without shared memory.

Suggested questions

8 ready-made prompts

Recently Distilled

Videos recently processed by our community