Marijn Haverbeke - The Rust That Could Have Been
-
0:04 - 0:09[ applause ]
-
0:10 - 0:12Yeah, I'm glad so many peoplestill showed up
-
0:12 - 0:15at the very end of the conference.
-
0:15 - 0:20So yeah, I'm going to be talking aboutmostly a number of features
-
0:20 - 0:23that were part of the Rust languageat some points,
-
0:23 - 0:24but no longer are.
-
0:25 - 0:29And, why this is the caseand usually why this is a good thing.
-
0:30 - 0:33So, as Ryan said, I'm Marijn Haverbeke.
-
0:33 - 0:37If you are into Javascript,you might have seen my name before.
-
0:42 - 0:44Rust has been under developmentfor a while:
-
0:44 - 0:46about ten years now, I think.
-
0:46 - 0:51First - long stretch - was justGraydon working in isolation and...
-
0:51 - 0:55Who knows what kind of ideas andexperiments he abandoned at that point.
-
0:55 - 0:59There's not even a like code repositoryfrom that time public.
-
0:59 - 1:02so it's like the prehistory.
-
1:02 - 1:04And then, at some point,
-
1:04 - 1:08Mozilla adopted the projectand assembled a team.
-
1:09 - 1:12From a little before that point,we do have Git history,
-
1:12 - 1:15and at that point,everything was discussed in issues
-
1:15 - 1:17and mailing lists, and there's...
-
1:18 - 1:19lots of records.
-
1:19 - 1:23I was part of this pretty much -the initial team - where we...
-
1:24 - 1:29Moved from the original OCaml-basedcompiler to a Rust-based compiler,
-
1:29 - 1:32and we got a bunch more peopleinvolved in the language.
-
1:32 - 1:34This was a period of...
-
1:34 - 1:37like, the first real experiencewith the language
-
1:37 - 1:39and a bunch of peoplefrom different backgrounds...
-
1:41 - 1:42giving their opinions on the language
-
1:42 - 1:45and trying to push itinto their favorite direction.
-
1:45 - 1:48And, we had a lot of likeexperiments and dead ends
-
1:48 - 1:51and overhauls and false starts and...
-
1:53 - 1:55just lots and lots of churn.
-
1:55 - 1:59We would sometimes come up witha breaking change in the morning,
-
1:59 - 2:01and then have a patch readyin the afternoon
-
2:01 - 2:03and then convince someoneto merge it later on and then...
-
2:04 - 2:08Because there was only one codebase,we'd just fix everything right away
-
2:08 - 2:09and people could continue working.
-
2:09 - 2:11There was some...
-
2:12 - 2:15some trickiness with actuallygetting like a compiler...
-
2:16 - 2:19that compiles the current codeafter you'd make a breaking change,
-
2:19 - 2:22so you'd first change the compiler,then upload a snapshot,
-
2:22 - 2:23then change the code,and then you could -
-
2:23 - 2:26everyone could - proceed withthe new snapshot.
-
2:26 - 2:29And then, of course,a year and a half ago - I think -
-
2:31 - 2:33the team [cut] version 1.0,
-
2:33 - 2:37and then the process changed entirely,so now it's like...
-
2:38 - 2:39everything stays backwards compatible.
-
2:39 - 2:44It's impressive how seriously they havebeen taking backward compatibility.
-
2:46 - 2:50Experiments moves like -[RFCs??] move very slowly
-
2:50 - 2:52and there has to be a wide consensus
-
2:52 - 2:55and it has to fitwithin the current codebase.
-
2:55 - 2:58So, that's a whole different stage again.
-
3:00 - 3:03I'm going to be mostly talking aboutthe period where I was part of the team.
-
3:03 - 3:06which was 2011-2012,
-
3:06 - 3:08and which was probablythe wildest period
-
3:08 - 3:13in terms of features cut,features changed - stuff like that.
-
3:15 - 3:17So, it may seem a bit ridiculous
-
3:17 - 3:20that we put so much time intoreally complicated features
-
3:20 - 3:22just to end up dropping them again.
-
3:23 - 3:28But, I think it's kind of an essentialpart of getting a complex design
-
3:28 - 3:30like a programming language right that,
-
3:31 - 3:34unless you're a super-genius,you won't really see in advance
-
3:34 - 3:36what the implicationsand the interactions between
-
3:36 - 3:40the various parts of the system areand you have to try it and see
-
3:41 - 3:44how well you can make it workand how well it fits into the system,
-
3:44 - 3:46and sometimesyou later have to just...
-
3:47 - 3:48abandon it again.
-
3:49 - 3:53I think that's part ofa healthy design process for like...
-
3:54 - 3:57mere mortals who need toactually see how something works
-
3:57 - 3:59before they can evaluate it.
-
4:00 - 4:04I'm structuring this talk about...around a number of visions
-
4:04 - 4:07that were part of the languageand then dropped again.
-
4:07 - 4:12And, I'll try to explain why I think that,in every case,
-
4:12 - 4:15it was a real good decision to drop them.
-
4:15 - 4:18But, it's still interesting to see
-
4:19 - 4:22what the original visions wereand what we did end up with.
-
4:23 - 4:28So, these are typestate,a structural type system and
-
4:29 - 4:33lightweight processes,and finally, garbage collection.
-
4:34 - 4:36Let's start with typestate.
-
4:38 - 4:41Typestate is... it was actually
-
4:41 - 4:45an important point in initialannouncements of the language.
-
4:45 - 4:47and people were very excited about it.
-
4:48 - 4:51What typestate does is basicallyallow you to...
-
4:51 - 4:56allow the compiler to knowmore about value than just its type.
-
4:56 - 4:57So, an example would be...
-
4:58 - 4:59This is something of type [sockets],
-
4:59 - 5:04but we also happen to know that it's openor this is something of type array,
-
5:04 - 5:07but we happen to know...or say vector in the current terminology,
-
5:07 - 5:10but we happen to know thatit's not empty.
-
5:10 - 5:13Something like that allowing you to add
-
5:14 - 5:17more safety to your program -more static guarantees.
-
5:19 - 5:23So, when you're programming,you usually have some mental model
-
5:23 - 5:27of why the thing you are doingright now is...
-
5:27 - 5:30is valid - is not going to crash -
-
5:30 - 5:32like if you're not just makingrandom changes
-
5:32 - 5:35and seeing if the [tests pass],you will have
-
5:36 - 5:39some mental model of your... program.
-
5:40 - 5:42And, to a certain degree,depending on the language,
-
5:42 - 5:45you can tell the compilerabout this model
-
5:45 - 5:46and the compiler can then check
-
5:46 - 5:49whether you are applyingyour model consistently.
-
5:49 - 5:53So, the simple case is just types -that you're actually passing the type
-
5:53 - 5:55that you think you are passing somewhere.
-
5:55 - 5:59And, if you don't,then, instead of finding out at runtime,
-
5:59 - 6:02you find out at compile time -and this is nice.
-
6:02 - 6:03There's a kind of...
-
6:04 - 6:08this computer does not have the fontsthat my computer had but...
-
6:08 - 6:10Imagine arrowheads on both sides.
-
6:10 - 6:14There's a kind of spectrumon which languages fall
-
6:14 - 6:16in terms of how much
-
6:17 - 6:19you can actually communicateto the compiler,
-
6:19 - 6:21so down on one side,there's Javascript
-
6:21 - 6:24and it's like... syntactically correct.
-
6:24 - 6:26Okay, let's go ahead - let's run it.
-
6:26 - 6:29And then, there's like,on the... way on other side,
-
6:29 - 6:32there's language like Coq,which require you to actually construct
-
6:32 - 6:37a formal proof that your program doeswhat it's supposed to do -
-
6:37 - 6:40that it does so in bounded time,in bounded space,
-
6:42 - 6:46which means you're makinga lot less mistakes.
-
6:46 - 6:48But, on the other hand,it's like a major...
-
6:49 - 6:53a major project to write a small programin such a language.
-
6:54 - 6:58And, there is a reason thatnot everyone is writing their web servers
-
6:58 - 6:59in Coq or whatever.
-
6:59 - 7:01And, Rust kind of falls in the middle.
-
7:01 - 7:04It does have quite a bitof static guarantees
-
7:04 - 7:06and it helps quite a lot.
-
7:06 - 7:11But, it still aims to be ergonomic,like easy to [program in],
-
7:12 - 7:14where you don't have to
-
7:15 - 7:18spend too much timeworking on these things.
-
7:20 - 7:25And I... one way to see the historyof programming languages is kind of...
-
7:26 - 7:29one aspect of it at least is
-
7:29 - 7:33that we've been finding betterand better vocabulary to...
-
7:33 - 7:38to describe these things we know aboutour program to the compiler
-
7:40 - 7:41in a way that's actually convenient.
-
7:41 - 7:43So, if you have a really terribletype system,
-
7:43 - 7:46that's often worse thanno type system at all.
-
7:46 - 7:49If I have to choose to write somethingin Java or Javascript,
-
7:49 - 7:52I'll just take Javascript,thank you very much.
-
7:52 - 7:54But, we're getting better at this,
-
7:54 - 7:56and Rust is makinga big contribution here,
-
7:56 - 7:59and like bringing a real,modern type system
-
7:59 - 8:00to the systems programming space.
-
8:00 - 8:03And the ownership model is - I think -
-
8:03 - 8:05just really, really good.
-
8:05 - 8:08I unfortunately wasn't on the teamanymore when this was introduced,
-
8:08 - 8:10so I can't take any credit for it, but..
-
8:10 - 8:12I think that this isthe most exciting part of Rust
-
8:12 - 8:14and it's exactly this kind of thingwhere you...
-
8:14 - 8:18where the compiler knowswhat you're trying to do and
-
8:18 - 8:21tells you when you'reviolating your model.
-
8:23 - 8:25So, back to typestate.
-
8:26 - 8:28It looked somewhat like this.
-
8:30 - 8:32You could define [predicates],
-
8:32 - 8:35which is this "pure function not empty"at the top
-
8:39 - 8:42The extra informationthat the compiler had about your values
-
8:42 - 8:45came in the form of this predicate [ ... ]
-
8:45 - 8:49But, these were actually just predicateswritten in normal Rust code
-
8:49 - 8:50that were supposed to be pure.
-
8:50 - 8:54There was a concept of [an fx] systemat that point - which also gone now.
-
8:54 - 8:59But, they just took a valueand said: "Okay, I hold or I don't hold."
-
9:00 - 9:05And, then you could definefor your functions,
-
9:05 - 9:07preconditions and postconditions.
-
9:07 - 9:09So, you could say,for example,
-
9:09 - 9:13this function "last" heredemands that its first argument
-
9:13 - 9:17has the "not empty" predicateholding on it,
-
9:17 - 9:21because you can't take the last elementfrom an empty array...
-
9:24 - 9:27Then, before you could passsuch a value to such a function
-
9:27 - 9:32you'd have to convince the compilerthat this predicate held at this point.
-
9:32 - 9:34For some things,this works relatively well:
-
9:34 - 9:37the compiler was very cleverin propagating its information
-
9:37 - 9:39through the control flow graphand like taking it
-
9:39 - 9:42from the post conditionsof the functions you called.
-
9:44 - 9:45But here, you have,for example,
-
9:45 - 9:49I create an arrayand then I want to pass it to last.
-
9:49 - 9:52But, it's not okay: I first have to...
-
9:53 - 9:55check that it's not empty.
-
9:55 - 9:59And, this is actually...a [sink] checkwould insert a runtime test,
-
9:59 - 10:03call to the predicate,and then panic if it failed.
-
10:06 - 10:08But actually, I mean,this array isn't empty:
-
10:08 - 10:10this is very easy to prove.
-
10:10 - 10:13But, because the compileronly saw these predicates as
-
10:13 - 10:15like opaque pieces of code,
-
10:15 - 10:17it couldn't actually reason about them -
-
10:17 - 10:19it could only take what you told it.
-
10:19 - 10:22Like, if you checkedthere [was variance of check],
-
10:22 - 10:26one of them which just waslike an unsafe form of
-
10:26 - 10:28"just believe me: this holds."
-
10:28 - 10:30So, that might also have beenappropriate here
-
10:30 - 10:32because I'm really sure thatthis array is not empty.
-
10:34 - 10:37And then, there was a one version that
-
10:38 - 10:42ensured that the compiler alreadystatically knew at this point
-
10:42 - 10:45that something else... that it waskind of an assertion of "okay...
-
10:46 - 10:50"I must notice at this point,but don't insert a runtime check.
-
10:51 - 10:54"I want to have a [static] errorif it's not provable."
-
10:56 - 11:00But, in my experience,the effect of this system
-
11:00 - 11:04was mostly that you would belittering your code with check statements
-
11:04 - 11:06and they would also panic at runtime.
-
11:06 - 11:10So, this amount of static guaranteeswasn't very great
-
11:10 - 11:14because often... usually the compilercouldn't really help a lot with
-
11:14 - 11:17like reasoning about when they actuallyheld them and when they didn't.
-
11:18 - 11:21It was in the compiler for a long time still
-
11:21 - 11:24but eventually it was dropped becauseit was just not pulling its weight.
-
11:24 - 11:28So, in terms of experimentsin good expressive ways
-
11:28 - 11:31to express these kind of things,I think this was a failed experiment.
-
11:31 - 11:34It existed in someresearch languages before
-
11:34 - 11:38but it's never really made it intoa big mainstream type language -
-
11:38 - 11:40for good reason, I think.
-
11:42 - 11:43So, so much for that.
-
11:44 - 11:47Next topic is "structural typing."
-
11:47 - 11:52So, in typing systems,you have two concepts
-
11:53 - 11:55where structural typing is...
-
11:55 - 11:59say you have a function type,which has a few arguments types,
-
11:59 - 12:00and a return type,and you want to compare it
-
12:00 - 12:02to another function type.
-
12:02 - 12:06So, you're just going to look atthe fields in the function:
-
12:06 - 12:08does it have the same amountof arguments,
-
12:08 - 12:13are its arguments of compatible types,is it return type of compatible type?
-
12:13 - 12:15And, that's structural.
-
12:15 - 12:17On the other hand,there is a nominal typing,
-
12:17 - 12:20where you just say:"Where is this type declared?
-
12:20 - 12:22"What's the name of this type?" -and it has to be the same.
-
12:22 - 12:25So, [Rust's structs] currently workthis way.
-
12:25 - 12:28As to enums,two types are only compatible
-
12:28 - 12:31if they are actual instances ofthe thing that was declared
-
12:31 - 12:34in the same point in the code.
-
12:36 - 12:39Initially, [structs were] structural types.
-
12:39 - 12:43So, this curly braces thing thereis syntax for a struct type,
-
12:43 - 12:48with two fields - x and y -of type "float."
-
12:48 - 12:52And, the type declarationjust defines an alias for the type.
-
12:53 - 12:58This is just like a name for[the type record with two float fields.]
-
13:00 - 13:04So, if I define a function,which takes an argument of this point,
-
13:04 - 13:08I can call it with just a recordconstructed on the fly
-
13:08 - 13:11without any record name involved.
-
13:12 - 13:14Records themselves don't have a name:
-
13:14 - 13:16they just have a structurein this system, and...
-
13:17 - 13:20it's kind of nice and lightweightand minimal,
-
13:20 - 13:24and often you don't even botherto give your record a name
-
13:24 - 13:25if you only use it a few times.
-
13:27 - 13:29So, where you would nowprobably use it [ ... ,]
-
13:29 - 13:34you could use a recordwith nice descriptive field names.
-
13:34 - 13:37I kind of liked it for programming with...
-
13:39 - 13:42But, I'll come back laterto why this part was removed.
-
13:43 - 13:46Another aspect of this was object types,
-
13:47 - 13:49whereas structure typeswere only compatible
-
13:49 - 13:53if they had actuallythe exact same fields and...
-
13:54 - 13:55in the same order.
-
13:55 - 13:58They weren't reorderedbecause of C compatibility
-
13:58 - 14:02and they had to be the exact sameto be able to compile it efficiently
-
14:02 - 14:05because then all codethat interacted with such a record
-
14:05 - 14:07knew how it was laid out in memory.
-
14:08 - 14:12Objects were a more dynamic feature,and here...
-
14:14 - 14:19any object type that has a subsetof the fields -
-
14:19 - 14:22fields are always methods -so they're always functions.
-
14:23 - 14:26This object type has its compatible,so I could,
-
14:27 - 14:30if I define the type - a collection of T -with these two -
-
14:30 - 14:33it's probably not a very great abstractionbut just bear with me -
-
14:33 - 14:37with a length andan item accessor method.
-
14:37 - 14:41You could take any object that hasI don't know what kind of...
-
14:42 - 14:44methods with also these two,
-
14:44 - 14:47and you could treat itas a collection of T.
-
14:48 - 14:52So, these were both the typesof the concrete objects
-
14:52 - 14:56and also serve the role of interfaces,which is kind of nice in terms of
-
14:56 - 15:00how many concepts you needto do object-oriented programming.
-
15:00 - 15:02And, you could also even use itas a kind of...
-
15:04 - 15:08checked duck typing,where you define your function
-
15:08 - 15:10and you just say:"I'm only going to call length
-
15:10 - 15:12"on the thing that I'm getting,"
-
15:13 - 15:15and then, anything that had a lengthmethod could be passed in -
-
15:15 - 15:18you don't even need to formally definean interface name or anything,
-
15:18 - 15:22it's just all like structural by name.
-
15:24 - 15:26So...
-
15:28 - 15:29One implication of this was
-
15:29 - 15:32that because code that used themdidn't know their size,
-
15:32 - 15:34they always had to be heap allocated.
-
15:34 - 15:36I think they even alwayshad to be garbage collected.
-
15:38 - 15:43Any [calls to them] will be goingthrough a dispatch table - a vtable.
-
15:43 - 15:46So, they're so much more heavyweight...
-
15:48 - 15:50compared to the rest of the language.
-
15:50 - 15:52We were finding that, in the compiler,
-
15:52 - 15:54we were kind of shying away from them
-
15:54 - 15:58and that we absolutely neededpolymorphism because
-
15:59 - 16:02they were more heavyweightthan necessary in many situations.
-
16:06 - 16:08Then, at some point...
-
16:09 - 16:11well, there was also
-
16:11 - 16:13a lot of machinery involvedin actually doing this,
-
16:13 - 16:17like upcasting to a type with less methods
-
16:17 - 16:20because then you needed toallocate a new vtable,
-
16:20 - 16:23preferably statically,which forwarded to the [alt] object
-
16:23 - 16:25and created a wrapper.
-
16:26 - 16:29It was conceptually simplebut not terribly simple to implement.
-
16:29 - 16:31And then, at some point...
-
16:32 - 16:35we got more [Haskell?] peopleon the team
-
16:35 - 16:37and we all started agitating for
-
16:37 - 16:40a typed class kind of implementation
-
16:40 - 16:43interface thing that we ended up with now.
-
16:44 - 16:47And, because no one really likedthese objects very much,
-
16:47 - 16:50we migrated to [that].
-
16:50 - 16:55And, I think they just fitwith the language much better.
-
16:55 - 16:58They don't require youto put something on the heap.
-
16:58 - 17:04They don't require indirect [calls] unlessyou actually are using polymorphism.
-
17:05 - 17:07So, I think that's a win.
-
17:08 - 17:15But, now that we have implementations,which effect a specific type,
-
17:17 - 17:19structural recordsalso become problematic,
-
17:19 - 17:22because if you're using a record thathappens to have the same shape
-
17:22 - 17:24in two completely independent contexts
-
17:25 - 17:29and they both define saya two string implementation of it,
-
17:29 - 17:30then these will clash,
-
17:30 - 17:33even though the actual usageshave nothing to do with each other,
-
17:33 - 17:36they will both be trying toimplement the same interface -
-
17:36 - 17:37the same trait on it.
-
17:38 - 17:40That doesn't work, so...
-
17:40 - 17:43Well, no one cared that muchabout structural records either,
-
17:43 - 17:47so they became nominalfor this reason at that point.
-
17:48 - 17:49And now, of course,
-
17:49 - 17:51[people's end functions]are still structural -
-
17:51 - 17:53they don't make much sensein any other way.
-
17:53 - 17:58But, the like heavy emphasison structural typing was abandoned...
-
17:59 - 18:01again for good reasons.
- Title:
- Marijn Haverbeke - The Rust That Could Have Been
- Description:
-
This talk will describe a number of language concepts and features that were in the pre-1.0 Rust language at some point but were ultimately abandoned, such as typestate, garbage collection, structural types, and a more or less classical object system. I’ll go over the reasons they were abandoned, and try to convince you that the Rust we have now is the best Rust yet.
---
For more go to https://rustfest.eu or follow us on Twitter: https://twitter.com/rustfest - Video Language:
- English
- Duration:
- 31:11
Sasha Harrell edited English subtitles for Marijn Haverbeke - The Rust That Could Have Been | ||
Retired user edited English subtitles for Marijn Haverbeke - The Rust That Could Have Been | ||
Retired user edited English subtitles for Marijn Haverbeke - The Rust That Could Have Been | ||
Retired user edited English subtitles for Marijn Haverbeke - The Rust That Could Have Been | ||
Retired user edited English subtitles for Marijn Haverbeke - The Rust That Could Have Been |