chiark / gitweb /
wip
[talk-2019-ghm-rust.git] / talk.txt
1
2 In many respects Rust is a competent but not particularly novel
3 language.
4
5 Powerful.
6
7 Reference to Blub languages.
8
9 B======================================================================B
10
11 [ MM survey slide ]
12
13 Firstly, I'm going to go into some detail about Rust's one very novel
14 property: it's approach to memory management.  Let us consider,
15 particularly, dynamically allocated memory.
16
17 Until now there have been basically two approaches:
18
19 In lower-level languages like C, C++ and assembler, you as the
20 programmer must know whenever memory allocation is occurring, and
21 control when that memory is freed, usually with explicit code.
22 Mistakes lead to bugs - often, bugs which are very hard to track down.
23 There are some static checkers, and coding conventions, which help to
24 reduce the number of these bugs but they are still a big problem even
25 with the most careful software development practices.
26
27 In higher-level languages, memory allocation is often implicit and
28 deallocation is handled automatically by a garbage collector.  This is
29 convenient for the programmer.  But it requires support from a
30 language runtime, which is awkward in some environments and makes it
31 hard to interface to other languages.  And it costs performance -
32 sometimes, a lot of performance.  Traditionally, garbage-collected
33 languages have focused on programmer convenience, or programming
34 language power, rather than performance.
35
36 [ MM survey slide + Rust ]
37
38 Rust has a different approach.  Each object in a Rust program has
39 exactly one owner; for a local variable that owner is the variable.
40 For an object in a complex data structure, the data structure is the
41 owner (and of course that data structure has, in turn, an owner).  In
42 many ways this resembles informal notions of object ownership which
43 programmers have typically used in C and C++ to make their code
44 comprehensible.
45
46 But in Rust the ownership is known to the language, and the rules
47 surrounding ownership are enforced by the compiler.  When an object
48 ceases to have an owner, it is freed.
49
50 This ownership system is used not only for dynamically allocated
51 objects, but for local variables, and statically allocated objects.
52
53 [ Borrowing example slide ]  https://doc.rust-lang.org/book/ch04-02-references-and-borrowing.html#mutable-references
54
55 To allow an object to be accessed other than through owner, Rust
56 formalises the notion of borrowing.  An object can be borrowed by
57 writing the ampersand, giving a reference.  The compiler checks that
58 the object will outlive the reference.
59
60 [ dangling reference error example  https://doc.rust-lang.org/book/ch04-02-references-and-borrowing.html#dangling-references ]
61
62 Borrows (that is, references) come in two kinds: mutable and
63 immutable.  You can have many immutable references at once.  A mutable
64 reference permits modification, and provides exclusive access.
65
66 [ Borrowing example slide with mut missing ]  ABOVE https://doc.rust-lang.org/book/ch04-02-references-and-borrowing.html#mutable-references
67
68 That's what the `mut' is doing in that example.  If you leave it out
69 the compiler complains.  This is the Rust `borrow checker' that you
70 have may have heard about: the part of the compiler which enforces the
71 object ownership rules.
72
73 Overall, this scheme makes use-after-free and double-free bugs
74 impossible.  You have to work at it to make a memory leak.  Rust
75 programs are safe (by default): you can write bugs, but you cannot
76 randomly corrupt memory (or otherwise trigger what in C/C++ is called
77 "undefined behaviour").  The ownership rules even give you safe
78 multithreading.
79
80 And, the ownership system means that the compiler can often optimise
81 very aggressively, because it has really good visibility of all the
82 aliases of and references to the objects its working with.  Compared
83 to garbage collected languages, the ownership system eliminates a lot
84 of runtime memory management.  I have found Rust programs to generally
85 be very fast.
86
87 C======================================================================C
88
89 Apart from the ownership system, there is little new in Rust.
90 Nevertheless, it is an advanced language with a lot of expressive
91 power - power which is generally available without sacrificing
92 performance.
93
94 Sometimes advanced languages from academia can feel like
95 incomprehensible alien technology, with a steep learning curve and an
96 unfamiliar or even obscure syntax.
97
98 Not Rust.  For me, Rust has managed to take the best and most proven
99 features of earlier research languages, and package them up into a
100 whole which feels fairly familiar and is easy to use.
101
102 Rust's syntax is a conventional structure of curly braces, keywords,
103 parentheses, and infix expressions.  It looks a lot like C or
104 JavaScript or something.
105
106 Rust is safe by default.  That is, bugs in your code can't corrupt
107 memory the way that they do in C and C++.  But, unlike most other safe
108 languages, if you really want full manual control, you can write
109 `unsafe'.  This is rarely needed, even if you want really fast code.
110
111 Rust is statically typed.  The compiler will typecheck it.  This is
112 great.  You may have heard Haskell and Ocaml programmers say "once you
113 can get the program to typecheck, it will probably work".  Rust has
114 the same experience.  When in the throes of writing a complex
115 algorithm you can type some drivelous pseudocode into your text
116 editor.  Then keep fixing errors until it builds and lo! it will often
117 work.
118
119 Rust also has type inference (similar to Ocaml, Haskell, etc.), so you
120 can often leave out the type annotations.
121
122 Rust supports polymorphism (also known as `generics'; it calls the
123 feature `traits'.  They're a bit bit like C++ templates, but not mad.
124 Rust supports dynamic dispatch (like `virtual' in C++), or static
125 dispatch, but in both cases the typechecking is done at compile time.
126
127 [ unsafe Rust/C/C++ example, chrobakpayne.rs glue.cpp ]
128
129 Rust has a reasonably good system for interfacing to code written in
130 other languages.  With the appropriate annotations, you can call C
131 functions directly from Rust and vice versa.  (Of course this requires
132 you to say `unsafe', since the semantics of the C parts of the program
133 are not known to the Rust compiler so you must check them yourself.)
134 Built on top of that are machineries for glueing Rust to, for example,
135 Python.
136
137 D======================================================================D
138
139 I also want to talk a bit about the attitudes and values of the Rust
140 project.  (I should say that this is an outsider's point of view.)
141
142 [ slide with quotes from C vs Rust ]
143
144 The most impressive thing, for me, is that the Rust community does not
145 blame Rust programmers for the bugs in Rust programs.  Rather, they
146 look for opportunities to help the programmer avoid bugs.  There is a
147 clear design ethos, to make APIs where the default and easy option
148 does the right thing, and to avoid beartraps.
149
150 In particular, the comparison with C is very striking.  The C
151 community have even resorted to writing compilers which ferociously
152 analyse your program for violations of C's bizarre and
153 nigh-incomprehensible rules, and then use those rule breaches as
154 excuses to miscompile your program.
155
156 Convenience is not regarded as the enemy of correctness, but its ally.
157
158 [ slide with interface stability ]
159
160 The Rust project is quite careful about language and library
161 stability.  They make a clear distinction between stable and unstable
162 features, and try quite hard to avoid backward-incompatible changes to
163 anything which has been declared as stable.
164
165 [ process and code of conduct ]
166
167 There's a mature process for evaluating and deciding on new features,
168 and a modern Code of Conduct.
169
170 E======================================================================E
171
172 Of course nothing is perfect.  I'm very critical by nature, so I often
173 find things to gripe about.
174
175 The most obvious difficulty with Rust, if you read the internet, is
176 some's feeling they are constantly fighting the borrow checker.
177 Personally I have not found this to be a problem at all.  I think it
178 may depend on how much experience of informal object ownership systems
179 you have - in particular, how much C and C++ you've done.
180
181 Of course having something like the borrow checker is the price Rust
182 pays for its novel memory management strategy, and it is that novel
183 strategy that makes for the high performance of Rust programs.
184
185 There is one annoyance that occurs when trying to design and implement
186 complex APIs.  It is not straightforward to define an object type one
187 of whose members is (or contains) a reference to another member.
188 Luckily this doesn't come up very often, and it is still possible to
189 hide the issue from the API's consumer.  The awkwardness is tolerable.
190
191 Rust does have macros.  In fact it has two ways to define macros (one
192 built on top of the other).  The more sophisticated macro system is
193 very capable and has been used to really impressive effect.  But it's
194 hard to use casually; and the simpler macro definition facility is
195 simultaneously too complicated and underpowered.  So casual macro use
196 is slightly awkward.
197
198 But the worst problem is cargo.  Cargo is Rust's language-specific
199 package manager and build tool.  It is really quite annoying.
200
201 The worst problem is that like all modern tools of this kind, its main
202 purpose is to automatically download stuff from the internet and run
203 it.  Apparently this is what is expected by the youth of today.  It
204 can be hit hard enough to stop it doing this, but you still run into
205 the difficulty that if you use one library from the repository, you
206 end up having to trust much more widely than ideal.  And at least
207 Rust's repository contains larger libraries than, say node.js's, so
208 the number of people you're trusting is much lower.
209
210 Also, as a build tool, cargo can be very inflexible.  Despite an
211 official policy that cargo should be suitable for running inside
212 another build systme, requests to be able to do `weird stuff' seem
213 usually to result in excuses why the thing you want to do is a bad
214 idea, rather than useful increases in flexibility.  (And the excuses
215 are usually based on misunderstandings.)  I guess if your project ends
216 up containing piece of opinionated curl-pipe-bash-ware, you should
217 expect a culture which produces these kind of problems.
218
219 F======================================================================~
220
221 Despite these difficulties, and of course a fair few minor
222 irritations, I have found programming in Rust to be both fun and very
223 productive.
224
225
226
227
228
229
230
231
232
233 not
234 very good either.
235
236
237
238 Unlike many other modern programming language ecosystems, the Rust
239 project and its community have a welcoming, cautious and mature feel.
240
241 The