Bending the Curve: A Personal Tutor at Your Fingertips
This is a modal window.
Das Video konnte nicht geladen werden, da entweder ein Server- oder Netzwerkfehler auftrat oder das Format nicht unterstützt wird.
Formale Metadaten
Titel |
| |
Serientitel | ||
Anzahl der Teile | 10 | |
Autor | ||
Lizenz | CC-Namensnennung 3.0 Unported: Sie dürfen das Werk bzw. den Inhalt zu jedem legalen Zweck nutzen, verändern und in unveränderter oder veränderter Form vervielfältigen, verbreiten und öffentlich zugänglich machen, sofern Sie den Namen des Autors/Rechteinhabers in der von ihm festgelegten Weise nennen. | |
Identifikatoren | 10.5446/52197 (DOI) | |
Herausgeber | ||
Erscheinungsjahr | ||
Sprache |
Inhaltliche Metadaten
Fachgebiet | ||
Genre | ||
Abstract |
|
RustConf 20206 / 10
3
00:00
Rhombus <Mathematik>KurvenanpassungBiegungSoftware EngineeringCompilerStrömungsrichtungBitFormale SpracheJSONXMLComputeranimationBesprechung/Interview
00:33
BiegungFormale SpracheBitFontProgrammierspracheKanalkapazitätCompilerMigration <Informatik>Formale Sprache
01:25
Migration <Informatik>AggregatzustandStrategisches SpielMAPSelbstrepräsentationBesprechung/Interview
01:47
p-BlockWorkstation <Musikinstrument>MeterMAPFlächeninhaltSelbstrepräsentationElektronischer Programmführer
02:34
Elektronischer ProgrammführerMultiplikationsoperatorp-BlockOrdnung <Mathematik>Bus <Informatik>MathematikBesprechung/Interview
03:00
MathematikPlastikkarteProgrammierspracheSchnitt <Mathematik>FlächeninhaltDämpfungMAPShape <Informatik>Besprechung/Interview
03:28
MAPShape <Informatik>ProgrammierspracheProgrammbibliothekGeradeCodeÜberlagerung <Mathematik>Prozess <Informatik>ProgrammierparadigmaAppletProgrammierungEndliche ModelltheorieMathematikFormale SpracheHilfesystemFehlermeldungBesprechung/Interview
04:38
ProgrammierspracheDatenanalyseProgrammierungDienst <Informatik>ProgrammProgrammiergerätRechenwerkShape <Informatik>CASE <Informatik>Formale SpracheWort <Informatik>Ordnung <Mathematik>MultiplikationsoperatorKategorie <Mathematik>MAPProgrammierungStrömungsrichtung
05:24
Formale SpracheLaufzeitfehlerSampler <Musikinstrument>OISCProgrammierungMailing-ListeObjektorientierte ProgrammierspracheFormale SpracheGewicht <Ausgleichsrechnung>Minkowski-MetrikMathematikImplementierungModulare ProgrammierungMereologieProgrammierspracheElektronische PublikationCompilerLaufzeitfehlerSampler <Musikinstrument>RechenwerkMultiplikationSoftwareExistenzsatzHeegaard-ZerlegungOrdnung <Mathematik>LeistungsbewertungKreisflächeDifferenteBesprechung/Interview
07:27
Sampler <Musikinstrument>LaufzeitfehlerProgrammierspracheFormale SemantikProgrammierspracheGemeinsamer SpeicherMultiplikationsoperatorCodeProdukt <Mathematik>Formale SpracheMereologieImplementierungEndliche ModelltheorieUmsetzung <Informatik>DickeWiederherstellung <Informatik>Objektorientierte ProgrammierspracheFormale GrammatikSyntaktische AnalyseBesprechung/Interview
08:29
Explosion <Stochastik>CompilerFehlermeldungMessage-PassingProgrammierungABEL <Programmiersprache>DatentypDefaultProgrammierspracheFormale GrammatikFormale SemantikFormale SpracheFormale SemantikMessage-PassingDefaultGenerizitätProgrammierspracheSampler <Musikinstrument>ImplementierungFunktionale ProgrammierspracheMinkowski-MetrikMathematikFehlererkennungPoisson-KlammerAusnahmebehandlungKlasse <Mathematik>CodeWiederherstellung <Informatik>CASE <Informatik>Kontrast <Statistik>SchlussregelMusterspracheUmsetzung <Informatik>SchnelltasteProgrammschleifeEndliche ModelltheorieHalbleiterspeicherMultiplikationsoperatorFitnessfunktionDifferenteDemoszene <Programmierung>DatensatzMereologieBesprechung/Interview
10:57
Natürliche SpracheInstantiierungProgrammierspracheWurzel <Mathematik>InjektivitätMultiplikationsoperatorBesprechung/Interview
11:31
ProgrammierspracheWurzel <Mathematik>DämpfungZellularer AutomatSoftwareentwicklerMereologieFormale SpracheCodePhysikalische TheorieKreisbogenKonstruktor <Informatik>Einfache GenauigkeitMultiplikationsoperatorEndliche ModelltheorieBesprechung/Interview
12:58
KurvenanpassungProgrammierungSystemplattformFormale SpracheShape <Informatik>CodeStandardabweichungProgrammierumgebungFormale SpracheExpertensystemInternetworkingAppletBruchrechnungVirtuelle MaschineProdukt <Mathematik>Basis <Mathematik>SystemplattformSoftwareCompilerEntscheidungstheorieMathematikProgrammierspracheZentrische StreckungSampler <Musikinstrument>RechenschieberObjektorientierte ProgrammierspracheBinärcodeMultiplikationsoperatorKurvenanpassungTexteditorKonfiguration <Informatik>MultigraphMereologieGoogolSystemprogrammVollständigkeitProgrammierungDebuggingGRASS <Programm>Algorithmische LerntheorieProgrammbibliothekAnalogieschlussEinfache GenauigkeitEindringerkennungEndliche ModelltheorieProzess <Informatik>DatenverwaltungBesprechung/Interview
16:20
ProgrammierumgebungCompilerGrenzschichtablösungDifferenteVisualisierungExpertensystemProdukt <Mathematik>Formale SpracheProgramm/Quellcode
16:58
ProgrammierumgebungCompilerCodeProgrammiergerätMultiplikationsoperatorFunktionale ProgrammierspracheVerkehrsinformationCodierungAusnahmebehandlungGenerator <Informatik>PolygonnetzBildschirmmaskeFehlermeldungAusdruck <Logik>BinärcodeProgramm/Quellcode
18:02
MAPParallele SchnittstelleCompilerTypentheorieProgrammiergerätGruppenkeimExplosion <Stochastik>Message-PassingFehlermeldungProgrammierungGüte der AnpassungStatistikCodeMinkowski-MetrikMultiplikationsoperatorFehlermeldungSoftwareentwicklerBinärcodeTaskMereologieProgrammfehlerWort <Informatik>MAPPerfekte GruppeMomentenproblemBitCompilerFormale SpracheBesprechung/Interview
19:39
TupelInnerer PunktPrädikat <Logik>DatentypPrädikat <Logik>ParserOrdnung <Mathematik>SchnelltasteArithmetischer AusdruckDatenfeldExistenzsatzParametersystemTypentheorieCharakteristisches Polynom
20:18
FehlermeldungMinimumSystemaufrufNegative ZahlMinkowski-MetrikRandwertFormale GrammatikValiditätFormale SpracheFlächeninhaltBesprechung/Interview
20:44
RandwertCodeRechter WinkelSchlussregelProgrammierspracheFlächeninhaltLoopFormale GrammatikImplementierungValiditätBesprechung/Interview
21:24
Normierter RaumFormale SpracheMultiplikationsoperatorProdukt <Mathematik>Logischer SchlussTypentheorieTeilmengeSoftwareCompilerElektronischer ProgrammführerProgrammiersprache
22:11
Kontextbezogenes SystemF-TestFehlermeldungMessage-PassingProgrammierspracheComputervirusZeichenketteMinimalgradBereichsschätzungZeichenketteInformationOrakel <Informatik>Program SlicingHalbleiterspeicherFormale SpracheFolge <Mathematik>CompilerSpeicherverwaltungMAPZeiger <Informatik>ValiditätCodePunktSichtenkonzeptAppletPuffer <Netzplantechnik>MultiplikationsoperatorSoftwareentwicklerBinärcodeTypentheorieKontextbezogenes SystemUnicodeFehlermeldungDickeATMHIP <Kommunikationsprotokoll>
24:41
TermFehlermeldungTypentheorieHill-DifferentialgleichungDatensichtgerätInnerer PunktDrucksondierungTypentheorieMereologieFehlermeldungSchlussregelLogischer SchlussCompilerFunktion <Mathematik>DifferenteCodeCASE <Informatik>Deskriptive StatistikWort <Informatik>QuaderObjektorientierte ProgrammierspracheElektronisches ForumVerschlingungÄußere Algebra eines ModulsFormale SpracheHilfesystemBetriebsmittelverwaltungHydrostatikParametersystemSpeicherverwaltungInformationSystemaufrufRichtungMeta-TagBesprechung/Interview
27:55
ParametersystemCompilerFehlermeldungErlang-VerteilungProgrammierspracheRoutingCompilerSystemaufrufHeuristikSoftwareentwicklerSchlussregelMultiplikationsoperatorCodeCharakteristisches PolynomMathematikSchwellwertverfahrenBesprechung/Interview
Transkript: Englisch(automatisch erzeugt)
00:16
Hi, I'm Esteban Cuber, a software engineer at Commuir, and a member of the Rust compiler team.
00:22
I will be talking about what Rust can do to improve its learnability beyond changing the language itself. But first, I want to address the name of the talk. I chose it late last year before our current situation, and because I'm a bit slow, I didn't realize how topical it has become until after it has been accepted and published.
00:41
It will become clearer why I chose it originally later in the talk. Secondly, while I was expanding the outline of this talk into a draft, I realized that the topics I was talking about were way more general than just Rust. Because of these two things, if I were to change the title of this talk,
01:00
it would be closer to, so you want to make a programming language that people use. I also want to point out that this talk will address not the how Rust does some things, but instead what and why. And finally, I want to acknowledge that I'm not a language designer, and I'm not speaking in any official capacity as a member of the compiler team.
01:22
With that out of the way, let's talk about migration. An experience that a lot of you may have had is moving to a new city, a new state, or a country. When going through something like that, you have to relearn how and where to do things that you were already used to doing.
01:41
You will rely on one of, broadly speaking, three tools and strategies. First, you will have access to a map, which is a simplified graphical representation of a physical space. It lets you get your bearings, find where important places are, and help you get there. With it, you can know that the firefighter station is 415 meters away from your house as the crow flies,
02:06
but it won't tell you that the sidewalk in front of it is broken, so you have to watch your step around there. Second, you will also explore, either intentionally or not, as you go about your day, and slowly create and expand a mental map of the area.
02:22
You may come across a pizza place and think to yourself, it looks reasonably priced, I need to check it out. It's two blocks down the street next to the red house. And finally, you may check out a travel guide or talk to a neighbor or friend that already knows the city.
02:40
They may let you know about things that would otherwise take you a long time to find out about. Like telling you, if you go three blocks the other way, there is a pizza place that is more expensive, but it's the best pizza in town. Or they will let you know about things in advance that would be annoying or inconvenient to find out yourself, like, in order to take the bus you need to already have a travel card, or you need the exact change.
03:06
What they are doing is using their lived experience, extrapolate what they know about you and your lived experience, and cut to the chase to discuss the areas that are different from what you may be used to, instead of starting from scratch and explaining what a street is.
03:23
The experience of learning a programming language can be very similar. You will have a map of the land, in the shape of the reference documentation, which will be detailed in the language's and libraries' arcane behaviors. Some people like to go through the documentation from cover to cover,
03:40
and only then, once they have an idea of what's available, will they venture to write their first line of code. Other people are more hands-on, particularly people that already know one or more other languages already. They may need a brief introduction, and then start trying things out.
04:02
Through this trial and error, they will be building a mental map of the language, identifying where their previous knowledge applies, and where it diverges in the new language. When moving from a language to another that follows the same particular programming paradigm, this process can be quite smooth.
04:20
When going from one paradigm to another, the process can be more arduous. For example, somebody familiar only with Pascal, moving to Java will require a slight change in their mental model. Same for someone moving from Java to Haskell. Finally, some people will seek out help.
04:40
This can be in the shape of a book targeted at people learning the language, in some cases aimed at people from very specific backgrounds, or through their reliance on online communities, or even hiring a teacher to teach you the language. When doing this, regardless of medium, the people on the other side will try to identify
05:01
what your current level of familiarity with the subject is, what you already know, in order to minimize the time needed to get you up to speed and productive. This includes succinctly pointing out things that will work out the same to what you're already used to, and particularly pointing out where that is not the case. I will be referring to this whole category of learning approach under the word tutor.
05:27
When designing a programming language, you will have a list of priorities or objectives you want to accomplish. You can't prioritize all things equally, which means that some will have a higher weight than others, and some will even restrict or preclude others.
05:44
You may want to prioritize runtime and design flexibility, but this priority will almost assuredly restrict how performant your language could be. You could decide to prioritize final execution speed, but that may require you to sacrifice compilation speed or restrict how dynamic your software can easily be made at runtime.
06:04
A different priority may be compilation speed, but this will certainly affect what feature the language can have in order to avoid potentially exponential evaluation in the language, or how ergonomic the language can be. An example from Rust could be that the smallest compilation unit is the crate,
06:22
and not the file, like in other languages. This permits the existence of circle and imports in the language, for example splitting an IDT definition and its implementation throughout multiple files, as long as they all belong to the same crate. This is good for the ergonomics of the language to help you keep your code clean,
06:42
but it means that currently Rust C cannot compile multiple files from the same crate in parallel. This is not a strong technical restriction, mind you, there are changes that could be made to make this possible, but they are hard to implement. If the language design had gone with a more restrictive module system,
07:01
it would be less ergonomic, but it would have allowed to simplify the implementation of the compiler, and made it easier to make this particular part of it faster. One reason I'm very happy to see the explosion of new languages in the past couple of decades is that there is no wrong answer on what the priorities should be,
07:21
and even if there were, having a swarm attack in the problem space helps everybody. We can learn from each other, see what works, what doesn't. Languages share and steal from each other all the time, and that is a great thing. Rust, for example, has very few original ideas.
07:42
An always implied priority in language design is to make the language as easy to pick up as possible. Very rarely someone goes out of their way to make their product harder to use. Beyond the objectives of the language, there are different parts of what makes a language. First and most visibly, you have the chosen syntax and grammar of the language,
08:03
which is what you can write, what the code looks like. A lot of conversations go on at length about syntax as if it were the most important part of any language. I strongly disagree. Cue a sync-await syntax conversation in the comments. I consider parsing and syntax to be the least interesting part of any language,
08:24
as it is mostly a solved problem that requires little effort in both design and implementation. A model of things like malformed code recovery. Particularly when put in contrast with the rest of the compiler's functions and the language design space.
08:41
Using square brackets instead of less than or more than for generics, to give an example, has little impact on the experience of writing the language, although it can have huge implications on the compiler's implementation and error recovery. Cue turbofish conversation in the comments. Secondly, you will also have the semantics of the syntax.
09:04
How the code actually behaves when written in a certain way. This is where small differences can surprise people when moving from language to language. This includes behaviors such as what happens behind the scenes when you call a method, or where in memory your data lives and how it is accessed.
09:22
Finally, you have features, but you can, and almost as important, cannot do with language. Language design is a lot of the time saying no, removing things that had been tried before that can lead people to make avoidable mistakes or that don't fit the rest of the language.
09:41
If you have used Rust, you have already noticed that this is very much part of its design, from the pro-road checker through the non-representability of null to immutability by default. When it comes down to it, features are sometimes foundational stuff common to all or most languages, like being able to bind a local variable or while loops,
10:01
or formalizing existing patterns into the language, like message passing or first-class functions. Regardless, anyone learning your new language, and in our case Rust, will have to internalize rules from those three buckets. If they come tabula rasa, you can ignore prior art and do anything you think will be best for them.
10:23
But in reality, a lot of people will be coming from other already existing languages, and there are so many languages out there that you can learn a lot from, or still if you prefer, with the benefit of hindsight. For all the complaints about the breakneck change in Rust, I believe it is a boring language.
10:41
All of its features, with the single exception of the pro-road checker, already exist in other languages. People more eloquent than me have described this as your language strangeness budget. I tried to say that three times in a row. The further you stray from the beaten path, the harder it will be for people to walk with you.
11:04
Consider human languages, for instance. There are lots of languages across this earth of ours, and a lot of them have common roots. Somebody who speaks Spanish, for example, will have a relatively easy time learning Portuguese. There is no one-to-one mapping for every grammatical construct and rule,
11:24
but due to their shared heritage, applying rules from Spanish to Portuguese will be correct more often than not. Picture instead if a Japanese person wanted to learn Norwegian. As beautiful as Norwegian may be, due to those two languages sharing no common root, this person will be having to start from scratch, which can be a much more frustrating experience.
11:46
Quick aside! I have the unsubstantiated theory that experienced developers have a harder time than less experienced developers when learning Rust. They need to forget a lot of constructs that work well enough in the languages they already know,
12:02
because they introduce things that go against the single owner enforcement that Rust has. Whereas somebody with less experience will simultaneously accept restrictions as just the way it is, and not seek out other, more performant constructs that can be much harder to understand or implement.
12:22
Rust has a curse. It has many, but this one is critical. Inefficient code is generally visible. Experienced developers hate to notice that their code is inefficient. They will recall at saying ark of ref cell of t, but they won't bat an eye at using Python. I know because I have the same instinct.
12:41
This makes it much harder to learn Rust for experienced developers, because they start with simple Rust code that will work but is slightly inefficient, and in an effort to improve it, they land squarely in parts of the language that they haven't yet developed a mental model for. To summarize, when creating a learnable language, copy from others,
13:05
deviate from them only if you're convinced you have a very good reason to do so. To do otherwise is to avoid success at all costs. If you have been on the internet for as long as I have, you must have already encountered this old joke.
13:21
It represents the learning curves for some popular editors people would use back in the 90s. People have done quite a few of these graphs for programming languages too. I would say that Rust probably lands somewhere between C++ and Haskell in there, but if you go looking around for the perception of Rust's learning curve, it's not very encouraging.
13:48
Part of the problem is the objectives we've set ourselves. We prioritize being able to produce fast binaries for constrained environments, and anything that can be done towards ergonomics and compilation speed
14:01
while not affecting that objective is already being done. Having said that, the experience of learning and using a language goes beyond the language itself. The available libraries, documentation, tooling, platform support, and the surrounding community all affect how easy it is to learn a language,
14:25
and as importantly, how likely people are to stick around. Going back to my original analogy, moving to a new place is not a single decision in time. In fact, every day you reaffirm your decision to stay, even if possibly.
14:41
If you had infinite resources, you could improve the learnability of your language, change the slope of its learning curve, by providing every single newcomer with a personalized tutor. This, needless to say, doesn't scale. You may have noticed that I included a nebulous tooling item in that prior slide.
15:02
This includes things like code formatters, linters, debuggers, package managers, and IDEs. For a while last century and up to the 90s, there was this fad in our industry dubbed Expert Systems. It was posited that you could take a handful of really experienced people,
15:22
pick their brains and encode their thinking, mental model, and decision-making process, and use that as the basis of software used by other, less experienced people. This way, you could get the benefits of an expert at a fraction of the cost to train one. We are still trying to apply this idea, only now we call it machine learning,
15:41
and we use it to figure out how many teaspoons there are in a measuring cup. This idea has been used in our industry in an effort to increase productivity in the shape of IDEs, Integrated Development Environments. These programs, with a text editor, debugger, code navigation utilities, auto-completion,
16:01
and other goodies, have everything you may need when writing software. If you look at most ecosystems, IDEs are an optional, separate tool from the compiler. In Java land, you have a plethora of options to choose from, from good to pretty amazing.
16:20
In the Microsoft.NET ecosystem, talking about the IDE Visual Studio and the compiler as separate entities is making a distinction without the difference. The compiler is so deeply embedded in the IDE that they are one and the same. But as I said earlier, IDEs are focused on productivity, not learnability.
16:40
We could create a new tool to act as a tutor, apply the idea of expert systems to the teaching of a language. But when you introduce a new tool, you have the problem of discoverability. The people that may need it the most will never find out about it. You could introduce it into an IDE, but if your ecosystem isn't self-contained,
17:03
making this IDE the de facto tool that all newcomers use, you're not helping everyone you could. However, there is one mandatory tool that people are forced to use. The compiler. A lot of people have this idea that the primary function of a compiler
17:22
is to take well-formed code and spit out a runnable binary. My steaming hot take is that the primary function of a compiler is to take malformed code and emit diagnostics to help the programmer turn it into well-formed code. A compiler is an error reporting tool with a code generation sidekick.
17:45
I know a lot of people will give me pushback on that comment and I am being slightly flippant, but what the user of the compiler uses it for the vast majority of the time is to get feedback on whether they have missed something. The vast majority of the code in the Rust compiler is dedicated to error reporting.
18:04
Yeah, I don't have good statistics, but anyone that has contributed to Rust C can attest that it certainly feels that way. Efficiency of generated code is important, but it is a well-explored space with decades of research and applied techniques.
18:21
At the same time, emitting good diagnostics is hard because it requires a lot of foresight and effort. Diagnostic errors touch upon every single part of the language from how easy it is to write typos that look like well-formed but nonsensical code to parsing errors that are carried forward to later stages of the compiler, compounding as they go along.
18:41
Unless you make it a priority, the developer experience will always be subpar. Communicating with the user to get them to that generated binary is at least as important, and in my eyes, it is more important than any other task the compiler is asked to do. And when we are emitting diagnostic errors,
19:01
it's the perfect place and moment to teach people. They have made a mistake and we can explain to them why they've made it. Think about what I'm talking about, what the possibilities we have here. Consider the kind of errors that people see. You have parse errors that are caused by malformed code
19:21
that is close to correct but that has a few typos. There is quite a bit of research on how to detect these errors automatically and identify what the user's original intent was. But if you have enough users reporting bugs and enough developers, you can get quite far with simply identifying common and problematic errors and handling them proactively in the parser.
19:43
We can detect small, incorrect usages. An example I always come back to is type ascription. It doesn't matter what it does, but I'll give you a short overview regardless. It is nightly only. It lets you annotate any expression with a type and uses the colon character in order to mimic let bindings
20:03
with types, function argument bindings, and struct field bindings. But it has one extra characteristic. It is extremely easy to make a typo that looks like it's a naive Rust parser. It's been the bane of my existence, but I am quite happy with how well we can detect it nowadays
20:21
and recover relatively well, although as you can see at the bottom there, we are still not quite there in silencing knockdown errors caused by it. Other more pervasive errors are what I call negative space boundary errors. I've taken to interpreting the negative space of a language as the area outside of a language valid grammar.
20:44
Consider a Cartesian area. Everything inside of that boundary is valid Rust. Everything outside of that boundary is all possible permutations of text. That's how the Rust grammar sees the world. But we aren't like that. We deal in shades of gray. There is code that lies right on the wrong side of that boundary
21:03
that would loop to a human as correct. It could be code that Rust explicitly doesn't support, for some specific reason. A reasonable person may be extrapolating from rules they have already internalized, if not fully learned, or relying on rules from other languages that don't apply to Rust and land there.
21:22
But the interesting thing is that we can proactively search for these cases, or at least watch people land in those places. This is not an original idea. Other types of software products conduct user research all the time, looking at how people fail to use their products. And once they have identified things reasonable people may do,
21:43
we can make the compiler handle them, even when they are features that can't be included in the language. Because we can make the compiler in fair intent, we can make the compiler understand the superset of the language and guide people towards a valid, supportive solution,
22:01
while explaining why what they have tried to do isn't supportive. This can include things that are possible in other languages, but that are not possible in Rust. One problem you may envision with that approach is that a tutor needs to have some knowledge of their duty to give them short, relevant explanations.
22:21
As you can imagine, writing a compiler with that level of knowledge of the user would be difficult for a non-Google entity, and even then. But the compiler has context of what the error was. For problems off the beaten path, but with a high degree of intent, we can assume that the user knows what they are trying to accomplish.
22:41
They just don't know how to do it in Rust. You need to have a lot of confidence when guiding the user, though, because misleading users can have dire consequences. For example, people with less experience may treat the compiler as an all-knowing oracle. When the oracle is wrong, they get very confused.
23:00
For common problems like typos, we don't need to give too much of an explanation. Consider explaining the distinction between string slices and heap-allocated strings to a newcomer. Rust has two and a half types here to represent the concept that depending on the language you are coming from, is either one or maybe two. A string is a continuous piece of memory
23:21
holding valid UTF-8 sequence of code points. A string slice is a fat pointer to a string and a length. A heap-allocated string is almost the same, but this fat pointer is owned and the sequence is in the heap and can be reallocated.
23:40
We need to explain that string slices can point to either a string or inside a heap-allocated string. We have to explain the ownership mode, auto-referencing, the distinction between the heap and the stack, unicode code points. And we haven't even mentioned null-terminated strings. All string, path, back of U8, back of char,
24:03
UTF-8, UTF-16, UTF-32, size of this or lifetime yet. If you knew where the user is coming from, we could explain to a C developer that the string is like a non-null-terminated string in the binary. To a C++ developer, that string slice is like a string view.
24:21
And to a Java developer, that a heap-allocated string is analogous to a string buffer. But we can't know where they are coming from. And you just saw how much time I needed to explain this one thing that you encounter really early on and that you're likely to encounter often after that.
24:40
So instead, we give out enough information to immediately unblock you, consider borrowing, call to owned. We provide a strong description of the problem that gives you just enough information to tell you there is a reason for the supplied code not to be accepted. In other cases, we would even weave a bunch of jargon
25:03
in the description on purpose to feed you words that you can search for. This way, people are slowly learning some of the rules, sometimes by inference, and sometimes being outright told about them. An example of teaching when relevant can be when wanting to return something
25:23
that implements a trait without caring about the actual underlying type. A Rust newcomer's first instinct could be to directly return it and just set the return type to the trait. Currently, doing so currently
25:40
inundates the output with a bunch of different errors. Some are stylistic warnings that can be easily fixed, and we explain how to do so. Other are knockdown errors that we should be hiding already. They will be fixed if you fix other parts of the code. But then we get to the meat of the output.
26:01
We introduce people to a potentially new feature for them and even include a link to the documentation they can read up on. The compiler actually checks that the suggestion would actually work. It checks that the involved types could work with a new return type. With slightly different output where impletrate wouldn't work directly,
26:23
we still give a bunch of unnecessary errors, but we also explain why impletrate won't work and provide the user a bunch of alternatives, in this case, using a box trait object or an enum, along with some example code that they can directly use. All of this lets us get around the lack of support
26:43
in the language for unsized return types while unblocking the user without forcing them to visit a forum to ask for help. Of course, someone that already knows they can't return an unboxed trait directly may try to avoid the heap allocation cost
27:02
and try to return a borrow but not know or forget that the lifetime has to be related somewhere. Another example can be when people get bitten by implicit static lifetime requirements of trait objects or type parameters. In all of these cases, the compiler tries to interpret
27:20
what the user is trying to accomplish and gives as short an explanation as it can to get them underway. You can consider the objective to minimize how much people have to ask for help. I showed that my coworkers asked me for help for a given problem once, and then I run and encode the explanation in the compiler.
27:42
If the compiler has been helpful to you in the past, feel free to thank my coworkers. But once you have gone this direction of providing suggestions, you can go wild. I mean, if you're already parsing a meta language, let's call it ++. Why not go all the way in? You can start parsing things from other languages
28:02
and start translating them. You don't have to go too deep down that route, just enough to catch people that have a momentary mental lapse. I'm also convinced that this approach has an extra benefit that is incredibly important. It lets Rust remain simple.
28:20
It reduces how many rules people need to keep in mind and makes the behavior of the code directly related to the code itself. There is no need for advanced behavior in the compiler that decides whether to use static or dynamic dispatch on a method call, depending on some internal heuristics. The behavior is laid bare in the code,
28:41
and its performance characteristics will not change from under you due to some unrelated code changes crossing some threshold. I also believe strongly that dedicating manpower to improving the user experience of developer tools is of paramount importance.
29:01
It is quite amazing to me what we have come to expect from our tools user experience. It seems like our entire industry has had Stockholm syndrome for so long that we don't even notice anymore. I want to ask of all of you today two things. Demand better from your tools
29:20
and be mindful of your users. Thank you for your time. Thank you.