<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Steve Klabnik — Rust</title><description>The Rust programming language, its ecosystem, and the experience of working with it.</description><link>https://steveklabnik.com/</link><item><title>Arguing about arguments</title><link>https://steveklabnik.com/writing/arguing-about-arguments/</link><guid isPermaLink="true">https://steveklabnik.com/writing/arguing-about-arguments/</guid><description>Here’s some Rust code: // define a function fn foo (x : i32 , y : i32 ) -&gt; i32 { // body elided } // call it let z = foo ( 5 , 6 ); In programming language jargon, we call x and y parameters and 5 and 6 arguments . Rust does not have many fancy features related to parameters and…</description><pubDate>Mon, 21 Sep 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Here’s some Rust code:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;rust&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;// define a function&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;fn&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; foo&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(x&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; i32&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, y&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; i32&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; i32&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;    // body elided&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;// call it&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;let&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; z &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; foo&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;5&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;6&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In programming language jargon, we call &lt;code&gt;x&lt;/code&gt; and &lt;code&gt;y&lt;/code&gt; &lt;em&gt;parameters&lt;/em&gt; and &lt;code&gt;5&lt;/code&gt; and &lt;code&gt;6&lt;/code&gt;
&lt;em&gt;arguments&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Rust does not have many fancy features related to parameters and arguments. But
other languages do. For example, &lt;a href=&quot;https://api.rubyonrails.org/classes/ActionController/Redirecting.html#method-i-redirect_to&quot;&gt;here’s a function in Ruby&lt;/a&gt;,
another language I’ve written a ton of:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;ruby&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;# its definition in Rails&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; redirect_to&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(options &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {}, response_options &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {})&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;  # body elided&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;end&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;# you can call it in all of these ways:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;# pass a string with a URL&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;redirect_to &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&amp;quot;http://www.rubyonrails.org&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;# pass an instance of a model to go to it, if post.id = 5 then this might go to&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;# &amp;quot;/posts/5&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;redirect_to @post&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;# invoke an action directly, might be equivalent to the above in a Posts controller&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;redirect_to &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;action:&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &amp;quot;show&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;id:&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 5&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;# redirect to a model&amp;#39;s URL, passing a flash message&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;redirect_to &lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;post_url&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(@post), &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;alert:&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &amp;quot;Watch it, mister!&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;# do the same but also set a specific HTTP code&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;redirect_to &lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;post_url&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(@post), &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;status:&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; :found&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;# do both&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;redirect_to &lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;post_url&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(@post), &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;status:&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 301&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;flash:&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; { &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;updated_post_id:&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; @post.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;id&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; }&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I used to love Ruby, and now I love Rust. And to be honest, &lt;code&gt;redirect_to&lt;/code&gt; and
friends are a huge reason why I am so against Rust gaining these sorts of fancy
features: they can be really concise, and beautiful to a certain kind of eye,
but it also makes it really, really hard to know what all you can do with a
function. You pretty much have to hope that someone has written good documentation,
and while Rails’s documentation is pretty good, not every library is going to have
it.&lt;/p&gt;
&lt;p&gt;To be clear about it, there are several things bundled together here: flexible
argument types, options hashes, defaults, and keyword-looking syntax. It’s that
whole style of API that shaped my skepticism, not argument labels by themselves.&lt;/p&gt;
&lt;p&gt;So, what exactly are all of these features?&lt;/p&gt;
&lt;h2 id=&quot;named-parameters&quot;&gt;Named parameters&lt;/h2&gt;
&lt;p&gt;The simplest one is &lt;em&gt;named parameters&lt;/em&gt;. As you might guess, this means that we can
explicitly use parameter names at the call site:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;rust&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;// without named parameters&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;let&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; z &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; foo&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;5&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;6&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;// if Rust had them&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;let&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; z &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; foo&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(x&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 5&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, y&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 6&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Named parameters are nice because they can give you more information at the call
site, but also they can be more flexible. Some languages also let you supply
named arguments in a different order:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;rust&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;// since we have names, we can write this:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;let&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; z &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; foo&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(x&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 5&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, y&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 6&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;// but we can also write this:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;let&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; z &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; foo&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(y&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 6&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, x&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 5&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The downside of named parameters is that they can get quite verbose:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;# FastAPI in Python, UserOut class not shown&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;@app.get&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;    &amp;quot;/me&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    response_model&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;UserOut, &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    status_code&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;200&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    tags&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&amp;quot;Users&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;],&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    summary&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&amp;quot;Get current user profile&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; get_current_user&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;():&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I tried to not strawman this by showing an extreme example, but &lt;code&gt;get&lt;/code&gt; can take
23 different keyword arguments, and so this could get quite, quite long.&lt;/p&gt;
&lt;p&gt;Named arguments can be good when passing expressions, so we can understand
something more at the call site. In the above, &lt;code&gt;status_code=200&lt;/code&gt; is much nicer
than a bare &lt;code&gt;200&lt;/code&gt;, if you know HTTP well it’s kind of obvious what it is, but
the additional clarity is nice. But it can be common to break truly complex
examples down into variables that we end up forwarding to the function, and then
it becomes verbose &lt;em&gt;and&lt;/em&gt; redundant. As an example from inside FastAPI where
&lt;code&gt;get&lt;/code&gt; is invoked directly with all of those options:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;.router.get(&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    path,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    response_model&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;response_model,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    status_code&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;status_code,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    tags&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;tags,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    dependencies&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;dependencies,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    summary&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;summary,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    description&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;description,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    response_description&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;response_description,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    responses&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;responses,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    deprecated&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;deprecated,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    operation_id&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;operation_id,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    response_model_include&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;response_model_include,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    response_model_exclude&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;response_model_exclude,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    response_model_by_alias&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;response_model_by_alias,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    response_model_exclude_unset&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;response_model_exclude_unset,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    response_model_exclude_defaults&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;response_model_exclude_defaults,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    response_model_exclude_none&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;response_model_exclude_none,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    include_in_schema&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;include_in_schema,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    response_class&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;response_class,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    name&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;name,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    callbacks&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;callbacks,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    openapi_extra&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;openapi_extra,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    generate_unique_id_function&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;generate_unique_id_function,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We actually snuck in another two features into this example: how did we only
pass five arguments into a function that has 23 parameters?&lt;/p&gt;
&lt;h2 id=&quot;optional-andor-default-arguments&quot;&gt;Optional and/or Default arguments&lt;/h2&gt;
&lt;p&gt;As the name implies, optional arguments is a feature where you can choose to not pass in an argument,
and default arguments lets you set a default when an argument is not passed.&lt;/p&gt;
&lt;p&gt;To go back to that example:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;@app.get&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;    &amp;quot;/me&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    response_model&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;UserOut, &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    status_code&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;200&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    tags&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&amp;quot;Users&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;],&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    summary&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&amp;quot;Get current user profile&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; get_current_user&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;():&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We only passed in five of the 22 possible arguments. If we had to pass all 22 every time, that would
be extremely verbose. So by declaring defaults for some parameters, we can leave them off of the call
site, and not pass arguments for them, and get the defaults instead. We saw this in the Ruby:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;ruby&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;# its definition in Rails&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; redirect_to&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(options &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {}, response_options &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {})&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The &lt;code&gt;= {}&lt;/code&gt; are defaults for &lt;code&gt;options&lt;/code&gt; and &lt;code&gt;response_options&lt;/code&gt;: they’re an empty hash map.&lt;/p&gt;
&lt;p&gt;You’ll often find optional and default arguments come together: after all, if you don’t pass
an argument in, what should the value of that parameter be? If your language has some sort of
null value, that can be one solution, and it can feel like optional arguments without default
arguments.&lt;/p&gt;
&lt;p&gt;But you can truly get one without the other with our next feature, function overloading:&lt;/p&gt;
&lt;h2 id=&quot;function-overloading&quot;&gt;Function Overloading&lt;/h2&gt;
&lt;p&gt;Languages that support function overloading allow you to define multiple
functions with the same name, but different signatures. Which function gets
invoked depends on which arguments you pass. This lets us truly have optional
arguments without default arguments. In Java:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;java&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;// Version 1: Requires both arguments&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;void&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; connect&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(String url, &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;int&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; timeout) { ... }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;// Version 2: Timeout is optional to the caller, and handled internally&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;void&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; connect&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(String url) {  ... }&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here, if you pass in a timeout, you get the first function, and if you don’t,
you get the second. Instead of null, the parameter just doesn’t exist at all.&lt;/p&gt;
&lt;p&gt;This is a specific form of something called “function dispatch,” which basically
means “hey when a function is invoked, what &lt;em&gt;exactly&lt;/em&gt; gets called?” There are a
&lt;em&gt;lot&lt;/em&gt; of different ways to do this, and I don’t want this post to get into all
of that right now, but there is a multitude of possibilities here: static vs
dynamic, single vs multiple, predicate dispatch, pattern matching dispatch,
prototype based dispatch… maybe I’ll write a post about that someday too.&lt;/p&gt;
&lt;p&gt;So, what are the pros and cons here?&lt;/p&gt;
&lt;h2 id=&quot;these-features-make-me-uneasy&quot;&gt;These features make me uneasy&lt;/h2&gt;
&lt;p&gt;As I said above, Rust doesn’t support any of these three features right now. And
they have been a persistent request from the community for years. &lt;a href=&quot;https://github.com/rust-lang/rfcs/issues/323&quot;&gt;Here&lt;/a&gt; is
a 12 year old GitHub issue about this support, and it even includes something we
didn’t talk about, “variable arity argument lists.”&lt;/p&gt;
&lt;p&gt;That gets me to the first thing that I don’t like about these features: there
are a &lt;em&gt;lot&lt;/em&gt; of them. And they are all intertwined. As we mentioned before, if
you have optional arguments, you probably want default arguments. If you have
named parameters, do you want to support &lt;em&gt;only&lt;/em&gt; named parameters, or do you want
to support both? It’s so tempting to just support all of them, and then you’ve
added a huge mountain of complexity.&lt;/p&gt;
&lt;p&gt;In Rust right now, you have to write multiple functions with slightly different
names:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;rust&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;// a new empty vector&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;let&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; v &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; Vec&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;new&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;// one with a set capacity&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;let&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; v &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; Vec&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;with_capacity&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;5&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For the simple cost of “write two different names for your functions,” you get
to keep the rules very simple: there is one function definition, and you invoke
it by name. Done. Would it be nice to be able to say all of these:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;rust&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;let&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; v &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; Vec&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;new&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;let&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; v &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; Vec&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;new&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;5&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;let&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; v &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; Vec&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;new&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(capacity&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 5&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Sure, maybe. But the cost feels very, very high to me. If you’re used to these
features, maybe it doesn’t seem that high, but I have a Ruby tattoo on my body.
I’ve seen some shit. And so I’ve grown to enjoy Rust’s simplicity in this area.
Yes, if you have a function with tons of parameters, you may need to write a
builder instead, and that comes with its own form of verbosity:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;rust&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;// if Vec had a builder&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;let&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; v &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; Vec&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;new&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    .&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;with_capacity&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;5&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    .&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;build&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;// all of the code you have to write to make the builder elided&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;But the language itself stays simple, and the rules are easy. For a language
that’s already perceived as complex, this has always felt right to me. And that’s
why I’ve pushed back against the various proposals to extend Rust in this way all
of these years.&lt;/p&gt;
&lt;p&gt;But recently, I changed my opinion on one of these features, and one alone, and
I would consider it okay if Rust gained them. Maybe. Also, it’s important to note
that I haven’t worked on Rust in years, and so my opinions are kind of irrelevant,
but whatever: it’s my blog, this is what opinions are for.&lt;/p&gt;
&lt;h2 id=&quot;im-okay-with-named-parameters-now&quot;&gt;I’m okay with named parameters now&lt;/h2&gt;
&lt;p&gt;I think Rust could be okay with named parameters, but &lt;em&gt;not&lt;/em&gt; optional or default
ones. And what changed my opinion is coding agents, actually. I’m sorry, maybe
you’re sick of me talking about AI, but hear me out.&lt;/p&gt;
&lt;p&gt;One of my beefs with named parameters, as mentioned above, is verbosity. But
what you gain for that verbosity is clarity. I don’t think that verbosity and
clarity are always the same thing; I like &lt;code&gt;{}&lt;/code&gt; rather than &lt;code&gt;do&lt;/code&gt;/&lt;code&gt;end&lt;/code&gt;, and find
it more readable, personally. But let’s take this function from the &lt;code&gt;image&lt;/code&gt; crate:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;rust&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;// definition&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;pub&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; fn&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; crop_imm&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;I&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; GenericImageView&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;(&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    image&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; &amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;I&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    x&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; u32&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    y&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; u32&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    width&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; u32&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    height&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; u32&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; SubImage&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;I&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt; { &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;...&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;// calling it&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;let&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; cropped &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; image&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;imageops&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;crop_imm&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;img, &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;10&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;20&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;200&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;100&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;// if we had named arguments&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;let&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; cropped &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; image&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;imageops&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;crop_imm&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    image&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; &amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;img,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    x&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 10&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    y&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 20&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    width&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 200&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    height&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 100&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This does really increase readability, no question about it. But for me, typing
all of that out just isn’t really super worth the squeeze. But when Claude is
gonna write it? I care a lot less. And the readability advantage for humans is
even stronger for agents: the extra clarity of the text inline seems to (I
haven’t run real evals on this yet…) be more helpful and use less tokens and
calls when looking at the actual call site. If an agent were reading that named
example above, it could tell that &lt;code&gt;10&lt;/code&gt; is the &lt;code&gt;x&lt;/code&gt; value without having to go
look up the function signature itself. “What’s good for humans is true for
agents” strikes again.&lt;/p&gt;
&lt;p&gt;This is also why I’m still against optional arguments: they deliberately
&lt;em&gt;hide&lt;/em&gt; what is being passed in to the function, and obscure clarity at the call
site. What’s nice about them is that you have to type less. But I’m not typing
myself anymore. So the benefit just isn’t there, but the drawbacks are. This
also doesn’t solve the verbosity side of passing &lt;code&gt;foo=foo&lt;/code&gt; in our FastAPI
example, it is still redundant. But one part of the downsides have been
ameliorated.&lt;/p&gt;
&lt;p&gt;Notably, all of this reasoning also applies to the builder pattern, and it’s why
I try to use builders sparingly in Rust. It can emulate named arguments, which
is good, but it can also emulate optional/default/variable arguments, which is
bad.  The juice is worth the squeeze sometimes, but not all the time, and
probably not even the majority of the time.&lt;/p&gt;
&lt;p&gt;So we’ve ameliorated the largest downside, but get to keep the largest upside.
That seems good. But even if we like the feature, there are still lots of
practical concerns with Rust specifically that make it not a slam-dunk to add
them to the language.&lt;/p&gt;
&lt;h2 id=&quot;theres-tons-of-practical-issues-though&quot;&gt;There’s tons of practical issues though&lt;/h2&gt;
&lt;p&gt;Now, “is this feature good in the abstract” is very different from “should this
feature” be implemented? There are a &lt;em&gt;lot&lt;/em&gt; of open questions and drawbacks to
implementing named parameters. A simple one is that you don’t get rid of all of
those previous functions, &lt;code&gt;with_capacity&lt;/code&gt; will exist forever. That’s a
relatively minor downside to some of the harder problems.&lt;/p&gt;
&lt;p&gt;First, strictly speaking Rust parameters aren’t names, they’re patterns. A
name is a simple pattern, but you can get more complex:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;rust&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;fn&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; foo&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;((x, y)&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;i32&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;i32&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)) {&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This parameter doesn’t have a name, it’s a pattern that introduces two bindings.
You could come up with some syntax that gives things external names vs internal
names, but there’s that complexity revealing its head again.&lt;/p&gt;
&lt;p&gt;What happens when functions become values? I can write this today:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;rust&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;fn&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; resize&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(width&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; u32&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, height&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; u32&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;    // body elided&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;fn&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; offset&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(dx&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; u32&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, dy&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; u32&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;    // body elided&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;let&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; f&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; fn&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;u32&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;u32&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; resizing { resize } &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;else&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; { offset };&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;What name do we use for &lt;code&gt;f&lt;/code&gt;’s parameters? They can be named different things.
Does this become an error? What names can you use when invoking &lt;code&gt;f&lt;/code&gt;? Making this
more complicated, Rust actually will accept this code right now:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;rust&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;type&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; Callback&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; fn&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(width&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; u32&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, height&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; u32&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;fn&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; f&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(g&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; Callback&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) {}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;fn&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; bar&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(x&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; u32&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, y&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; u32&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) {}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;fn&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; main&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;    f&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(bar) ;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The names in &lt;code&gt;Callback&lt;/code&gt; are just documentation, as you can see they’re not
required.  Does this become an error? Do we require &lt;code&gt;bar&lt;/code&gt; to change its names?
The same goes for trait definitions, actually:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;rust&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;trait&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; Writer&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    fn&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; write&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;amp;mut&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; self&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, data&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; &amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;u8&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;]);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;struct&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; Sink&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;impl&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; Writer&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; for&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; Sink&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    fn&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; write&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;amp;mut&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; self&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, bytes&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; &amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;u8&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;]) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;        // body elided&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Is this an error? Is it okay?&lt;/p&gt;
&lt;p&gt;Here’s another problem: evaluation order.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;rust&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;fn&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; consume&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(data&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; Vec&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;u8&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;, length&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; usize&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;    // body elided&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Right now, Rust always evaluates parameters from left to right at the call site.
So if we use the named version:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;rust&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;fn&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; consume&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(data&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; Vec&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;u8&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;, length&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; usize&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;    // body elided&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;fn&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; consume2&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(length&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; usize&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, data&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; Vec&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;u8&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;    // body elided&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;fn&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; main&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    let&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; data &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; vec!&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;3&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;];&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;    // this is an error, borrow after move&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;    consume&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(data, data&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;len&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;());&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;    // this is okay&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;    consume2&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(data&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;len&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(), data);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;    // does this compile or not?&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;    consume&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(length&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; data&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;len&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(), data&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; data);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If we keep left to right evaluation order according to the definition, but let
you use named values in any order, suddenly some orders at the call site compile
and some orders do not.  Do we change evaluation order to do whatever compiles?
That feels very dangerous and confusing.&lt;/p&gt;
&lt;p&gt;Rust does let you do this with struct fields:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;rust&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;struct&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; Args&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    data&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; Vec&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;u8&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    length&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; usize&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;fn&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; main&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    let&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; data &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; vec!&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;3&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;];&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;    // works&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    let&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; args &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; Args&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        length&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; data&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;len&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        data,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    };&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;    // doesn&amp;#39;t&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    let&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; args &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; Args&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        data,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        length&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; data&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;len&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    };&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is one reason why a lot of proposals for named arguments try to unify them
with structs. As I said before, not insurmountable, just things that need to be
sorted.&lt;/p&gt;
&lt;p&gt;Another small thing is a compatibility hazard: if we start naming parameters,
renaming them breaks callers. Is that okay? Could you introduce aliases to help
with this? That’s more complexity…&lt;/p&gt;
&lt;p&gt;These are just some of the problems that come up in the design space, and this
post is getting long, so I’ll leave it at this for now. But proposals for doing
this have to engage with all of this and more, which is why language design is
difficult.&lt;/p&gt;
&lt;h2 id=&quot;in-conclusion&quot;&gt;In conclusion&lt;/h2&gt;
&lt;p&gt;I like to think that I change my opinions over time as the world or my
understanding of it changes. So I thought it might be interesting to share a way
in which an opinion that I’ve held for over a decade has changed a bit lately.
I’m still not sure if named parameters are right for Rust, but I’m at least
somewhat open to the idea these days. We’ll see what the language team decides
if anyone does decide to keep trying to push this forward. And people do, for
example, I am writing this in part because I saw &lt;a href=&quot;https://botahamec.dev/named-optional-args&quot;&gt;this post&lt;/a&gt; go by today.
This post isn’t intended to be support or a rebuttal of it, I actually didn’t
even read it yet, it’s just that I’ve been thinking about this a lot lately
(while working on &lt;a href=&quot;https://rue-lang.dev/&quot;&gt;Rue&lt;/a&gt;) and seeing that go by pushed me to write some of
the thoughts down. You should probably go check it out, as it’s an actual
proposal in this space and this post is more of an exploration of the general
idea and my own thoughts on it.&lt;/p&gt;
&lt;hr/&gt;
&lt;p&gt;Here’s my post about this post on BlueSky:&lt;/p&gt;
&lt;bluesky-post src=&quot;at://did:plc:3danwc67lo7obz2fmdg6jxcr/app.bsky.feed.post/3mw2ahu3pv22q&quot; data-pagefind-ignore=&quot;true&quot;&gt; &lt;div class=&quot;bluesky-embed s-3olstj&quot;&gt;&lt;div class=&quot;highlighted-post s-hik11q&quot;&gt;&lt;div class=&quot;meta s-hik11q&quot;&gt;&lt;a href=&quot;https://bsky.app/profile/did:plc:3danwc67lo7obz2fmdg6jxcr&quot; target=&quot;_blank&quot; class=&quot;avatar-wrapper s-hik11q&quot;&gt;&lt;img loading=&quot;lazy&quot; src=&quot;https://cdn.bsky.app/img/avatar/plain/did:plc:3danwc67lo7obz2fmdg6jxcr/bafkreidffwgsdli2xp56t3kfemk7bryow3mygu7zbvgcsxgsu3ntnp4hwm&quot; alt=&quot;&quot; class=&quot;avatar s-hik11q&quot;/&gt;&lt;/a&gt; &lt;a href=&quot;https://bsky.app/profile/did:plc:3danwc67lo7obz2fmdg6jxcr&quot; target=&quot;_blank&quot; class=&quot;name-wrapper s-hik11q&quot;&gt;&lt;bdi class=&quot;display-name-wrapper s-hik11q&quot;&gt;&lt;span class=&quot;display-name s-hik11q&quot;&gt;Steve Klabnik&lt;/span&gt;&lt;/bdi&gt; &lt;span class=&quot;handle s-hik11q&quot;&gt;@steveklabnik.com&lt;/span&gt;&lt;/a&gt; &lt;svg class=&quot;logo s-hik11q&quot; fill=&quot;none&quot; viewBox=&quot;0 0 320 286&quot;&gt;&lt;path fill=&quot;#0A7AFF&quot; d=&quot;M69.364 19.146c36.687 27.806 76.147 84.186 90.636 114.439 14.489-30.253 53.948-86.633 90.636-114.439C277.107-.917 320-16.44 320 32.957c0 9.865-5.603 82.875-8.889 94.729-11.423 41.208-53.045 51.719-90.071 45.357 64.719 11.12 81.182 47.953 45.627 84.785-80 82.874-106.667-44.333-106.667-44.333s-26.667 127.207-106.667 44.333c-35.555-36.832-19.092-73.665 45.627-84.785-37.026 6.362-78.648-4.149-90.071-45.357C5.603 115.832 0 42.822 0 32.957 0-16.44 42.893-.917 69.364 19.147Z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/div&gt;  &lt;p class=&quot;rich-text is-large s-1lecfnd&quot;&gt;Arguing about arguments

&lt;a target=&quot;_blank&quot; href=&quot;https://steveklabnik.com/writing/arguing-about-arguments/&quot; rel=&quot;noopener nofollow&quot; class=&quot;link s-1lecfnd&quot;&gt;steveklabnik.com/writing/argu...&lt;/a&gt;&lt;/p&gt; &lt;div class=&quot;embeds s-azdpbr&quot;&gt;&lt;a target=&quot;_blank&quot; href=&quot;https://steveklabnik.com/writing/arguing-about-arguments/&quot; rel=&quot;noopener noreferrer nofollow&quot; class=&quot;external-embed s-rtbqd8&quot;&gt;&lt;img loading=&quot;lazy&quot; src=&quot;https://cdn.bsky.app/img/feed_thumbnail/plain/did:plc:3danwc67lo7obz2fmdg6jxcr/bafkreigpeqitvd6az3jx55koev3nbbllzxb6moswv6erkvptevqphh553e&quot; alt=&quot;&quot; class=&quot;thumbnail s-rtbqd8&quot;/&gt; &lt;div class=&quot;meta s-rtbqd8&quot;&gt;&lt;p class=&quot;title s-rtbqd8&quot;&gt;Arguing about arguments&lt;/p&gt; &lt;p class=&quot;description s-rtbqd8&quot;&gt;Here’s some Rust code: // define a function fn foo (x : i32 , y : i32 ) -&gt; i32 { // body elided } // call it let z = foo ( 5 , 6 ); In programming language jargon, we call x and y parameters and 5 and 6 arguments . Rust does not have many fancy features related to parameters and…&lt;/p&gt; &lt;div class=&quot;domain s-rtbqd8&quot;&gt;&lt;svg class=&quot;icon&quot; fill=&quot;none&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path stroke=&quot;currentColor&quot; stroke-linecap=&quot;round&quot; stroke-width=&quot;2&quot; d=&quot;m4.172 8.07 3.94 2.957.977-1.941 3.887-.978 1.15-4.6M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Zm-6.078 4.865.973-1.946-2.869-1.928-1.89-.12-1.08 1.075 1.947 2.919h2.919Z&quot;&gt;&lt;/path&gt;&lt;/svg&gt; &lt;span class=&quot;domain-name&quot;&gt;steveklabnik.com&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/a&gt;&lt;/div&gt; &lt;time datetime=&quot;2026-09-21T17:30:35.997Z&quot; class=&quot;date s-hik11q&quot;&gt;September 21, 2026 at 5:30 PM&lt;/time&gt; &lt;div class=&quot;stats s-hik11q&quot;&gt;&lt;span class=&quot;stat s-hik11q&quot; title=&quot;92 likes&quot;&gt;&lt;svg class=&quot;icon&quot; fill=&quot;none&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; d=&quot;M12 5.768c6.162-6.25 16.725 5.358 0 14.732C-4.725 11.126 5.838-.482 12 5.768Z&quot;&gt;&lt;/path&gt;&lt;/svg&gt; &lt;span&gt;92&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;stat s-hik11q&quot; title=&quot;11 reposts&quot;&gt;&lt;svg class=&quot;icon&quot; fill=&quot;none&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path stroke=&quot;currentColor&quot; stroke-linecap=&quot;square&quot; stroke-width=&quot;2&quot; d=&quot;m17 3 3 3-3 3M7 21l-3-3 3-3m-2 3h15v-5M4 11V6h15&quot;&gt;&lt;/path&gt;&lt;/svg&gt; &lt;span&gt;11&lt;/span&gt;&lt;/span&gt; &lt;div class=&quot;gap s-hik11q&quot;&gt;&lt;/div&gt; &lt;a href=&quot;https://bsky.app/profile/did:plc:3danwc67lo7obz2fmdg6jxcr/post/3mw2ahu3pv22q&quot; target=&quot;_blank&quot; class=&quot;permalink s-hik11q&quot;&gt;&lt;span&gt;Read 21 replies on Bluesky&lt;/span&gt;&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt; &lt;/bluesky-post&gt;</content:encoded></item><item><title>Thirteen years of Rust and the birth of Rue</title><link>https://steveklabnik.com/writing/thirteen-years-of-rust-and-the-birth-of-rue/</link><guid isPermaLink="true">https://steveklabnik.com/writing/thirteen-years-of-rust-and-the-birth-of-rue/</guid><description>I started using Rust on December 21, 2012. It’s now December 22, 2025. That’s a long time. I don’t have a ton of thoughts about Rust to share today, like I thought I might. I program in the language regularly, it’s nice, I prefer it to all others. I have my beefs and my regrets,…</description><pubDate>Sun, 21 Dec 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I started using Rust on December 21, 2012. It’s now December 22, 2025. That’s a
long time.&lt;/p&gt;
&lt;p&gt;I don’t have a ton of thoughts about Rust to share today, like I thought I
might. I program in the language regularly, it’s nice, I prefer it to all
others. I have my beefs and my regrets, like any real project, but for the most
part, I am pretty happy these days. To be honest, after a pretty rough last few
years, that’s been the theme of 2025: I’m pretty happy these days.&lt;/p&gt;
&lt;p&gt;I have long been wondering if I should try and make my own language. I really
like them! That’s part of why I got involved in Ruby and then Rust in the first
place! But I’ll be turning 40 in a month, and I barely have time for things
anymore. So I had kind of put that on the back burner.&lt;/p&gt;
&lt;p&gt;But one thing that 2025 changed: I went from an AI skeptic to writing most of my
code with Claude. I’m still a bit unsure about LLMs outside of programming, but
as a software development tool, I’ve found them finally to be good enough to be
legitimately useful. Your mileage may vary, I’m not really going to try and tell
you that they should be for you, only that they are for me.&lt;/p&gt;
&lt;p&gt;And so, earlier this year, I embarked on starting my own little language project.
I decided to call it “Rue”, becuase:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;It has to start with Ru, duh. I did Ruby and then Rust, so my hands are
basically tied here…&lt;/li&gt;
&lt;li&gt;It has a negative connotation, “to rue the day”, like Rust has a possible
negative interpretation.&lt;/li&gt;
&lt;li&gt;It has a nature connotation, a
&lt;a href=&quot;https://en.wikipedia.org/wiki/Ruta_graveolens&quot;&gt;Rue&lt;/a&gt;, like Rust has a possible
fungi connotation.&lt;/li&gt;
&lt;li&gt;It’s short.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;I have also been wondering for a few years if you can build a language without
financial backing and a team. I think LLMs might change that equation. Yes,
Claude costs money, but I mean like, you don’t need to do what Mozilla did and
drop seven or eight figures worth of money on a development team to make
meaningful progress. And since I don’t have a ton of personal time these days,
what better way to test that than to actually give it a go.&lt;/p&gt;
&lt;p&gt;Anyway, I got into it, and kind of made a mess of the first go. And then I had a
tremendously busy fall, and had to put things by the wayside.&lt;/p&gt;
&lt;p&gt;But this week, I had some time after work, and decided to start over. And I’m
much more happy with how it’s going this time. So I’ve decided it’s time to at
least let the world know I’m working on it, just because why not.&lt;/p&gt;
&lt;p&gt;I don’t expect it to grow to anything more than my hobby project, but then
again, that’s also true of Rasmus and Graydon and a ton of other language
authors, so, never say never. But that’s not an explicit goal here. I reserve
the right to just stop working on this when I think it’s not fun. I’m not trying
to build a community or even add committers. It’s just something for me for fun.&lt;/p&gt;
&lt;p&gt;You can find Rue over at &lt;a href=&quot;https://rue-lang.dev/&quot;&gt;https://rue-lang.dev/&lt;/a&gt; if you want to check it out.
There’s a blog with an RSS feed. I may blog there, I may not. But I’ll probably
keep it over there more than over here, in general.&lt;/p&gt;
&lt;p&gt;I’m not saying that Claude is amazing, or that this code is fantastic, or
anything. The language is still very janky. I’m sure I have codegen bugs. It’s
missing basic features. It is very, very much a work in progress.&lt;/p&gt;
&lt;p&gt;Thank you to everyone for making 2025 a nice year. There’s a lot of terrible
things in this world right now, but I’m more hopeful than ever, personally.
I hope to still be writing Rust in another ten years, and maybe even writing
some Rue. We’ll see :)&lt;/p&gt;
&lt;hr/&gt;
&lt;p&gt;Here’s my post about this post on BlueSky:&lt;/p&gt;
&lt;bluesky-post src=&quot;at://did:plc:3danwc67lo7obz2fmdg6jxcr/app.bsky.feed.post/3majjeqo4ik2t&quot; data-pagefind-ignore=&quot;true&quot;&gt; &lt;div class=&quot;bluesky-embed s-3olstj&quot;&gt;&lt;div class=&quot;highlighted-post s-hik11q&quot;&gt;&lt;div class=&quot;meta s-hik11q&quot;&gt;&lt;a href=&quot;https://bsky.app/profile/did:plc:3danwc67lo7obz2fmdg6jxcr&quot; target=&quot;_blank&quot; class=&quot;avatar-wrapper s-hik11q&quot;&gt;&lt;img loading=&quot;lazy&quot; src=&quot;https://cdn.bsky.app/img/avatar/plain/did:plc:3danwc67lo7obz2fmdg6jxcr/bafkreidffwgsdli2xp56t3kfemk7bryow3mygu7zbvgcsxgsu3ntnp4hwm&quot; alt=&quot;&quot; class=&quot;avatar s-hik11q&quot;/&gt;&lt;/a&gt; &lt;a href=&quot;https://bsky.app/profile/did:plc:3danwc67lo7obz2fmdg6jxcr&quot; target=&quot;_blank&quot; class=&quot;name-wrapper s-hik11q&quot;&gt;&lt;bdi class=&quot;display-name-wrapper s-hik11q&quot;&gt;&lt;span class=&quot;display-name s-hik11q&quot;&gt;Steve Klabnik&lt;/span&gt;&lt;/bdi&gt; &lt;span class=&quot;handle s-hik11q&quot;&gt;@steveklabnik.com&lt;/span&gt;&lt;/a&gt; &lt;svg class=&quot;logo s-hik11q&quot; fill=&quot;none&quot; viewBox=&quot;0 0 320 286&quot;&gt;&lt;path fill=&quot;#0A7AFF&quot; d=&quot;M69.364 19.146c36.687 27.806 76.147 84.186 90.636 114.439 14.489-30.253 53.948-86.633 90.636-114.439C277.107-.917 320-16.44 320 32.957c0 9.865-5.603 82.875-8.889 94.729-11.423 41.208-53.045 51.719-90.071 45.357 64.719 11.12 81.182 47.953 45.627 84.785-80 82.874-106.667-44.333-106.667-44.333s-26.667 127.207-106.667 44.333c-35.555-36.832-19.092-73.665 45.627-84.785-37.026 6.362-78.648-4.149-90.071-45.357C5.603 115.832 0 42.822 0 32.957 0-16.44 42.893-.917 69.364 19.147Z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/div&gt;  &lt;p class=&quot;rich-text is-large s-1lecfnd&quot;&gt;Thirteen years of &lt;a target=&quot;_blank&quot; href=&quot;https://bsky.app/hashtag/rustlang&quot; class=&quot;hashtag s-1lecfnd&quot;&gt;#rustlang&lt;/a&gt; and the birth of &lt;a target=&quot;_blank&quot; href=&quot;https://bsky.app/hashtag/ruelang&quot; class=&quot;hashtag s-1lecfnd&quot;&gt;#ruelang&lt;/a&gt; &lt;a target=&quot;_blank&quot; href=&quot;https://steveklabnik.com/writing/thirteen-years-of-rust-and-the-birth-of-rue/&quot; rel=&quot;noopener nofollow&quot; class=&quot;link s-1lecfnd&quot;&gt;steveklabnik.com/writing/thir...&lt;/a&gt;&lt;/p&gt; &lt;div class=&quot;embeds s-azdpbr&quot;&gt;&lt;a target=&quot;_blank&quot; href=&quot;https://steveklabnik.com/writing/thirteen-years-of-rust-and-the-birth-of-rue/&quot; rel=&quot;noopener noreferrer nofollow&quot; class=&quot;external-embed s-rtbqd8&quot;&gt; &lt;div class=&quot;meta s-rtbqd8&quot;&gt;&lt;p class=&quot;title s-rtbqd8&quot;&gt;Thirteen years of Rust and the birth of Rue&lt;/p&gt; &lt;p class=&quot;description s-rtbqd8&quot;&gt;Blog post: Thirteen years of Rust and the birth of Rue by Steve Klabnik&lt;/p&gt; &lt;div class=&quot;domain s-rtbqd8&quot;&gt;&lt;svg class=&quot;icon&quot; fill=&quot;none&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path stroke=&quot;currentColor&quot; stroke-linecap=&quot;round&quot; stroke-width=&quot;2&quot; d=&quot;m4.172 8.07 3.94 2.957.977-1.941 3.887-.978 1.15-4.6M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Zm-6.078 4.865.973-1.946-2.869-1.928-1.89-.12-1.08 1.075 1.947 2.919h2.919Z&quot;&gt;&lt;/path&gt;&lt;/svg&gt; &lt;span class=&quot;domain-name&quot;&gt;steveklabnik.com&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/a&gt;&lt;/div&gt; &lt;time datetime=&quot;2025-12-21T20:05:35.682Z&quot; class=&quot;date s-hik11q&quot;&gt;December 21, 2025 at 8:05 PM&lt;/time&gt; &lt;div class=&quot;stats s-hik11q&quot;&gt;&lt;span class=&quot;stat s-hik11q&quot; title=&quot;111 likes&quot;&gt;&lt;svg class=&quot;icon&quot; fill=&quot;none&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; d=&quot;M12 5.768c6.162-6.25 16.725 5.358 0 14.732C-4.725 11.126 5.838-.482 12 5.768Z&quot;&gt;&lt;/path&gt;&lt;/svg&gt; &lt;span&gt;111&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;stat s-hik11q&quot; title=&quot;10 reposts&quot;&gt;&lt;svg class=&quot;icon&quot; fill=&quot;none&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path stroke=&quot;currentColor&quot; stroke-linecap=&quot;square&quot; stroke-width=&quot;2&quot; d=&quot;m17 3 3 3-3 3M7 21l-3-3 3-3m-2 3h15v-5M4 11V6h15&quot;&gt;&lt;/path&gt;&lt;/svg&gt; &lt;span&gt;10&lt;/span&gt;&lt;/span&gt; &lt;div class=&quot;gap s-hik11q&quot;&gt;&lt;/div&gt; &lt;a href=&quot;https://bsky.app/profile/did:plc:3danwc67lo7obz2fmdg6jxcr/post/3majjeqo4ik2t&quot; target=&quot;_blank&quot; class=&quot;permalink s-hik11q&quot;&gt;&lt;span&gt;Read 19 replies on Bluesky&lt;/span&gt;&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt; &lt;/bluesky-post&gt;</content:encoded></item><item><title>Is Rust faster than C?</title><link>https://steveklabnik.com/writing/is-rust-faster-than-c/</link><guid isPermaLink="true">https://steveklabnik.com/writing/is-rust-faster-than-c/</guid><description>Someone on Reddit recently asked: What would make a Rust implementation of something faster than a C implementation, all things being the same? I think this is a great and interesting question! It’s really tough because it ultimately relies on what exactly you mean by “all things…</description><pubDate>Mon, 09 Jun 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Someone on Reddit recently asked:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;What would make a Rust implementation of something faster than a C
implementation, all things being the same?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I think this is a great and interesting question! It’s really tough because it
ultimately relies on what exactly you mean by “all things being the same.” And I
think this is something that makes it hard to compare languages.&lt;/p&gt;
&lt;p&gt;Here’s some ways in which you can argue that things are “the same” but also,
that they’re not, and what they imply for runtime performance.&lt;/p&gt;
&lt;h2 id=&quot;inline-assembly&quot;&gt;Inline Assembly&lt;/h2&gt;
&lt;p&gt;Rust has inline assembly built into the language. C has inline assembly as a
very common compiler extension, to the degree where saying it’s not part of the
language is an arguable nitpick.&lt;/p&gt;
&lt;p&gt;Here’s an example in Rust:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;rust&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;use&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; std&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;arch&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;asm;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;#[&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;unsafe&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(no_mangle)]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;pub&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; fn&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; rdtsc&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;() &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; u64&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    let&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; lo&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;  u32&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    let&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; hi&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;  u32&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    unsafe&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;        asm!&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;            &amp;quot;rdtsc&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;            out&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&amp;quot;eax&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) lo,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;            out&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&amp;quot;edx&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) hi,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;            options&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(nomem, nostack, preserves_flags),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        );&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    ((hi &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;as&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; u64&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 32&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;|&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (lo &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;as&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; u64&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This reads the time stamp counter with &lt;code&gt;rdtsc&lt;/code&gt;, and returns its value.&lt;/p&gt;
&lt;p&gt;Here’s the example in C:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;c&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;#include&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &amp;lt;stdint.h&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;uint64_t&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; rdtsc&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;void&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    uint32_t&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; lo, hi;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    __asm__&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; _&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;_volatile__&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;        &amp;quot;rdtsc&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        : &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&amp;quot;=a&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(lo), &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&amp;quot;=d&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(hi)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    );&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    return&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; ((&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;uint64_t&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)hi &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 32&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;|&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; lo;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;These (under &lt;code&gt;-0&lt;/code&gt; in both rustc &lt;code&gt;1.87.0&lt;/code&gt; and clang &lt;code&gt;20.1.0&lt;/code&gt;) produce the same
assembly:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;asm&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;rdtsc&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        rdtsc&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        shl&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;     rdx&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;32&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        mov&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;     eax&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;eax&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        or&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;      rax&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;rdx&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        ret&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here’s a link on Godbolt: &lt;a href=&quot;https://godbolt.org/z/f7K8cfnx7&quot;&gt;https://godbolt.org/z/f7K8cfnx7&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Does this count? I don’t know. I don’t think it really speaks to the question
asked, but it is one way to answer the question.&lt;/p&gt;
&lt;h2 id=&quot;similar-code-different-results&quot;&gt;Similar code, different results&lt;/h2&gt;
&lt;p&gt;Rust and C can have different semantics for similar code. Here’s a struct in
Rust:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;rust&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;struct&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; Rust&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    x&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; u32&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    y&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; u64&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    z&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; u32&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here’s “the same” struct in C:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;c&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;struct&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; C {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    uint32_t&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; x;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    uint64_t&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; y;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    uint32_t&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; z;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;};&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In Rust, this struct is 16 bytes (on x86_64, again) and in C, it is 24. This is
because Rust is free to reorder the fields to optimize for size, while C
is not.&lt;/p&gt;
&lt;p&gt;Is this the same, or different?&lt;/p&gt;
&lt;p&gt;In C, you can re-order the fields to get the same size. In Rust, you can write
&lt;code&gt;#[repr(C)]&lt;/code&gt; to get the same layout as C. Does this mean we should have written
different Rust or different C to get “the same” thing?&lt;/p&gt;
&lt;h2 id=&quot;social-factors&quot;&gt;Social Factors&lt;/h2&gt;
&lt;p&gt;Some people have reported that, thanks to Rust’s checks, they are more willing
to write code that’s a bit more dangerous than in the equivalent C (or C++),
where they’d do a bit more copying to play it a bit safer. This would be “the
same” in the sense of the same devs on the same project, but the code would be
different, due to judgement calls. You can make an argument that that’s not the
same, but is different too.&lt;/p&gt;
&lt;p&gt;An example of this from a long time ago is the Stylo project. Mozilla tried to
parallelize Firefox’s style layout twice in C++, and both times the project
failed. The multithreading was too tricky to get right. The third time, they
used Rust, and managed to ship. This is the same project, (though not the same
programmers, I believe) by the same organization, but one was possible and one
was not. Is that “the same”? In some senses, but not in others.&lt;/p&gt;
&lt;p&gt;This also goes for a similar question: assuming we have a junior developer
writing Rust, and also writing C, for the same task. Are we going to get faster
code in one or the other? This controls for ability, but not for the same code.
Is that “the same”? I don’t know. What about an expert in each language, someone
who knows Rust super well but doesn’t know C, and vice versa, being given the
same task? Is that different than a junior, or an “average” developer?&lt;/p&gt;
&lt;h2 id=&quot;compile-time-vs-runtime&quot;&gt;Compile time vs runtime?&lt;/h2&gt;
&lt;p&gt;Another redditor asks:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I’m not Rust expert, but aren’t most (all?) of the safety checks compile time
checks? They shouldn’t have any runtime impact.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;A great question! Part of this is another example of defaults being different.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;array[0]&lt;/code&gt; is valid in both languages.&lt;/p&gt;
&lt;p&gt;In Rust, there’s a bounds check at runtime. In C, there is not. Does this mean
that they’re the same? In Rust, I could write &lt;code&gt;array.get_unchecked(0)&lt;/code&gt;, and get
C’s semantics. In C, I could write a bounds check to get Rust’s semantics. Are
any of those “the same”?&lt;/p&gt;
&lt;p&gt;In Rust, that check may be optimized away, if the compiler can prove it’s safe.
In C, if we wrote the bounds check by hand, the check may be optimized away, if
the compiler can prove it’s safe. Are any of those “the same”?&lt;/p&gt;
&lt;p&gt;They aren’t wrong that a lot of Rust’s safety checks are at compile time. But
some are at runtime. But this raises another interesting question: That compile-time
check may cause you to write different code for the same task as in C. A common
example is using indices rather than pointers. That may mean that the generated
code performs differently. Is that check truly “at compile time”? Technically,
at the micro level, yes. At the engineering level? Possibly not!&lt;/p&gt;
&lt;h2 id=&quot;my-conclusions&quot;&gt;My Conclusions&lt;/h2&gt;
&lt;p&gt;I think the most important part of this question is related to possibility, that
is:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;If we assume C is the ‘fastest language,’ whatever that means.&lt;/li&gt;
&lt;li&gt;Is there any inherent reason why Rust could not do the same things?&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;I think the answer to that is “no,” even ignoring the inline assembly case. So
on that most important, fundamental level, the answer is “there’s no difference
between the two.”&lt;/p&gt;
&lt;p&gt;But we’re not usually talking about that. We’re usually talking about something
in the context of engineering, a specific project, with specific developers,
with specific time constraints, and so on. I think that there are so many
variables that it is difficult to draw generalized conclusions.&lt;/p&gt;
&lt;hr/&gt;
&lt;p&gt;Here’s my post about this post on BlueSky:&lt;/p&gt;
&lt;bluesky-post src=&quot;at://did:plc:3danwc67lo7obz2fmdg6jxcr/app.bsky.feed.post/3lr6xouhoxc2i&quot; data-pagefind-ignore=&quot;true&quot;&gt; &lt;div class=&quot;bluesky-embed s-3olstj&quot;&gt;&lt;div class=&quot;highlighted-post s-hik11q&quot;&gt;&lt;div class=&quot;meta s-hik11q&quot;&gt;&lt;a href=&quot;https://bsky.app/profile/did:plc:3danwc67lo7obz2fmdg6jxcr&quot; target=&quot;_blank&quot; class=&quot;avatar-wrapper s-hik11q&quot;&gt;&lt;img loading=&quot;lazy&quot; src=&quot;https://cdn.bsky.app/img/avatar/plain/did:plc:3danwc67lo7obz2fmdg6jxcr/bafkreidffwgsdli2xp56t3kfemk7bryow3mygu7zbvgcsxgsu3ntnp4hwm&quot; alt=&quot;&quot; class=&quot;avatar s-hik11q&quot;/&gt;&lt;/a&gt; &lt;a href=&quot;https://bsky.app/profile/did:plc:3danwc67lo7obz2fmdg6jxcr&quot; target=&quot;_blank&quot; class=&quot;name-wrapper s-hik11q&quot;&gt;&lt;bdi class=&quot;display-name-wrapper s-hik11q&quot;&gt;&lt;span class=&quot;display-name s-hik11q&quot;&gt;Steve Klabnik&lt;/span&gt;&lt;/bdi&gt; &lt;span class=&quot;handle s-hik11q&quot;&gt;@steveklabnik.com&lt;/span&gt;&lt;/a&gt; &lt;svg class=&quot;logo s-hik11q&quot; fill=&quot;none&quot; viewBox=&quot;0 0 320 286&quot;&gt;&lt;path fill=&quot;#0A7AFF&quot; d=&quot;M69.364 19.146c36.687 27.806 76.147 84.186 90.636 114.439 14.489-30.253 53.948-86.633 90.636-114.439C277.107-.917 320-16.44 320 32.957c0 9.865-5.603 82.875-8.889 94.729-11.423 41.208-53.045 51.719-90.071 45.357 64.719 11.12 81.182 47.953 45.627 84.785-80 82.874-106.667-44.333-106.667-44.333s-26.667 127.207-106.667 44.333c-35.555-36.832-19.092-73.665 45.627-84.785-37.026 6.362-78.648-4.149-90.071-45.357C5.603 115.832 0 42.822 0 32.957 0-16.44 42.893-.917 69.364 19.147Z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/div&gt;  &lt;p class=&quot;rich-text is-large s-1lecfnd&quot;&gt;Is &lt;a target=&quot;_blank&quot; href=&quot;https://bsky.app/hashtag/rustlang&quot; class=&quot;hashtag s-1lecfnd&quot;&gt;#rustlang&lt;/a&gt; faster than C?

&lt;a target=&quot;_blank&quot; href=&quot;https://steveklabnik.com/writing/is-rust-faster-than-c/&quot; rel=&quot;noopener nofollow&quot; class=&quot;link s-1lecfnd&quot;&gt;steveklabnik.com/writing/is-r...&lt;/a&gt;&lt;/p&gt; &lt;div class=&quot;embeds s-azdpbr&quot;&gt;&lt;a target=&quot;_blank&quot; href=&quot;https://steveklabnik.com/writing/is-rust-faster-than-c/&quot; rel=&quot;noopener noreferrer nofollow&quot; class=&quot;external-embed s-rtbqd8&quot;&gt; &lt;div class=&quot;meta s-rtbqd8&quot;&gt;&lt;p class=&quot;title s-rtbqd8&quot;&gt;Is Rust faster than C?&lt;/p&gt; &lt;p class=&quot;description s-rtbqd8&quot;&gt;Blog post: Is Rust faster than C? by Steve Klabnik&lt;/p&gt; &lt;div class=&quot;domain s-rtbqd8&quot;&gt;&lt;svg class=&quot;icon&quot; fill=&quot;none&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path stroke=&quot;currentColor&quot; stroke-linecap=&quot;round&quot; stroke-width=&quot;2&quot; d=&quot;m4.172 8.07 3.94 2.957.977-1.941 3.887-.978 1.15-4.6M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Zm-6.078 4.865.973-1.946-2.869-1.928-1.89-.12-1.08 1.075 1.947 2.919h2.919Z&quot;&gt;&lt;/path&gt;&lt;/svg&gt; &lt;span class=&quot;domain-name&quot;&gt;steveklabnik.com&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/a&gt;&lt;/div&gt; &lt;time datetime=&quot;2025-06-09T18:04:36.057Z&quot; class=&quot;date s-hik11q&quot;&gt;June 9, 2025 at 6:04 PM&lt;/time&gt; &lt;div class=&quot;stats s-hik11q&quot;&gt;&lt;span class=&quot;stat s-hik11q&quot; title=&quot;91 likes&quot;&gt;&lt;svg class=&quot;icon&quot; fill=&quot;none&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; d=&quot;M12 5.768c6.162-6.25 16.725 5.358 0 14.732C-4.725 11.126 5.838-.482 12 5.768Z&quot;&gt;&lt;/path&gt;&lt;/svg&gt; &lt;span&gt;91&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;stat s-hik11q&quot; title=&quot;19 reposts&quot;&gt;&lt;svg class=&quot;icon&quot; fill=&quot;none&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path stroke=&quot;currentColor&quot; stroke-linecap=&quot;square&quot; stroke-width=&quot;2&quot; d=&quot;m17 3 3 3-3 3M7 21l-3-3 3-3m-2 3h15v-5M4 11V6h15&quot;&gt;&lt;/path&gt;&lt;/svg&gt; &lt;span&gt;19&lt;/span&gt;&lt;/span&gt; &lt;div class=&quot;gap s-hik11q&quot;&gt;&lt;/div&gt; &lt;a href=&quot;https://bsky.app/profile/did:plc:3danwc67lo7obz2fmdg6jxcr/post/3lr6xouhoxc2i&quot; target=&quot;_blank&quot; class=&quot;permalink s-hik11q&quot;&gt;&lt;span&gt;Read 10 replies on Bluesky&lt;/span&gt;&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt; &lt;/bluesky-post&gt;</content:encoded></item><item><title>Rust 1.0, ten years later</title><link>https://steveklabnik.com/writing/rust-ten-years-later/</link><guid isPermaLink="true">https://steveklabnik.com/writing/rust-ten-years-later/</guid><description>It’s kind of hard to believe it’s been ten years since Rust 1.0 was released. I stopped working on Rust three years ago, and frankly, the last three years have been pretty rough. But 2025 is shaping up to be a really good year for me, with lots of positive changes. With that in…</description><pubDate>Thu, 15 May 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;It’s kind of hard to believe it’s been ten years since Rust 1.0 was released.&lt;/p&gt;
&lt;p&gt;I stopped working on Rust three years ago, and frankly, the last three years
have been pretty rough. But 2025 is shaping up to be a really good year for me,
with lots of positive changes.&lt;/p&gt;
&lt;p&gt;With that in mind, this post is going to be a bit of a different one than you
might expect. For a fantastic post that’s a bit more traditional, check out
what Graydon wrote for the Rust Foundation: &lt;a href=&quot;https://rustfoundation.org/media/10-years-of-stable-rust-an-infrastructure-story/&quot;&gt;10 years of stable Rust: an
infrastructure story&lt;/a&gt;. It’s fantastic, of course.&lt;/p&gt;
&lt;p&gt;I’d instead like to reflect a bit on a comment I saw on the internet the other day:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;[Rust is] not a great hobby language but it is a fantastic professional
language, precisely because of the ease of refactors and speed of development
that comes with the type system and borrow checker.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;a href=&quot;https://pcwalton.github.io/&quot;&gt;Patrick Walton&lt;/a&gt;, one of the earliest contributors to Rust, had this
to say:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I never thought I’d live to see the day when someone would say this. The first
5 years of Rust were all “this is interesting for hobby projects but nobody will
ever adopt this in industry”.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The release of Rust 1.0 was great, but it was also stressful. The few years
before Rust 1.0 were marked by a deep, deep anxiety among the team. I’m sure
someone else who was around back then will disagree with me, but that’s my
recollection. It may not have always been overt, but it was there. A large
question was looming over us: would anyone actually use this thing? Would it
become a hobbyist language, or would it be something that people actually
used in production?&lt;/p&gt;
&lt;p&gt;At this point, we now know the answer: yes, Rust is used a lot. It’s used
for real, critical projects to do actual work by some of the largest companies
in our industry. We did good.&lt;/p&gt;
&lt;p&gt;The release of 1.0 was the start of that journey in earnest. It was time to stop
changing things all the time, and to start focusing on stability. It was time to
gain more users, and to fix the issues that they found. We had to start shipping
stable releases, and we had to start doing it on a regular basis. We had to
start doing all of the things that a real programming language does.&lt;/p&gt;
&lt;p&gt;Over the last ten years, a lot changed. It wasn’t easy, and it took a lot of
blood, sweat, and many, many tears. But we did it. We built a real programming
language, and we built a real community around it.&lt;/p&gt;
&lt;p&gt;Rust is very much not perfect. There’s more work to be done, and arguably,
someone out there should probably be starting a language that will someday eat
Rust’s lunch.&lt;/p&gt;
&lt;p&gt;But ten years ago, we were pushing a button and praying that it would all work
out. And now, ten years later, I’m doing this:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;text&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;❯ rustup update stable&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;info: syncing channel updates for &amp;#39;stable-x86_64-unknown-linux-gnu&amp;#39;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;info: latest update on 2025-05-15, rust version 1.87.0 (17067e9ac 2025-05-09)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;info: downloading component &amp;#39;rust-src&amp;#39;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;info: downloading component &amp;#39;cargo&amp;#39;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;info: downloading component &amp;#39;clippy&amp;#39;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;info: downloading component &amp;#39;rust-docs&amp;#39;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;info: downloading component &amp;#39;rust-std&amp;#39;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;info: downloading component &amp;#39;rustc&amp;#39;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;info: downloading component &amp;#39;rustfmt&amp;#39;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;info: removing previous version of component &amp;#39;rust-src&amp;#39;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;info: removing previous version of component &amp;#39;cargo&amp;#39;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;info: removing previous version of component &amp;#39;clippy&amp;#39;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;info: removing previous version of component &amp;#39;rust-docs&amp;#39;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;info: removing previous version of component &amp;#39;rust-std&amp;#39;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;info: removing previous version of component &amp;#39;rustc&amp;#39;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;info: removing previous version of component &amp;#39;rustfmt&amp;#39;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;info: installing component &amp;#39;rust-src&amp;#39;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;info: installing component &amp;#39;cargo&amp;#39;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;info: installing component &amp;#39;clippy&amp;#39;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;info: installing component &amp;#39;rust-docs&amp;#39;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt; 19.9 MiB /  19.9 MiB (100 %)  16.3 MiB/s in  1s ETA:  0s&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;info: installing component &amp;#39;rust-std&amp;#39;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt; 29.4 MiB /  29.4 MiB (100 %)  22.2 MiB/s in  1s ETA:  0s&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;info: installing component &amp;#39;rustc&amp;#39;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt; 76.3 MiB /  76.3 MiB (100 %)  23.9 MiB/s in  3s ETA:  0s&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;info: installing component &amp;#39;rustfmt&amp;#39;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  stable-x86_64-unknown-linux-gnu updated - rustc 1.87.0 (17067e9ac 2025-05-09) (from rustc 1.86.0 (05f9846f8 2025-03-31))&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;and then going about my day. It is a rare privilege to be able to spend ten
years building a tool you want to use, and then be able to spend your time at
work using it. I am grateful to have had that opportunity, and I hope that
everyone else who has worked on Rust over the years feels the same way.&lt;/p&gt;
&lt;hr/&gt;
&lt;p&gt;Here’s my post about this post on BlueSky:&lt;/p&gt;
&lt;bluesky-post src=&quot;at://did:plc:3danwc67lo7obz2fmdg6jxcr/app.bsky.feed.post/3lpa37moavc2s&quot; data-pagefind-ignore=&quot;true&quot;&gt; &lt;div class=&quot;bluesky-embed s-3olstj&quot;&gt;&lt;div class=&quot;highlighted-post s-hik11q&quot;&gt;&lt;div class=&quot;meta s-hik11q&quot;&gt;&lt;a href=&quot;https://bsky.app/profile/did:plc:3danwc67lo7obz2fmdg6jxcr&quot; target=&quot;_blank&quot; class=&quot;avatar-wrapper s-hik11q&quot;&gt;&lt;img loading=&quot;lazy&quot; src=&quot;https://cdn.bsky.app/img/avatar/plain/did:plc:3danwc67lo7obz2fmdg6jxcr/bafkreidffwgsdli2xp56t3kfemk7bryow3mygu7zbvgcsxgsu3ntnp4hwm&quot; alt=&quot;&quot; class=&quot;avatar s-hik11q&quot;/&gt;&lt;/a&gt; &lt;a href=&quot;https://bsky.app/profile/did:plc:3danwc67lo7obz2fmdg6jxcr&quot; target=&quot;_blank&quot; class=&quot;name-wrapper s-hik11q&quot;&gt;&lt;bdi class=&quot;display-name-wrapper s-hik11q&quot;&gt;&lt;span class=&quot;display-name s-hik11q&quot;&gt;Steve Klabnik&lt;/span&gt;&lt;/bdi&gt; &lt;span class=&quot;handle s-hik11q&quot;&gt;@steveklabnik.com&lt;/span&gt;&lt;/a&gt; &lt;svg class=&quot;logo s-hik11q&quot; fill=&quot;none&quot; viewBox=&quot;0 0 320 286&quot;&gt;&lt;path fill=&quot;#0A7AFF&quot; d=&quot;M69.364 19.146c36.687 27.806 76.147 84.186 90.636 114.439 14.489-30.253 53.948-86.633 90.636-114.439C277.107-.917 320-16.44 320 32.957c0 9.865-5.603 82.875-8.889 94.729-11.423 41.208-53.045 51.719-90.071 45.357 64.719 11.12 81.182 47.953 45.627 84.785-80 82.874-106.667-44.333-106.667-44.333s-26.667 127.207-106.667 44.333c-35.555-36.832-19.092-73.665 45.627-84.785-37.026 6.362-78.648-4.149-90.071-45.357C5.603 115.832 0 42.822 0 32.957 0-16.44 42.893-.917 69.364 19.147Z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/div&gt;  &lt;p class=&quot;rich-text is-large s-1lecfnd&quot;&gt;&lt;a target=&quot;_blank&quot; href=&quot;https://bsky.app/hashtag/rustlang&quot; class=&quot;hashtag s-1lecfnd&quot;&gt;#rustlang&lt;/a&gt; 1.0, ten years later &lt;a target=&quot;_blank&quot; href=&quot;https://steveklabnik.com/writing/rust-ten-years-later/&quot; rel=&quot;noopener nofollow&quot; class=&quot;link s-1lecfnd&quot;&gt;steveklabnik.com/writing/rust...&lt;/a&gt;&lt;/p&gt; &lt;div class=&quot;embeds s-azdpbr&quot;&gt;&lt;a target=&quot;_blank&quot; href=&quot;https://steveklabnik.com/writing/rust-ten-years-later/&quot; rel=&quot;noopener noreferrer nofollow&quot; class=&quot;external-embed s-rtbqd8&quot;&gt; &lt;div class=&quot;meta s-rtbqd8&quot;&gt;&lt;p class=&quot;title s-rtbqd8&quot;&gt;Rust 1.0, ten years later&lt;/p&gt; &lt;p class=&quot;description s-rtbqd8&quot;&gt;&lt;/p&gt; &lt;div class=&quot;domain s-rtbqd8&quot;&gt;&lt;svg class=&quot;icon&quot; fill=&quot;none&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path stroke=&quot;currentColor&quot; stroke-linecap=&quot;round&quot; stroke-width=&quot;2&quot; d=&quot;m4.172 8.07 3.94 2.957.977-1.941 3.887-.978 1.15-4.6M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Zm-6.078 4.865.973-1.946-2.869-1.928-1.89-.12-1.08 1.075 1.947 2.919h2.919Z&quot;&gt;&lt;/path&gt;&lt;/svg&gt; &lt;span class=&quot;domain-name&quot;&gt;steveklabnik.com&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/a&gt;&lt;/div&gt; &lt;time datetime=&quot;2025-05-15T17:49:56.018Z&quot; class=&quot;date s-hik11q&quot;&gt;May 15, 2025 at 5:49 PM&lt;/time&gt; &lt;div class=&quot;stats s-hik11q&quot;&gt;&lt;span class=&quot;stat s-hik11q&quot; title=&quot;198 likes&quot;&gt;&lt;svg class=&quot;icon&quot; fill=&quot;none&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; d=&quot;M12 5.768c6.162-6.25 16.725 5.358 0 14.732C-4.725 11.126 5.838-.482 12 5.768Z&quot;&gt;&lt;/path&gt;&lt;/svg&gt; &lt;span&gt;198&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;stat s-hik11q&quot; title=&quot;35 reposts&quot;&gt;&lt;svg class=&quot;icon&quot; fill=&quot;none&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path stroke=&quot;currentColor&quot; stroke-linecap=&quot;square&quot; stroke-width=&quot;2&quot; d=&quot;m17 3 3 3-3 3M7 21l-3-3 3-3m-2 3h15v-5M4 11V6h15&quot;&gt;&lt;/path&gt;&lt;/svg&gt; &lt;span&gt;35&lt;/span&gt;&lt;/span&gt; &lt;div class=&quot;gap s-hik11q&quot;&gt;&lt;/div&gt; &lt;a href=&quot;https://bsky.app/profile/did:plc:3danwc67lo7obz2fmdg6jxcr/post/3lpa37moavc2s&quot; target=&quot;_blank&quot; class=&quot;permalink s-hik11q&quot;&gt;&lt;span&gt;Read 13 replies on Bluesky&lt;/span&gt;&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt; &lt;/bluesky-post&gt;</content:encoded></item><item><title>Thinking like a compiler: places and values in Rust</title><link>https://steveklabnik.com/writing/thinking-like-a-compiler-places-and-values-in-rust/</link><guid isPermaLink="true">https://steveklabnik.com/writing/thinking-like-a-compiler-places-and-values-in-rust/</guid><description>A while back, someone on the internet asked about this syntax in Rust: * pointer_of_some_kind = blah; They wanted to know how the compiler understands this code, especially if the pointer wasn’t a reference, but a smart pointer. I wrote them a lengthy reply, but wanted to expand…</description><pubDate>Mon, 07 Apr 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;A while back, someone on the internet asked about this syntax in Rust:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;rust&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;*&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;pointer_of_some_kind &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; blah;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;They wanted to know how the compiler understands this code, especially if the
pointer wasn’t a reference, but a smart pointer. I wrote them a lengthy reply,
but wanted to expand and adapt it into a blog post in case a broader audience
may be interested.&lt;/p&gt;
&lt;p&gt;Now, I don’t work on the Rust compiler, and haven’t really ever, but what I do
know is language semantics. If you’re a language nerd, this post may not be
super interesting to you, other than to learn about Rust’s value categories, but
if you haven’t spent a lot of time with the finer details of programming
languages, I’m hoping that this may be a neat peek into that world.&lt;/p&gt;
&lt;hr/&gt;
&lt;p&gt;Programming languages are themselves languages, in the same sense that human
languages are. Well, mostly, anyway. The point is, to understand some Rust code
like this:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;rust&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;*&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;pointer_of_some_kind &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; blah;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We can apply similar tools to how we might understand some “English code” like
this:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;text&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;You can&amp;#39;t judge a book by its cover.&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Oh, you also might ask yourself as you’re reading the next sections, “why so
many steps?” The short answer is a classic one: by breaking down the big problem
of “what does this mean?” into smaller steps, each step is easier. Doing everything
at once is way more difficult than a larger number of smaller steps. I’m going
to cover the classical ways compilers work, there’s a ton of variety when you
start getting into more modern ways of doing things, and often these steps are
blended together, or done out of order, all kinds of other things. Handling
errors is a huge topic in and of itself! Consider this a starting point, not an
ending one.&lt;/p&gt;
&lt;p&gt;Let’s get into it.&lt;/p&gt;
&lt;h2 id=&quot;lexical-analysis-aka-scanning-or-tokenizing&quot;&gt;Lexical Analysis (aka ‘scanning’ or ‘tokenizing’)&lt;/h2&gt;
&lt;p&gt;The first thing we want to do is to try and figure out if these words are even
valid words at all. With computer languages, this process is called “lexical
analysis,” though you’ll also hear the term “tokenizing” to describe it. In other
words, we’re not interested in any sort of meaning at all at this stage, we just
want to figure out what we’re even talking about.&lt;/p&gt;
&lt;p&gt;So if we look at this English sentence:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;text&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;You can&amp;#39;t judge a book by its cover.&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We follow a two step process in order to tokenize it: we first “scan” it to
produce a sequence of “lexemes.” We do this by following some rules. I’m not
going to give you a sample of the rules for English here, as this post is
already long enough. But you might end up with something like this:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;text&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;You&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;can&amp;#39;t&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;judge&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;a&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;book&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;by&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;its&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;cover&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;.&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Note how we do have &lt;code&gt;&amp;#39;&lt;/code&gt; in &lt;code&gt;can&amp;#39;t&lt;/code&gt;, but &lt;code&gt;.&lt;/code&gt; is separate from &lt;code&gt;cover&lt;/code&gt;. These
are the kinds of rules we’d be following: the &lt;code&gt;&amp;#39;&lt;/code&gt; is because this is a contraction,
but the &lt;code&gt;.&lt;/code&gt; is not really part of &lt;code&gt;cover&lt;/code&gt;, but its own thing.&lt;/p&gt;
&lt;p&gt;We then run a second step and evaluate each individual string of characters, turning
them into “tokens.” A token is some sort of data type in your compiler, probably, so
for example we could do this in Rust:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;rust&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;enum&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; Token&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;    Word&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;String&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;    Punctuation&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;String&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And so the output of our tokenizer might be an array of something like&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;rust&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;[&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;    Word&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&amp;quot;You&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;    Word&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&amp;quot;can&amp;#39;t&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;    Word&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&amp;quot;judge&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;    Word&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&amp;quot;a&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;    Word&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&amp;quot;book&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;    Word&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&amp;quot;by&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;    Word&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&amp;quot;its&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;    Word&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&amp;quot;cover&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;    Punctuation&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&amp;quot;.&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;At this point, we know we have something semi-coherent, but we’re still
not sure it’s valid yet. On to the next step!&lt;/p&gt;
&lt;h2 id=&quot;syntactic-analysis-aka-parsing&quot;&gt;Syntactic Analysis (aka ‘parsing’)&lt;/h2&gt;
&lt;p&gt;Funny enough, this is an area where human-language linguistics and compilers
mean things that are slightly different. With human language, parsing is often
combined with our next step, which is semantic analysis. But we (most of the
time) try to separate syntax and semantic analysis in compilers.&lt;/p&gt;
&lt;p&gt;Again, I’m going to massively simplify with the English. We’re going to use
these rules for what a sentence is:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;A sentence is a sequence of words.&lt;/li&gt;
&lt;li&gt;A sentence has a “subject,” which is the first word, and must be capitalized.&lt;/li&gt;
&lt;li&gt;A sentence ends with a period.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Obviously this is a tiny subset of English, but you get the idea. The goal of
syntactic analysis is to turn our sequence of tokens into a richer data
structure that’s easier to work with. In other words, we’ve figured out that
our sentence is made up of valid sequences of characters, but do they fit the
grammatical rules of our language? Note that we also don’t need to store everything;
for example, maybe our English data structure looks like this:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;rust&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;struct&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; Sentence&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    subject&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; String&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    words&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; Vec&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;String&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Where’s the period? How do we know &lt;code&gt;subject&lt;/code&gt; must be capitalized? That’s the job
of syntactic analysis. Since every sentence ends with a period, we don’t need to
track it in our data structure: the analysis makes sure that it’s true, and then
we aren’t doing it again. Likewise, we don’t need to store our subject as a
capitalized string if we don’t want to: we determined that the input was, but we
can transform it as needed. So our value after syntax analysis might look like this:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;rust&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;Sentence&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    subject&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &amp;quot;you&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    words&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; [&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&amp;quot;can&amp;#39;t&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&amp;quot;judge&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&amp;quot;a&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&amp;quot;book&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&amp;quot;by&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&amp;quot;its&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&amp;quot;cover&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;],&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Often, for computer languages, a tree-like structure works well, and so you’d
see an “abstract syntax tree,” or “AST” at the end of this stage. But it’s not
strictly speaking required, whatever data structure makes sense for you can
work.&lt;/p&gt;
&lt;p&gt;Now that we have a richer data structure, we’re almost done. Now we have to get
into meaning.&lt;/p&gt;
&lt;h2 id=&quot;semantic-analysis-aka-wtf-does-this-mean&quot;&gt;Semantic Analysis (aka ‘wtf does this mean’)&lt;/h2&gt;
&lt;p&gt;Imagine our sentence wasn’t “You can’t judge a book by its cover.” but instead
this:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;text&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;incididunt ut labore et dolore magna aliqua.&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is a famous bit of text that’s incoherent. The words are all Latin words,
and it &lt;em&gt;feels&lt;/em&gt; like it might be a sentence, but it’s nonsense. We could parse
this into a &lt;code&gt;Sentence&lt;/code&gt;:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;rust&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;Sentence&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    subject&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &amp;quot;Lorem&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    words&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; [&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&amp;quot;ipsum&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&amp;quot;dolor&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&amp;quot;sit&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&amp;quot;amet&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;/* and continued */&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; ],&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;But it’s not valid. How do we determine &lt;em&gt;that&lt;/em&gt;?&lt;/p&gt;
&lt;p&gt;Well, in the context of English, “Lorem” isn’t a valid English word. So if we
were to check that the subject is a valid word, we’d successfully reject this
sentence. In computer languages, we’d do similar things like type checking:
&lt;code&gt;5 + &amp;quot;hello&amp;quot;&lt;/code&gt; might lex and parse just fine, but when we try and figure out
what it means, we learn it’s nonsense. Except if your language lets you add
numbers and strings!&lt;/p&gt;
&lt;p&gt;After semantic analysis, we’ve determined that our program is good, aka “well
formed.” In a compiler, we’d then go on to generate machine code or byte code
to represent our program. But that stuff, while incredibly interesting, isn’t
what we’re talking about here: remember our original objective? It was to
understand this:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;rust&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;*&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;pointer_of_some_kind &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; blah;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That’s semantics. So now that we have some background, let’s talk about how
to understand this code.&lt;/p&gt;
&lt;h2 id=&quot;so-how-do-i-understand-this-code&quot;&gt;So… how do I understand this code?&lt;/h2&gt;
&lt;p&gt;Well, to understand the code, we first need to understand how it lexes and
parses. In other words, what the &lt;em&gt;grammar&lt;/em&gt; of our language is. How our language
would lex, tokenize, and then parse our code. In this case, it’s Rust. Rust’s
grammar is large and complex, so we’ll only be talking about part of it today.
We’re going to focus on statements vs expressions.&lt;/p&gt;
&lt;p&gt;You may have heard that Rust is an “expression based language” before. Well,
this is what people mean. You see, when it comes to most of the things you say
in a program, they’re often one of these two things. Expressions are things that
produce some sort of value, and statements are used to sequence the evaluation
of expressions. That’s a bit abstract, so let’s get concrete.&lt;/p&gt;
&lt;h3 id=&quot;statements&quot;&gt;Statements&lt;/h3&gt;
&lt;p&gt;Rust has a few kinds of statements: first, there’s “declaration statements”
and “expression statements,” and each have their own sub-kinds as well.&lt;/p&gt;
&lt;p&gt;Declaration statements have two kinds: &lt;em&gt;item declarations&lt;/em&gt;, and &lt;em&gt;let statements&lt;/em&gt;.
Item declarations are things like &lt;code&gt;mod&lt;/code&gt; or &lt;code&gt;struct&lt;/code&gt; or &lt;code&gt;fn&lt;/code&gt;: they declare certain
things exist. &lt;code&gt;let&lt;/code&gt; statements are probably the most famous form of statement in
Rust, they look like this:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;text&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt; OuterAttribute* let PatternNoTopAlt ( : Type )? (= Expression † ( else BlockExpression) ? ) ? ;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That’s… a mouthful. We haven’t talked about &lt;code&gt;*&lt;/code&gt; or &lt;code&gt;?&lt;/code&gt; yet, and we don’t really
want to cover some of the more exotic parts of Rust right now. So we’re going
to talk about this via a simpler grammar first:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;text&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;let Variable = Expression;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is how we create new variables in Rust: we say &lt;code&gt;let&lt;/code&gt;, and then a name, an &lt;code&gt;=&lt;/code&gt;,
and then finally some expression. The result of evaluating that expression becomes
the value of the variable.&lt;/p&gt;
&lt;p&gt;This is leaving out a lot: the name isn’t just a name, it’s a pattern, which is
very cool. &lt;code&gt;let else&lt;/code&gt; exists in Rust now, and that’s cool. We’re ignoring types
here. But you can get the basics with just this simple version.&lt;/p&gt;
&lt;p&gt;Expression statements are much simpler:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;text&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;ExpressionWithoutBlock ; | ExpressionWithBlock ;?&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The &lt;code&gt;|&lt;/code&gt; there is an or, so we can either have a single expression followed by a &lt;code&gt;;&lt;/code&gt;,
or a block (denoted by &lt;code&gt;{}&lt;/code&gt;s, which can optionally (the ? means it can exist or not)
be followed by a &lt;code&gt;;&lt;/code&gt;.)&lt;/p&gt;
&lt;p&gt;So to think like a compiler, you can start to figure out how to combine these rules.
For example:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;rust&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;let&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; x &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;    5&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; +&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 6&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;};&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here, we have a let statement, but the expression on the right hand side of the &lt;code&gt;=&lt;/code&gt;
is an &lt;code&gt;ExpressionWithBlock&lt;/code&gt;. Here’s a pop quiz for you: is the &lt;code&gt;;&lt;/code&gt; part of the let
expression, or part of the expression on the right hand side?&lt;/p&gt;
&lt;p&gt;The answer is, it’s part of the &lt;code&gt;let&lt;/code&gt;. The let expression has a mandatory &lt;code&gt;;&lt;/code&gt;, but
the block does not, and so:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;text&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;let x = ExpressionWithBlock;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If we had the semicolon with the block, we’d still need the one for the let, and
so we’d have &lt;code&gt;};;&lt;/code&gt;. Which the compiler accepts, but it warns about it.&lt;/p&gt;
&lt;p&gt;Going back to our original code:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;rust&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;*&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;pointer_of_some_kind &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; blah;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We don’t have a &lt;code&gt;let&lt;/code&gt;, and this isn’t an item declaration: this is an expression
statement. We have a &lt;code&gt;ExpressionWithoutBlock&lt;/code&gt;, followed by a &lt;code&gt;;&lt;/code&gt;. So now we have
to talk about expressions.&lt;/p&gt;
&lt;h3 id=&quot;expressions&quot;&gt;Expressions&lt;/h3&gt;
&lt;p&gt;There are a &lt;em&gt;lot&lt;/em&gt; of expression types in Rust. &lt;a href=&quot;https://doc.rust-lang.org/stable/reference/expressions.html&quot;&gt;Section 8.2 of the
Reference&lt;/a&gt; has 19 sub-sections. Whew! In this case, this code is an
Operation Expression, and more specifically, an &lt;a href=&quot;https://doc.rust-lang.org/stable/reference/expressions/operator-expr.html#assignment-expressions&quot;&gt;Assignment Expression&lt;/a&gt;:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;text&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Expression = Expression&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Easy enough! So the left hand side of the &lt;code&gt;=&lt;/code&gt; is an expression with &lt;code&gt;*pointer_of_some_kind&lt;/code&gt;, and the right hand side is &lt;code&gt;blah&lt;/code&gt;. Easy enough!&lt;/p&gt;
&lt;p&gt;But these two expressions are in some ways, the entire reason that I wrote this
post. We just finally got here! You see, the reference has this to say about
assignment expressions:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;An assignment expression moves a value into a specified place.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;What are those?&lt;/p&gt;
&lt;h4 id=&quot;places-and-values&quot;&gt;Places and Values&lt;/h4&gt;
&lt;p&gt;C, and older versions of C++, called these two things “lvalue” and “rvalue,”
for “left” and “right”, like the sides of the &lt;code&gt;=&lt;/code&gt;. More recent C++ standards
have more categories. Rust splits the difference: it only has two categories,
like C, but they map more cleanly to two of C++‘s categories. Rust calls
lvalues, the left hand side, a “place,” and rvalues, the right hand side,
a “value.” Here’s two more precise definitions, from the Unsafe Code Guidelines:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A &lt;a href=&quot;https://rust-lang.github.io/unsafe-code-guidelines/glossary.html#place&quot;&gt;place&lt;/a&gt; is basically a pointer, but might contain more information
such as size or alignment. A place has a type, indicating the type of values
that it stores.&lt;/li&gt;
&lt;li&gt;A &lt;a href=&quot;https://rust-lang.github.io/unsafe-code-guidelines/glossary.html#value&quot;&gt;value&lt;/a&gt; A value is what gets stored in a place. A value has a type.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Both of these have expression forms, so a &lt;em&gt;place expression&lt;/em&gt; produces a place
when it’s evaluated, and a &lt;em&gt;value expression&lt;/em&gt; produces a value. And that’s
how &lt;code&gt;=&lt;/code&gt; works: we have a place expression on the left, a value expression
on the right, and we put that value in that place. Easy enough!&lt;/p&gt;
&lt;p&gt;Once again, the code we were trying to figure out:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;rust&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;*&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;pointer_of_some_kind &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; blah;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So &lt;code&gt;*&lt;/code&gt;, the dereference operator, takes the pointer, and evaluates to the place
where it points: its address. And &lt;code&gt;blah&lt;/code&gt; gives us the value to put there.&lt;/p&gt;
&lt;p&gt;Case closed? Not quite!&lt;/p&gt;
&lt;h3 id=&quot;deref&quot;&gt;Deref&lt;/h3&gt;
&lt;p&gt;Rust has a trait, &lt;code&gt;Deref&lt;/code&gt;, that lets us override the &lt;code&gt;*&lt;/code&gt; operator. So let’s
talk about this example, to make things easier:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;rust&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;use&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; std&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;ops&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;Deref&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;DerefMut&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;};&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;struct&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; DerefMutExample&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;T&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    value&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; T&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;impl&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;T&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt; &lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;Deref&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; for&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; DerefMutExample&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;T&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    type&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; Target&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; T&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    fn&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; deref&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; &amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;Self&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;Target&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        &amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;value&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;impl&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;T&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt; &lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;DerefMut&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; for&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; DerefMutExample&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;T&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    fn&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; deref_mut&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;amp;mut&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; self&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; &amp;amp;mut&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; Self&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;Target&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        &amp;amp;mut&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; self&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;value&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;fn&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; main () {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    let&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; mut&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; x &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; DerefMutExample&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; { value&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &amp;#39;a&amp;#39;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; };&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    *&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;x &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &amp;#39;b&amp;#39;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;    assert_eq!&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&amp;#39;b&amp;#39;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, x&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;value);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You can play with it &lt;a href=&quot;https://play.rust-lang.org/?version=stable&amp;amp;mode=debug&amp;amp;edition=2021&amp;amp;gist=0d6c7f3d8a2c00bc79dabef47ab550e2&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;We didn’t talk about the kind of expression that’s relevant here yet: a &lt;em&gt;path
expression.&lt;/em&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Path expressions that resolve to local or static variables are place
expressions, other paths are value expressions.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;We talked about &lt;code&gt;let&lt;/code&gt; earlier: in &lt;code&gt;let mut x = DerefMutExample { value: &amp;#39;a&amp;#39; };&lt;/code&gt;
above, the &lt;code&gt;x&lt;/code&gt; is a path expression, and since it’s resolving to our new variable,
that means it’s a place expression. The &lt;code&gt;DerefMutExample { value: &amp;#39;a&amp;#39; }&lt;/code&gt; is a
value expression, because it doesn’t resolve to a variable.&lt;/p&gt;
&lt;p&gt;Let’s talk about &lt;code&gt;*x = &amp;#39;b&amp;#39;;&lt;/code&gt;, remember our assignment expression:&lt;/p&gt;
&lt;p&gt;expression = expression;&lt;/p&gt;
&lt;p&gt;And what it does: it moves a value into a place.&lt;/p&gt;
&lt;p&gt;To understand how &lt;code&gt;*&lt;/code&gt; works, we only need to add one more thing: the Dereference
expression. It’s produced by the deference operator, &lt;code&gt;*&lt;/code&gt;. It looks like this:&lt;/p&gt;
&lt;p&gt;*expression&lt;/p&gt;
&lt;p&gt;Its semantics are pretty straightforward:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;If the expression has the type &lt;code&gt;&amp;amp;T&lt;/code&gt;, &lt;code&gt;&amp;amp;mut T&lt;/code&gt;, &lt;code&gt;*const T&lt;/code&gt;, or &lt;code&gt;*mut T&lt;/code&gt;, then
this evaluates to the place of the value being pointed to, and gives it the
same mutability.&lt;/li&gt;
&lt;li&gt;If the expression is not one of those types, then it is equivalent to either
&lt;code&gt;*std::ops::Deref::deref(&amp;amp;x)&lt;/code&gt; if it’s immutable or
&lt;code&gt;*std::ops::DerefMut::deref_mut(&amp;amp;mut x)&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;That’s it. Now we have enough to fully understand &lt;code&gt;*x = &amp;#39;b&amp;#39;&lt;/code&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;&amp;#39;b&amp;#39;&lt;/code&gt; is a value expression&lt;/li&gt;
&lt;li&gt;&lt;code&gt;*x&lt;/code&gt; is not a pointer type, so we expand it to
&lt;code&gt;*std::ops::DerefMut::deref_mut(&amp;amp;mut x)&lt;/code&gt; and try again&lt;/li&gt;
&lt;li&gt;&lt;code&gt;std::ops::DerefMut::deref_mut(&amp;amp;mut x)&lt;/code&gt; returns the type &lt;code&gt;&amp;amp;mut char&lt;/code&gt; in this
case, and it is pointing at the place of &lt;code&gt;self.value&lt;/code&gt; (which I’m gonna call
&lt;code&gt;&amp;lt;that place&amp;gt;&lt;/code&gt; for short), which currently has the value &lt;code&gt;&amp;#39;a&amp;#39;&lt;/code&gt; stored in it. Now
we have &lt;code&gt;*&amp;amp;mut &amp;lt;that place&amp;gt;&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;We now use the other rule of the dereference operator, we’re operating on a
&lt;code&gt;&amp;amp;mut T&lt;/code&gt;, so &lt;code&gt;*&amp;amp;mut &amp;lt;that place&amp;gt;&lt;/code&gt; refers to &lt;code&gt;&amp;lt;that place&amp;gt;&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;We now have &lt;code&gt;&amp;lt;that place&amp;gt; = &amp;#39;b&amp;#39;&lt;/code&gt;, and so we move that &lt;code&gt;&amp;#39;b&amp;#39;&lt;/code&gt; into that place.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Whew! That’s that.&lt;/p&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Thinking like a compiler can be fun! Once you’ve mastered the idea of grammars
and gotten used to substituting things, you can figure out all sorts of
interesting stuff. In this specific case, sometimes people wonder why &lt;code&gt;Deref&lt;/code&gt;
returns a reference if the whole goal is to show where something should point…
and if you didn’t know that dereference expressions expanded to something with
&lt;code&gt;*&lt;/code&gt; in it, it would be confusing! But now you know. And hopefully learned some
interesting things about values, places, and how compilers think about code
along the way.&lt;/p&gt;
&lt;hr/&gt;
&lt;p&gt;Here’s my post about this post on BlueSky:&lt;/p&gt;
&lt;bluesky-post src=&quot;at://did:plc:3danwc67lo7obz2fmdg6jxcr/app.bsky.feed.post/3lmanw5qdik2o&quot; data-pagefind-ignore=&quot;true&quot;&gt; &lt;div class=&quot;bluesky-embed s-3olstj&quot;&gt;&lt;div class=&quot;highlighted-post s-hik11q&quot;&gt;&lt;div class=&quot;meta s-hik11q&quot;&gt;&lt;a href=&quot;https://bsky.app/profile/did:plc:3danwc67lo7obz2fmdg6jxcr&quot; target=&quot;_blank&quot; class=&quot;avatar-wrapper s-hik11q&quot;&gt;&lt;img loading=&quot;lazy&quot; src=&quot;https://cdn.bsky.app/img/avatar/plain/did:plc:3danwc67lo7obz2fmdg6jxcr/bafkreidffwgsdli2xp56t3kfemk7bryow3mygu7zbvgcsxgsu3ntnp4hwm&quot; alt=&quot;&quot; class=&quot;avatar s-hik11q&quot;/&gt;&lt;/a&gt; &lt;a href=&quot;https://bsky.app/profile/did:plc:3danwc67lo7obz2fmdg6jxcr&quot; target=&quot;_blank&quot; class=&quot;name-wrapper s-hik11q&quot;&gt;&lt;bdi class=&quot;display-name-wrapper s-hik11q&quot;&gt;&lt;span class=&quot;display-name s-hik11q&quot;&gt;Steve Klabnik&lt;/span&gt;&lt;/bdi&gt; &lt;span class=&quot;handle s-hik11q&quot;&gt;@steveklabnik.com&lt;/span&gt;&lt;/a&gt; &lt;svg class=&quot;logo s-hik11q&quot; fill=&quot;none&quot; viewBox=&quot;0 0 320 286&quot;&gt;&lt;path fill=&quot;#0A7AFF&quot; d=&quot;M69.364 19.146c36.687 27.806 76.147 84.186 90.636 114.439 14.489-30.253 53.948-86.633 90.636-114.439C277.107-.917 320-16.44 320 32.957c0 9.865-5.603 82.875-8.889 94.729-11.423 41.208-53.045 51.719-90.071 45.357 64.719 11.12 81.182 47.953 45.627 84.785-80 82.874-106.667-44.333-106.667-44.333s-26.667 127.207-106.667 44.333c-35.555-36.832-19.092-73.665 45.627-84.785-37.026 6.362-78.648-4.149-90.071-45.357C5.603 115.832 0 42.822 0 32.957 0-16.44 42.893-.917 69.364 19.147Z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/div&gt;  &lt;p class=&quot;rich-text is-large s-1lecfnd&quot;&gt;Thinking like a compiler: places and values in &lt;a target=&quot;_blank&quot; href=&quot;https://bsky.app/hashtag/rustlang&quot; class=&quot;hashtag s-1lecfnd&quot;&gt;#rustlang&lt;/a&gt;

&lt;a target=&quot;_blank&quot; href=&quot;https://steveklabnik.com/writing/thinking-like-a-compiler-places-and-values-in-rust/&quot; rel=&quot;noopener nofollow&quot; class=&quot;link s-1lecfnd&quot;&gt;steveklabnik.com/writing/thin...&lt;/a&gt;&lt;/p&gt; &lt;div class=&quot;embeds s-azdpbr&quot;&gt;&lt;a target=&quot;_blank&quot; href=&quot;https://steveklabnik.com/writing/thinking-like-a-compiler-places-and-values-in-rust/&quot; rel=&quot;noopener noreferrer nofollow&quot; class=&quot;external-embed s-rtbqd8&quot;&gt; &lt;div class=&quot;meta s-rtbqd8&quot;&gt;&lt;p class=&quot;title s-rtbqd8&quot;&gt;Thinking like a compiler: places and values in Rust&lt;/p&gt; &lt;p class=&quot;description s-rtbqd8&quot;&gt;&lt;/p&gt; &lt;div class=&quot;domain s-rtbqd8&quot;&gt;&lt;svg class=&quot;icon&quot; fill=&quot;none&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path stroke=&quot;currentColor&quot; stroke-linecap=&quot;round&quot; stroke-width=&quot;2&quot; d=&quot;m4.172 8.07 3.94 2.957.977-1.941 3.887-.978 1.15-4.6M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Zm-6.078 4.865.973-1.946-2.869-1.928-1.89-.12-1.08 1.075 1.947 2.919h2.919Z&quot;&gt;&lt;/path&gt;&lt;/svg&gt; &lt;span class=&quot;domain-name&quot;&gt;steveklabnik.com&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/a&gt;&lt;/div&gt; &lt;time datetime=&quot;2025-04-07T19:09:04.578Z&quot; class=&quot;date s-hik11q&quot;&gt;April 7, 2025 at 7:09 PM&lt;/time&gt; &lt;div class=&quot;stats s-hik11q&quot;&gt;&lt;span class=&quot;stat s-hik11q&quot; title=&quot;85 likes&quot;&gt;&lt;svg class=&quot;icon&quot; fill=&quot;none&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; d=&quot;M12 5.768c6.162-6.25 16.725 5.358 0 14.732C-4.725 11.126 5.838-.482 12 5.768Z&quot;&gt;&lt;/path&gt;&lt;/svg&gt; &lt;span&gt;85&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;stat s-hik11q&quot; title=&quot;11 reposts&quot;&gt;&lt;svg class=&quot;icon&quot; fill=&quot;none&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path stroke=&quot;currentColor&quot; stroke-linecap=&quot;square&quot; stroke-width=&quot;2&quot; d=&quot;m17 3 3 3-3 3M7 21l-3-3 3-3m-2 3h15v-5M4 11V6h15&quot;&gt;&lt;/path&gt;&lt;/svg&gt; &lt;span&gt;11&lt;/span&gt;&lt;/span&gt; &lt;div class=&quot;gap s-hik11q&quot;&gt;&lt;/div&gt; &lt;a href=&quot;https://bsky.app/profile/did:plc:3danwc67lo7obz2fmdg6jxcr/post/3lmanw5qdik2o&quot; target=&quot;_blank&quot; class=&quot;permalink s-hik11q&quot;&gt;&lt;span&gt;Read 4 replies on Bluesky&lt;/span&gt;&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt; &lt;/bluesky-post&gt;</content:encoded></item><item><title>Does unsafe undermine Rust&apos;s guarantees?</title><link>https://steveklabnik.com/writing/does-unsafe-undermine-rusts-guarantees/</link><guid isPermaLink="true">https://steveklabnik.com/writing/does-unsafe-undermine-rusts-guarantees/</guid><description>When people first hear about unsafe in Rust, they often have questions. A very normal thing to ask is, “wait a minute, doesn’t this defeat the purpose?” And while it’s a perfectly reasonable question, the answer is both straightforward and has a lot of nuance. So let’s talk about…</description><pubDate>Mon, 17 Mar 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;When people first hear about &lt;code&gt;unsafe&lt;/code&gt; in Rust, they often have questions. A very
normal thing to ask is, “wait a minute, doesn’t this defeat the purpose?” And while
it’s a perfectly reasonable question, the answer is both straightforward and has a
lot of nuance. So let’s talk about it.&lt;/p&gt;
&lt;p&gt;(The straightforward answer is “no”, by the way.)&lt;/p&gt;
&lt;h2 id=&quot;memory-safe-languages-and-their-implementations&quot;&gt;Memory safe languages and their implementations&lt;/h2&gt;
&lt;p&gt;The first way to think about this sort of thing is to remember that programming
languages and their implementations are two different things. This is sometimes
difficult to remember, since many programming languages only have one
implementation, but this general principle applies even in those cases. That is,
there are the desired semantics of the language you are implementing, and then
the codebase that makes programs in that language do those things.&lt;/p&gt;
&lt;p&gt;Let’s examine a “real” programming language to talk about this: &lt;a href=&quot;https://en.wikipedia.org/wiki/Brainfuck&quot;&gt;Brainfuck&lt;/a&gt;.
Brainfuck programs are made up of eight different characters, each one performing
one operation. Brainfuck programs can only do those eight things, and nothing
more.&lt;/p&gt;
&lt;p&gt;However, this simplicity leads to two interesting observations about the
differences between languages in the abstract and their implementations.&lt;/p&gt;
&lt;h3 id=&quot;unsafety-in-implementation&quot;&gt;Unsafety in implementation&lt;/h3&gt;
&lt;p&gt;The first is that properties of the language itself are distinct from properties
of an implementation of the language. The semantics of the Brainfuck language
don’t provide an opportunity to call some sort of re-usable function
abstraction, for example. Yet, when we write a Brainfuck interpreter or
compiler, we can use a programming language that supports functions. That
doesn’t change that Brainfuck programs themselves can’t define or call
functions.&lt;/p&gt;
&lt;p&gt;And in fact, we often want to implement a language in another language that has
more abilities than the language we’re implementing. For example, while it’s
possible to implement Brainfuck in Brainfuck, it’s much easier to do so in a
language that lets you define and call functions. Another classic example is
interacting with hardware. Brainfuck has the &lt;code&gt;.&lt;/code&gt; instruction that allows you to
produce output. But in order to actually produce output to say, a terminal, you
interact with your platform’s API to do so. But inside of that API, eventually
you’ll hit a layer where there are no abstractions: you need to talk to hardware
directly. Doing so is not statically able to be guaranteed to be memory safe,
because the hardware/software interface often boils down to “put some
information at this arbitrary memory location and the hardware will take it from
there.” Our Brainfuck program is operating in an environment just like any
other; at the end of the day it has to coordinate with the underlying operating
system or hardware at some point. But just because our implementation must do
so, doesn’t mean that our Brainfuck programs do so directly. The semantics of
programs written in Brainfuck aren’t changed by the fact that the implementation
can (and must) do things that are outside of those semantics.&lt;/p&gt;
&lt;p&gt;Let’s take Ruby as a more realistic example than Brainfuck. Ruby does not let us modify
arbitrary memory addresses from within Ruby itself. This means that pure Ruby
programs should not be able to produce a segmentation fault. But in the real
world, Ruby programs can segfault. This is possible if there’s a bug in the Ruby
interpreter’s code. Sure, it’s our Ruby code that’s making the call to a
function that results in a segfault, but the real fault lies with the code
outside of Ruby’s purview.&lt;/p&gt;
&lt;p&gt;That this can happen doesn’t mean that Ruby’s guarantees around memory
manipulation is somehow useless, or suffers segmentation faults at the same rate
as programs in a language that allow you to manipulate arbitrary memory as a
matter of course. But it does also mean that we don’t need to look at our entire
program to figure out where the problem comes from: it instead comes from our
non-Ruby code. Ruby’s guarantees have helped us eliminate a lot of suspects when
figuring out whodunit.&lt;/p&gt;
&lt;h3 id=&quot;extending-languages-and-unsafety&quot;&gt;Extending languages and unsafety&lt;/h3&gt;
&lt;p&gt;The second property is that certain implementations may extend the language in
arbitrary ways. For example, I could write a Brainfuck interpreter and say that
I support a ninth instruction, &lt;code&gt;@&lt;/code&gt;, that terminates the program when invoked.
This would be a non-portable extension, and Brainfuck programs written in my
variant wouldn’t work in other interpreters, but sometimes, this technique is
useful.&lt;/p&gt;
&lt;p&gt;Many languages find that these sorts of extensions are useful, and so offer a
feature called a “foreign function interface” that allows for your program to
invoke code in a different language. This provides the ability to do things that
are outside of the domain of the language itself, which can be very useful.
Brainfuck does not offer an FFI, but if it did, you could imagine that &lt;code&gt;@&lt;/code&gt; could
be implemented in terms of it, making programs that use &lt;code&gt;@&lt;/code&gt; portable again, as
long as the extended functionality was included somehow, often as a library of
some kind.&lt;/p&gt;
&lt;p&gt;Just like our implementation has the ability to do things outside of our
languages’ semantics, FFI and similar extension mechanisms also give us the
ability to do arbitrary things. I can write an extension for Ruby that writes to
arbitrary memory. And I can cause a segfault. But we’re in the same place that
we were with our implementation issues; we know that if we get a segfault, the
blame lies not with our Ruby code, but instead, with either the implementation
or our FFI.&lt;/p&gt;
&lt;h3 id=&quot;so-how-is-this-memory-safe&quot;&gt;So how is this memory safe?&lt;/h3&gt;
&lt;p&gt;It may seem contradictory that we can call a language “memory safe” if
real-world programs have the ability to cause memory problems. But the thing is,
it isn’t &lt;em&gt;really&lt;/em&gt; programs in that language that caused the issue: it was FFI,
which is in a different language entirely, or it was implementation issues, and
implementations must do memory unsafe things, thanks to a need to interact with
the OS or hardware. And so the definition of “memory safe language” is commonly
understood to refer to languages and their implementations in the absence of
either implementation bugs or FFI bugs. In practice, these bugs occur at such a
low rate compared to languages that are clearly not memory safe that this
practical definition serves a good purpose, even if you may feel a bit
uncomfortable with these “exceptions.”&lt;/p&gt;
&lt;p&gt;But there’s actually a deeper reason why these exceptions are acceptable, and
that’s due to how we understand properties of programs and programming languages
in the first place. That is, this isn’t just a practical “well these exceptions
seem fine” sort of thing, they’re actually okay on a deeper level.&lt;/p&gt;
&lt;h2 id=&quot;programs-properties-and-proofs&quot;&gt;Programs, properties, and proofs&lt;/h2&gt;
&lt;p&gt;So how do we know anything about how programs and programming languages work at
all?&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Computer science is no more about computers than astronomy is about
telescopes.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Edsger Wybe Dijkstra&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;A fun thing about computer science is that it’s closely related to other
disciplines, including math! And so there’s a long history of using math
techniques to understand computers and their programs.&lt;/p&gt;
&lt;p&gt;One technique of building knowledge is the idea of proofs. If you get a
degree in computer science, you’ll engage with proofs quite a lot. I even
took a class on logic in the philosophy department as part of my degree.&lt;/p&gt;
&lt;p&gt;I don’t intend to give you a full introduction to the idea of proofs in this
blog post, but there’s some high-level concepts that are useful to make sure
we’re in the same page about before we go forward.&lt;/p&gt;
&lt;h3 id=&quot;aristotelian-syllogisms&quot;&gt;Aristotelian syllogisms&lt;/h3&gt;
&lt;p&gt;Here is a very classic example of a form of reasoning called a “syllogism”,
given by Aristotle in 350 BCE:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;All men are mortal.&lt;/li&gt;
&lt;li&gt;Socrates is a man.&lt;/li&gt;
&lt;li&gt;Therefore, Socrates is mortal.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;These first two lines are called “propositions,” and the third is a conclusion.
We can base our conclusion on a logical relationship between the information given
to us by the propositions.&lt;/p&gt;
&lt;p&gt;But how do we know propositions are true? Are all men mortal? What’s important
here is that we, for the purposes of our proof, assume that propositions are
true. And we do this because, on some level, we cannot know everything. And so
to begin, we have to start somewhere, and make some assumptions about what we
know. It’s true that later, we may discover a fact that disproves our
proposition, and now our proof no longer works. But that’s just the way that
the world works. It doesn’t prevent these sorts of proofs from being useful to
help us gain knowledge about the world and how it works, as best as we can tell
at the current time.&lt;/p&gt;
&lt;p&gt;So on some level, this is also why Ruby is a memory safe language even though a
C extension can segfault: there’s always some kind of things that we have to
assume are true. Memory safe languages are ones where the amount of code we have
to assume is memory safe, rather than is guaranteed to be by the semantics, is
small, and preferably indicated in the code itself. Put another way, the amount
of code we need to trust is memory safe is large in a memory unsafe language,
and small in a memory safe language, rather than zero.&lt;/p&gt;
&lt;h3 id=&quot;logic-and-programs&quot;&gt;Logic and programs&lt;/h3&gt;
&lt;p&gt;As time went on, so did our understanding of logic. And, of course, we even have
competing logics! And then this gets fun, because terms can mean something
slightly different. For example, in more recent logics, we’d call something like
“All men are mortal” to be an &lt;em&gt;axiom&lt;/em&gt;, rather than a proposition. Same idea:
it’s something that we accept without proof.&lt;/p&gt;
&lt;p&gt;As computers appeared, people sought to apply the rules for mathematical logic
onto them. We even call circuits that carry out classic logical operations
“logic gates.” Number theory and logic were foundational to making computers
work. And so, once high level languages appeared on the scene, there was
interest in applying these mathematical tools to understanding programs as well.
This discipline is called “formal verification,” and the general idea is to
describe various properties we wish a system to have, and then use formal
methods from mathematics to demonstrate that this is true.&lt;/p&gt;
&lt;p&gt;This area of study is very deep, and I don’t plan to cover the vast majority of
it here. However, I do want to pursue one particular thread in this area.&lt;/p&gt;
&lt;h3 id=&quot;hoare-logic&quot;&gt;Hoare Logic&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://dl.acm.org/doi/10.1145/363235.363259&quot;&gt;“Hoare Logic”&lt;/a&gt; is, well:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;In this paper an attempt is made to explore the logical foundations of
computer programming by use of techniques which were first applied in the
study of geometry and have later been extended to other branches of
mathematics. This involves the elucidation of sets of axioms and rules of
inference which can be used in proofs of the properties of computer programs.
Examples are given of such axioms and rules, and a formal proof of a simple
theorem is displayed. Finally, it is argued that important advantage, both
theoretical and practical, may follow from a pursuance of these topics.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Incidentally, C. A. R. Hoare, the author of this paper, and Graydon Hoare, the
creator of Rust, are unrelated.&lt;/p&gt;
&lt;p&gt;How does Hoare logic work? Yet again, not going to cover all of it, but the
general idea is this: In order to figure out if a program does what it is
supposed to do, we need to be able to reason about the state of the program
after execution happens. And so we need to be able to describe the state before,
and its relationship to the state after. And so you get this notation:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;text&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;P { Q } R&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;P is a precondition, Q is a program, and R is the result of the program
executing with those preconditions.&lt;/p&gt;
&lt;p&gt;But most programs have more than one statement. So how could we model this?
Hoare gives us the Rule of Composition:&lt;/p&gt;
&lt;p&gt;If &lt;code&gt;P { Q1 } R1&lt;/code&gt; and &lt;code&gt;R1 { Q2 } R&lt;/code&gt; then &lt;code&gt;P { Q1; Q2 } R&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;This allows us to build up a program by proving each statement in turn.&lt;/p&gt;
&lt;p&gt;Hoare logic is very neat, and I’ve only scratched the surface here. People did a
lot of work to extend Hoare logic to include more and more aspects of programs.
But then, something else happened.&lt;/p&gt;
&lt;h3 id=&quot;separation-logic&quot;&gt;Separation Logic&lt;/h3&gt;
&lt;p&gt;In 2002, &lt;a href=&quot;https://www.cs.cmu.edu/~jcr/seplogic.pdf&quot;&gt;Separation Logic: A Logic for Shared Mutable Data Structures&lt;/a&gt;
was published.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;In joint work with Peter O’Hearn and others, based on early ideas of Burstall,
we have developed an extension of Hoare logic that permits reasoning about
low-level imperative programs that use shared mutable data structure.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Hmm, shared mutable data structures? Where have I heard that before…&lt;/p&gt;
&lt;p&gt;Let’s see what they have to say:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The problem faced by these approaches is that the correctness of a program
that mutates data structures usually depends upon complex restrictions on the
sharing in these structures.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;For sure. Well, what are we to do about this?&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The key to avoiding this difficulty is to introduce a novel
logical operation &lt;code&gt;P * Q&lt;/code&gt;, called separating conjunction (or
sometimes independent or spatial conjunction), that asserts
that P and Q hold for disjoint portions of the addressable
storage.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;What disjoint portions of addressable storage might we care about?&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Our intent is to capture the low-level character of machine language. One can
think of the store as describing the contents of registers, and the heap as
describing the contents of an addressable memory.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Pretty useful!&lt;/p&gt;
&lt;p&gt;Before we talk a bit about how separation logic works, consider this paragraph
on why it’s named as such:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Since these logics are based on the idea that the structure of an assertion
can describe the separation of storage into disjoint components,we have come
to use the term separation logics, both for the extension of predicate
calculus with the separation operators and the resulting extension of Hoare
logic. A more precise name might be storage separation logics, since it is
becoming apparent that the underlying idea can be generalized to describe the
separation of other kinds of resources.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The plot thickens.&lt;/p&gt;
&lt;p&gt;Anyway, in Separation Logic, we use slightly different notation than Hoare Logic:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;text&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;{ P } C { Q }&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This says that we start with the precondition &lt;code&gt;P&lt;/code&gt;, and if the program &lt;code&gt;C&lt;/code&gt;
executes, it will not have undefined behavior, and if it terminates, &lt;code&gt;Q&lt;/code&gt; will
hold.&lt;/p&gt;
&lt;p&gt;Furthermore, there is the “frame rule”, which I am going to butcher the notation
for because I haven’t bothered to install something to render math correctly
just for this post:&lt;/p&gt;
&lt;p&gt;If &lt;code&gt;{ p } c { q }&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;then &lt;code&gt;{ p * r } c { q * r }&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;where no free variable in &lt;code&gt;r&lt;/code&gt; is modified by &lt;code&gt;c&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Why is it interesting to add something to both sides of an equation, in a sense?
Well what this gives us the ability to do is add any predicates about parts of
the program that &lt;code&gt;c&lt;/code&gt; doesn’t modify or mutate. You might think of &lt;code&gt;&amp;amp;mut T&lt;/code&gt; or
even just ownership in general: we can reason about just these individual parts
of a program, separately from the rest of it. In other words, we have some
foundational ideas for ownership and even bits of borrowing, and while this original
paper doesn’t involve concurrency, eventually Concurrent Separation Logic would become
a thing as well.&lt;/p&gt;
&lt;p&gt;I think the paper explains why the frame rule matters better than I can:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Every valid specification &lt;code&gt;{p} c {q}&lt;/code&gt; is “tight” in the sense that every cell
in its footprint must either be allocated by &lt;code&gt;c&lt;/code&gt; or asserted to be active by
&lt;code&gt;p&lt;/code&gt;; “locality” is the opposite property that everything asserted to be active
belongs to the footprint. The role of the frame rule is to infer from a local
specification of a command the more global specification appropriate to the
larger footprint of an enclosing command.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;What this gives us is something called “local reasoning,” and local reasoning
is &lt;em&gt;awesome&lt;/em&gt;. Before I talk about that, I want to leave you with one other
very interesting paragraph:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Since our logic permits programs to use unrestricted address arithmetic,there
is little hope of constructing any general-purpose garbage collector. On the
other hand, the situation for the older logic, in which addresses are disjoint
from integers, is more hopeful. However, it is clear that this logic permits
one to make assertions, such as “The heap contains two elements” that might be
falsified by the execution of a garbage collector, even though, in any
realistic sense, such an execution is unobservable.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Anyway. Let’s talk about local vs global analysis.&lt;/p&gt;
&lt;h2 id=&quot;global-vs-local-analysis&quot;&gt;Global vs local analysis&lt;/h2&gt;
&lt;p&gt;Proving things about programs isn’t easy. But one thing that can make it even
harder is that, for many properties of many programs you’d want to analyze, you
need to do a &lt;em&gt;global analysis&lt;/em&gt;. As an example, let’s use Ruby. Ruby is an
incredibly dynamic programming language, which makes it fairly resistant to
static analysis.&lt;/p&gt;
&lt;h3 id=&quot;global-analysis&quot;&gt;Global analysis&lt;/h3&gt;
&lt;p&gt;Here is a Ruby program. Do you know if this program executes successfully?&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;ruby&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; Foo&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;  def&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; self.bar&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;    &amp;quot;baz&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;  end&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;end&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;p&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; Foo&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;bar&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Yeah, it prints &lt;code&gt;baz&lt;/code&gt;. But what about this Ruby program?&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;ruby&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; Foo&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;  def&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; self.bar&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;    &amp;quot;baz&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;  end&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;end&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;require&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &amp;quot;foo_ext.rb&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;p&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; Foo&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;bar&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We can’t know. &lt;code&gt;foo_ext.rb&lt;/code&gt; may contain no relevant code, but it also might
include something like this:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;ruby&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;Foo&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;class_eval&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; { &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;undef&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; :bar&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; }&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In which case, when we try and call &lt;code&gt;Foo.bar&lt;/code&gt;, it no longer exists:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;text&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&amp;lt;anonymous&amp;gt;&amp;#39;: eval:13:in `block in &amp;lt;main&amp;gt;&amp;#39;: undefined method `bar&amp;#39; for class `Foo&amp;#39; (NameError)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;eval:13:in `class_eval&amp;#39;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;eval:13:in `&amp;lt;main&amp;gt;&amp;#39;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;-e:in `eval&amp;#39;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Ouch. So in this case, we’re going to need the whole code of our program in
order to be able to figure out what’s going on here.&lt;/p&gt;
&lt;p&gt;Incidentally, &lt;a href=&quot;https://sorbet.org/&quot;&gt;Sorbet&lt;/a&gt; is a very cool project to add type checking to
Ruby. They do require access to the entire Ruby source code in order to do their
analysis. But they also made some decisions to help make it more tractable; if
you try Sorbet out on the web, the type checker is &lt;em&gt;fast&lt;/em&gt;. What happens when you
try the above code with Sorbet?&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;text&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;editor.rb:5: Unsupported method: undef https://srb.help/3008&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;     5 |Foo.class_eval { undef :bar }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                         ^^^^^^^^^^&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is a very fair tradeoff! It’s very common with various forms of analysis to
choose certain restrictions in order to make what they want to do tractable. Ruby
has so much evil in it, just not supporting some of the more obscure things is
completely fair, in my opinion.&lt;/p&gt;
&lt;h3 id=&quot;local-analysis&quot;&gt;Local analysis&lt;/h3&gt;
&lt;p&gt;The opposite of global analysis is, well, local analysis. Let’s consider a Rust
equivalent of our Ruby:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;rust&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;struct&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; Foo&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;impl&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; Foo&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    fn&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; bar&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;() &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; String&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;        String&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&amp;quot;baz&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;fn&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; main&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;    dbg!&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;Foo&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;bar&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;());&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Can we know if this program works? Sure, everything is here. Now, if we tried the
same trick as the Ruby code, we know that it would work, because Rust doesn’t have
the ability to remove the definition of &lt;code&gt;bar&lt;/code&gt; like Ruby does. So let’s try something
else:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;rust&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;struct&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; Foo&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;impl&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; Foo&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    fn&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; bar&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;() &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; String&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;        // body hidden&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;fn&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; main&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;    dbg!&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;Foo&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;bar&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;());&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Can we know if &lt;code&gt;main&lt;/code&gt; is properly typed here? We can, even though we know
nothing about the body. That’s because &lt;code&gt;dbg!&lt;/code&gt; takes any value that implements
the &lt;code&gt;Debug&lt;/code&gt; trait, and we know that &lt;code&gt;Foo::bar()&lt;/code&gt; returns &lt;code&gt;String&lt;/code&gt;, which
implements &lt;code&gt;Debug&lt;/code&gt;. Typechecking &lt;code&gt;main&lt;/code&gt; is local to main’s implementation, we
don’t need to look into the bodies of any function it calls to determine if it’s
well-typed. We only need to know their signatures. If we didn’t require &lt;code&gt;bar&lt;/code&gt; to
have a type signature, we’d have to peek into its body to figure out what it
returns, and so on for any function that &lt;code&gt;bar&lt;/code&gt; calls in its body. Instead of
this arbitrarily deep process, we can just look at the signature and be done
with it.&lt;/p&gt;
&lt;h2 id=&quot;composability-of-proofs&quot;&gt;Composability of proofs&lt;/h2&gt;
&lt;p&gt;So why is local analysis so helpful? The first reason is either speed or
scalability, depending on how you want to look at it. If you are running global
analysis checks, they will get more expensive the larger your codebase, since
they will require checking the entire thing to work. Whereas local analysis only
requires a local context, it doesn’t get any more expensive when you add more
code to your project, only when you change that local context. So when you’re
trying to scale checks up to larger projects, local analysis is crucial.&lt;/p&gt;
&lt;p&gt;But I also like to personally think about it as a sort of abstraction. That is,
global analysis is a leaky abstraction: changes in one part of the codebase can
cascade into other parts. Remember this line about the frame rule?&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The role of the frame rule is to infer from a local specification of a command
the more global specification appropriate to the larger footprint of an
enclosing command.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;If we have local reasoning, we can be sure that changes locally don’t break out
of the boundaries of those changes. As long as the types of our function don’t
change, we can mess with the body as much as we want, and we know that the rest
of the analysis of the program is still intact. This is really useful, in the
same way that abstractions are useful when building programs more generally.&lt;/p&gt;
&lt;h2 id=&quot;rustbelt&quot;&gt;Rustbelt&lt;/h2&gt;
&lt;p&gt;Okay, we have taken a real deep dive here. What’s this all have to do with
unsafe Rust?&lt;/p&gt;
&lt;p&gt;Well, seven years ago, &lt;a href=&quot;https://plv.mpi-sws.org/rustbelt/popl18/paper.pdf&quot;&gt;RustBelt: Securing the Foundations of the Rust
Programming Language&lt;/a&gt; by Ralf Jung, Jaques-Henri Jourdan, Robbert
Krebbers, and Derek Dreyer, was published:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;In this paper, we give the first formal (and machine-checked) safety proof for
a language representing a realistic subset of Rust.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;But it’s more exciting than that:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Our proof is extensible in the sense that, for each new Rust library that uses
unsafe features, we can say what verification condition it must satisfy in
order for it to be deemed a safe extension to the language.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Very good!&lt;/p&gt;
&lt;p&gt;The paper begins by talking about why verifying Rust is such a challenge:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Consequently, to overcome this restriction, the implementations of Rust’s
standard libraries make widespread use of unsafe operations, such as “raw
pointer” manipulations for which aliasing is not tracked. The developers of
these libraries claim that their uses of unsafe code have been properly
“encapsulated”, meaning that if programmers make use of the APIs exported by
these libraries but otherwise avoid the use of unsafe operations themselves,
then their programs should never exhibit any unsafe/undefined behaviors. In
effect, these libraries extend the expressive power of Rust’s type system by
loosening its ownership discipline on aliased mutable state in a modular,
controlled fashion&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This is basically the question asked at the start of this post: can you honestly
say that a function is safe if it contains &lt;code&gt;unsafe&lt;/code&gt; code as part of its
implementation?&lt;/p&gt;
&lt;p&gt;They go on to describe the first challenge for the project: choosing the correct
logic to model Rust in (some information cut for clarity):&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Iris is a language-generic framework for higher-order concurrent separation
logic which in the past year has been equipped with tactical support for
conducting machine-checked proofs of programs in Coq. By virtue of being a
separation logic, Iris comes with built-in support for reasoning modularly
about ownership. Moreover, the main selling point of Iris is its support for
deriving custom program logics for different domains using only a small set of
primitive mechanisms. In the case of RustBelt, we used Iris to derive a novel
lifetime logic, whose primary feature is a notion of borrow propositions that
mirrors the “borrowing” mechanism for tracking aliasing in Rust.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Separation logic!&lt;/p&gt;
&lt;p&gt;So how does this work? There are three parts to the proof. I’m going to
summarize them because I’m already quoting extensively, please go read the paper
if you want the exact details, it is well written.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Verify that the typing rules are sound when interpreted semantically.&lt;/li&gt;
&lt;li&gt;Verify that if a program is well typed semantically, it does not exhibit
unsafe behavior.&lt;/li&gt;
&lt;li&gt;For any library that uses unsafe, check that it satisfies the semantics that
its interface requires.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;If all three of these things are true, then the program is safe to execute. This
is also exciting because, thanks to 3, when someone writes new unsafe code, they
can get RustBelt to let them know which properties they need to satisfy to make
sure that their unsafe code doesn’t cause problems.&lt;/p&gt;
&lt;h3 id=&quot;weaknesses&quot;&gt;Weaknesses&lt;/h3&gt;
&lt;p&gt;Of course, there is more to do following up on RustBelt:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;We do not model (1) more relaxed forms of atomic accesses, which Rust uses for
efficiency in libraries like Arc; (2) Rust’s trait objects (comparable to
interfaces in Java), which can pose safety issues due to their interactions
with lifetimes; or (3) stack unwinding when a panic occurs, which causes
issues similar to exception safety in C++.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;However, the results were good enough to find some soundness bugs in the
standard library, and if I remember correctly, widen one of the APIs in a sound
manner as well. Another interesting thing about RustBelt is that it was
published before Rust gained Non-lexical lifetimes, however, it modeled them,
since folks knew they were coming down the pipeline.&lt;/p&gt;
&lt;h2 id=&quot;the-theoretical-vs-the-empirical&quot;&gt;The theoretical vs the empirical&lt;/h2&gt;
&lt;p&gt;So, we have some amount of actual proof that unsafe code in Rust doesn’t
undermine Rust’s guarantees: what it does is allow us to extend Rust’s
semantics, just like FFI would allow us to extend a program written in
a language that supports it. As long as our unsafe code is semantically
correct, then we’re all good.&lt;/p&gt;
&lt;p&gt;… but what if it’s not semantically correct?&lt;/p&gt;
&lt;h3 id=&quot;when-things-go-wrong&quot;&gt;When things go wrong&lt;/h3&gt;
&lt;p&gt;At some point maybe I’ll write a post about the specifics here, but this post is
already incredibly long. I’ll cut to the chase: you can get undefined behavior,
which means anything can happen. You don’t have a real Rust program. It’s bad.&lt;/p&gt;
&lt;p&gt;But at least it’s scoped to some degree. However, many people get this scope a
bit wrong. They’ll say something like:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;You only need to verify the unsafe blocks.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This is true, but also a bit misleading. Before we get into the unsafe stuff, I
want you to consider an example. Is this Rust code okay?&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;rust&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;struct&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; Foo&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    bar&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; usize&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;impl&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; Foo&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    fn&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; set_bar&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;amp;mut&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; self&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, bar&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; usize&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;        self&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;bar &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; bar;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;No unsafe shenanigans here. This code is perfectly safe, if a bit useless.&lt;/p&gt;
&lt;p&gt;Let’s talk about unsafe. The canonical example of unsafe code being affected
outside of unsafe itself is the implementation of &lt;code&gt;Vec&amp;lt;T&amp;gt;&lt;/code&gt;. Vecs look something
like this (the real code is different for reasons that don’t really matter in
this context):&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;rust&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;struct&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; Vec&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;T&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    ptr&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; *mut&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; T&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    len&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; usize&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    cap&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; usize&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The pointer is to a bunch of &lt;code&gt;T&lt;/code&gt;s in a row, the length is the current number of &lt;code&gt;T&lt;/code&gt;s
that are valid, and the capacity is the total number of &lt;code&gt;T&lt;/code&gt;s. The length and the
capacity are different so that memory allocation is amortized; the capacity is
always greater than or equal to the length.&lt;/p&gt;
&lt;p&gt;That property is very important! If the length is greater than the capacity,
when we try and index into the Vec, we’d be accessing random memory.&lt;/p&gt;
&lt;p&gt;So now, this function, which is the same as &lt;code&gt;Foo::set_bar&lt;/code&gt;, is no longer okay:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;rust&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;impl&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;T&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt; &lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;Vec&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;T&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    fn&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; set_len&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;amp;mut&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; self&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, len&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; usize&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;        self&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;len &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; len;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is because the unsafe code inside of other methods of &lt;code&gt;Vec&amp;lt;T&amp;gt;&lt;/code&gt; need to be
able to rely on the fact that &lt;code&gt;len &amp;lt;= capacity&lt;/code&gt;. And so you’ll find that
&lt;code&gt;Vec&amp;lt;T&amp;gt;::set_len&lt;/code&gt; in Rust is marked as unsafe, even though it doesn’t contain
unsafe code.&lt;/p&gt;
&lt;p&gt;And this is why the module being the privacy boundary matters: the only way to
set len directly in safe Rust code is code within the same privacy boundary as
the &lt;code&gt;Vec&amp;lt;T&amp;gt;&lt;/code&gt; itself. And so, that’s the same module, or its children.&lt;/p&gt;
&lt;p&gt;This is still ultimately better than any line of code in the whole codebase, but
it’s not quite as small as you may think at first.&lt;/p&gt;
&lt;h3 id=&quot;how-can-we-check-that-things-havent-gone-wrong&quot;&gt;How can we check that things haven’t gone wrong?&lt;/h3&gt;
&lt;p&gt;Okay, so while RustBelt could give you some idea if your code is correct, I doubt
you’re about to jump into Coq and write some proofs. What can you do? Well,
Rust provides a tool, &lt;code&gt;miri&lt;/code&gt;, that can interpret your Rust code and let you know
if you’ve violated some unsafe rules. But it’s not complete, that is, miri can
tell you if your code is wrong, but it cannot tell you if your code is right. It’s
still quite useful.&lt;/p&gt;
&lt;p&gt;To get miri, you can install it with Rust nightly:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;text&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;$ rustup +nightly component add miri&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And then run your test suite under miri with&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;text&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;$ cargo +nightly miri test&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For more details, consult &lt;a href=&quot;https://github.com/rust-lang/miri&quot;&gt;miri’s documentation&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&quot;do-things-go-wrong&quot;&gt;Do things go wrong?&lt;/h3&gt;
&lt;p&gt;Do people write good unsafe code, or bad?&lt;/p&gt;
&lt;p&gt;Well, the obvious answer to the above question is “yes.” Anyone who says all
unsafe code in Rust is sound is obviously lying. But the absolute isn’t what’s
interesting here, it’s the shade of grey. Is unsafe pervasive? Does Rust have
memory related bugs at the same rate as other MSLs, or closer to memory-unsafe
languages?&lt;/p&gt;
&lt;p&gt;It’s still sort of early days here, but we do have some preliminary results that
are helpful. In 2022, &lt;a href=&quot;https://security.googleblog.com/2022/12/memory-safe-languages-in-android-13.html&quot;&gt;Google reported&lt;/a&gt; that:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;To date, there have been zero memory safety vulnerabilities discovered in
Android’s Rust code.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I am very interested to see a more up to date report about how that’s changed,
but as they say:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;We don’t expect that number to stay zero forever, but given the volume of new
Rust code across two Android releases, and the security-sensitive components
where it’s being used, it’s a significant result. It demonstrates that Rust is
fulfilling its intended purpose of preventing Android’s most common source of
vulnerabilities. Historical vulnerability density is greater than 1/kLOC (1
vulnerability per thousand lines of code) in many of Android’s C/C++ components
(e.g. media, Bluetooth, NFC, etc). Based on this historical vulnerability
density, it’s likely that using Rust has already prevented hundreds of
vulnerabilities from reaching production.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;We’ll see if these results replicate themselves, in the future, and also outside
of Google. But it at least looks like in practice, most unsafe code has not led
to problems. At least so far!&lt;/p&gt;
&lt;hr/&gt;
&lt;p&gt;Here’s my post about this post on BlueSky:&lt;/p&gt;
&lt;bluesky-post src=&quot;at://did:plc:3danwc67lo7obz2fmdg6jxcr/app.bsky.feed.post/3lkqjlfxypk2d&quot; data-pagefind-ignore=&quot;true&quot;&gt; &lt;div class=&quot;bluesky-embed s-3olstj&quot;&gt;&lt;div class=&quot;highlighted-post s-hik11q&quot;&gt;&lt;div class=&quot;meta s-hik11q&quot;&gt;&lt;a href=&quot;https://bsky.app/profile/did:plc:3danwc67lo7obz2fmdg6jxcr&quot; target=&quot;_blank&quot; class=&quot;avatar-wrapper s-hik11q&quot;&gt;&lt;img loading=&quot;lazy&quot; src=&quot;https://cdn.bsky.app/img/avatar/plain/did:plc:3danwc67lo7obz2fmdg6jxcr/bafkreidffwgsdli2xp56t3kfemk7bryow3mygu7zbvgcsxgsu3ntnp4hwm&quot; alt=&quot;&quot; class=&quot;avatar s-hik11q&quot;/&gt;&lt;/a&gt; &lt;a href=&quot;https://bsky.app/profile/did:plc:3danwc67lo7obz2fmdg6jxcr&quot; target=&quot;_blank&quot; class=&quot;name-wrapper s-hik11q&quot;&gt;&lt;bdi class=&quot;display-name-wrapper s-hik11q&quot;&gt;&lt;span class=&quot;display-name s-hik11q&quot;&gt;Steve Klabnik&lt;/span&gt;&lt;/bdi&gt; &lt;span class=&quot;handle s-hik11q&quot;&gt;@steveklabnik.com&lt;/span&gt;&lt;/a&gt; &lt;svg class=&quot;logo s-hik11q&quot; fill=&quot;none&quot; viewBox=&quot;0 0 320 286&quot;&gt;&lt;path fill=&quot;#0A7AFF&quot; d=&quot;M69.364 19.146c36.687 27.806 76.147 84.186 90.636 114.439 14.489-30.253 53.948-86.633 90.636-114.439C277.107-.917 320-16.44 320 32.957c0 9.865-5.603 82.875-8.889 94.729-11.423 41.208-53.045 51.719-90.071 45.357 64.719 11.12 81.182 47.953 45.627 84.785-80 82.874-106.667-44.333-106.667-44.333s-26.667 127.207-106.667 44.333c-35.555-36.832-19.092-73.665 45.627-84.785-37.026 6.362-78.648-4.149-90.071-45.357C5.603 115.832 0 42.822 0 32.957 0-16.44 42.893-.917 69.364 19.147Z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/div&gt;  &lt;p class=&quot;rich-text is-large s-1lecfnd&quot;&gt;Does unsafe undermine &lt;a target=&quot;_blank&quot; href=&quot;https://bsky.app/hashtag/rustlang&quot; class=&quot;hashtag s-1lecfnd&quot;&gt;#rustlang&lt;/a&gt; &apos;s guarantees? &lt;a target=&quot;_blank&quot; href=&quot;https://steveklabnik.com/writing/does-unsafe-undermine-rusts-guarantees/&quot; rel=&quot;noopener nofollow&quot; class=&quot;link s-1lecfnd&quot;&gt;steveklabnik.com/writing/does...&lt;/a&gt;&lt;/p&gt; &lt;div class=&quot;embeds s-azdpbr&quot;&gt;&lt;a target=&quot;_blank&quot; href=&quot;https://steveklabnik.com/writing/does-unsafe-undermine-rusts-guarantees/&quot; rel=&quot;noopener noreferrer nofollow&quot; class=&quot;external-embed s-rtbqd8&quot;&gt; &lt;div class=&quot;meta s-rtbqd8&quot;&gt;&lt;p class=&quot;title s-rtbqd8&quot;&gt;Does unsafe undermine Rust&apos;s guarantees?&lt;/p&gt; &lt;p class=&quot;description s-rtbqd8&quot;&gt;&lt;/p&gt; &lt;div class=&quot;domain s-rtbqd8&quot;&gt;&lt;svg class=&quot;icon&quot; fill=&quot;none&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path stroke=&quot;currentColor&quot; stroke-linecap=&quot;round&quot; stroke-width=&quot;2&quot; d=&quot;m4.172 8.07 3.94 2.957.977-1.941 3.887-.978 1.15-4.6M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Zm-6.078 4.865.973-1.946-2.869-1.928-1.89-.12-1.08 1.075 1.947 2.919h2.919Z&quot;&gt;&lt;/path&gt;&lt;/svg&gt; &lt;span class=&quot;domain-name&quot;&gt;steveklabnik.com&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/a&gt;&lt;/div&gt; &lt;time datetime=&quot;2025-03-19T15:43:41.710Z&quot; class=&quot;date s-hik11q&quot;&gt;March 19, 2025 at 3:43 PM&lt;/time&gt; &lt;div class=&quot;stats s-hik11q&quot;&gt;&lt;span class=&quot;stat s-hik11q&quot; title=&quot;138 likes&quot;&gt;&lt;svg class=&quot;icon&quot; fill=&quot;none&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; d=&quot;M12 5.768c6.162-6.25 16.725 5.358 0 14.732C-4.725 11.126 5.838-.482 12 5.768Z&quot;&gt;&lt;/path&gt;&lt;/svg&gt; &lt;span&gt;138&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;stat s-hik11q&quot; title=&quot;41 reposts&quot;&gt;&lt;svg class=&quot;icon&quot; fill=&quot;none&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path stroke=&quot;currentColor&quot; stroke-linecap=&quot;square&quot; stroke-width=&quot;2&quot; d=&quot;m17 3 3 3-3 3M7 21l-3-3 3-3m-2 3h15v-5M4 11V6h15&quot;&gt;&lt;/path&gt;&lt;/svg&gt; &lt;span&gt;41&lt;/span&gt;&lt;/span&gt; &lt;div class=&quot;gap s-hik11q&quot;&gt;&lt;/div&gt; &lt;a href=&quot;https://bsky.app/profile/did:plc:3danwc67lo7obz2fmdg6jxcr/post/3lkqjlfxypk2d&quot; target=&quot;_blank&quot; class=&quot;permalink s-hik11q&quot;&gt;&lt;span&gt;Read 17 replies on Bluesky&lt;/span&gt;&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt; &lt;/bluesky-post&gt;</content:encoded></item><item><title>A Happy Day for Rust</title><link>https://steveklabnik.com/writing/a-happy-day-for-rust/</link><guid isPermaLink="true">https://steveklabnik.com/writing/a-happy-day-for-rust/</guid><description>A while back, I wrote A sad day for Rust about the Actix-web unsafe controversy. The short of it was, Actix-web was using some unsound unsafe code. When this was discovered, people responded pretty harshly, and the maintainer quit. Others picked up the work, but it still wasn’t…</description><pubDate>Wed, 05 Mar 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;A while back, I wrote &lt;a href=&quot;/writing/a-sad-day-for-rust/&quot;&gt;A sad day for Rust&lt;/a&gt; about the Actix-web unsafe
controversy. The short of it was, Actix-web was using some unsound unsafe code.
When this was discovered, people responded pretty harshly, and the maintainer
quit. Others picked up the work, but it still wasn’t great:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I’m not sure where we go from here, and I’m not sure what we could have done
to prevent this from happening. But I feel like this is a failure, and it’s set
Rust back a bit, and I’m just plain sad.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;While the Rust community surely isn’t perfect, today I’d like to share with you
a different story: one where there was some controversy, but it was handled in
the complete opposite way.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://rustup.rs/&quot;&gt;Rustup&lt;/a&gt; is the official installer and toolchain manager for Rust. It
has a much smaller team than Rust itself does, and releases on a much slower
schedule.&lt;/p&gt;
&lt;p&gt;Back in August of last year, it was decided to &lt;a href=&quot;https://github.com/rust-lang/rustup/pull/3985&quot;&gt;change some behavior&lt;/a&gt;.
The details aren’t super important, what matters is that it’s a breaking change
to a critical component of the ecosystem. I’m not here to say if this change is
good or bad; they had good motivations, there’s also good reasons to keep the
previous behavior, it’s one of those classic “you can’t make everyone happy”
sort of deals.&lt;/p&gt;
&lt;p&gt;The team knew that they’d need to let people know that this had happened:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Yes, you’ve understood it correctly, and this breakage is intentional: #3635 (comment)&lt;/p&gt;
&lt;p&gt;Before the actual release, we’ll definitely clearly communicate this change with
the community, and we’ll use the beta phase to collect user feedback.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;And they did &lt;a href=&quot;https://internals.rust-lang.org/t/seeking-beta-testers-for-rustup-v1-28-0/22060&quot;&gt;make a post on internals&lt;/a&gt; about the change, seeking
feedback. This also landed in a This Week in Rust, in my understanding.&lt;/p&gt;
&lt;p&gt;The problem is, not everyone reads internals, and not everyone reads This Week
in Rust. And so yesterday, some folks woke up to a broken CI, leading to &lt;a href=&quot;https://github.com/rust-lang/rustup/issues/4211&quot;&gt;this
bug report&lt;/a&gt; among other upset posts elsewhere on the internet.&lt;/p&gt;
&lt;p&gt;I have been on the other side of this before. It’s frustrating when you try and
communicate something, and people don’t hear about it, and then they find out
later and get mad at you about it. I also remember the Actix debacle, and many
other controversies in the broader open source ecosystem.&lt;/p&gt;
&lt;bluesky-post src=&quot;at://did:plc:3danwc67lo7obz2fmdg6jxcr/app.bsky.feed.post/3ljiqodr7q22f&quot; data-pagefind-ignore=&quot;true&quot;&gt; &lt;div class=&quot;bluesky-embed s-3olstj&quot;&gt;&lt;div class=&quot;highlighted-post s-hik11q&quot;&gt;&lt;div class=&quot;meta s-hik11q&quot;&gt;&lt;a href=&quot;https://bsky.app/profile/did:plc:3danwc67lo7obz2fmdg6jxcr&quot; target=&quot;_blank&quot; class=&quot;avatar-wrapper s-hik11q&quot;&gt;&lt;img loading=&quot;lazy&quot; src=&quot;https://cdn.bsky.app/img/avatar/plain/did:plc:3danwc67lo7obz2fmdg6jxcr/bafkreidffwgsdli2xp56t3kfemk7bryow3mygu7zbvgcsxgsu3ntnp4hwm&quot; alt=&quot;&quot; class=&quot;avatar s-hik11q&quot;/&gt;&lt;/a&gt; &lt;a href=&quot;https://bsky.app/profile/did:plc:3danwc67lo7obz2fmdg6jxcr&quot; target=&quot;_blank&quot; class=&quot;name-wrapper s-hik11q&quot;&gt;&lt;bdi class=&quot;display-name-wrapper s-hik11q&quot;&gt;&lt;span class=&quot;display-name s-hik11q&quot;&gt;Steve Klabnik&lt;/span&gt;&lt;/bdi&gt; &lt;span class=&quot;handle s-hik11q&quot;&gt;@steveklabnik.com&lt;/span&gt;&lt;/a&gt; &lt;svg class=&quot;logo s-hik11q&quot; fill=&quot;none&quot; viewBox=&quot;0 0 320 286&quot;&gt;&lt;path fill=&quot;#0A7AFF&quot; d=&quot;M69.364 19.146c36.687 27.806 76.147 84.186 90.636 114.439 14.489-30.253 53.948-86.633 90.636-114.439C277.107-.917 320-16.44 320 32.957c0 9.865-5.603 82.875-8.889 94.729-11.423 41.208-53.045 51.719-90.071 45.357 64.719 11.12 81.182 47.953 45.627 84.785-80 82.874-106.667-44.333-106.667-44.333s-26.667 127.207-106.667 44.333c-35.555-36.832-19.092-73.665 45.627-84.785-37.026 6.362-78.648-4.149-90.071-45.357C5.603 115.832 0 42.822 0 32.957 0-16.44 42.893-.917 69.364 19.147Z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/div&gt;  &lt;p class=&quot;rich-text is-large s-1lecfnd&quot;&gt;at one point i questioned my desire to help people get into open source

image unrelated&lt;/p&gt; &lt;div class=&quot;embeds s-azdpbr&quot;&gt;&lt;div class=&quot;image-embed is-bordered is-aligned s-t3k6fc&quot;&gt;&lt;div class=&quot;single-item tl tr bl br is-standalone s-t3k6fc&quot; style=&quot;aspect-ratio: 1024/766&quot;&gt;&lt;img loading=&quot;lazy&quot; src=&quot;https://cdn.bsky.app/img/feed_thumbnail/plain/did:plc:3danwc67lo7obz2fmdg6jxcr/bafkreignn6nf4mlkc2yfpj3y4dwo5j3dyuod3gbcw4rolpcsca6ujbbo5y&quot; alt=&quot;a tweet by @primawesome

My neighbor told me coyotes keep eating his outdoor cats so I asked how many cats he has and he said he just goes to the shelter and gets a new cat afterwards so I said it sounds like he&apos;s just feeding shelter cats to coyotes and then his daughter started crying&quot; class=&quot;image s-t3k6fc&quot;/&gt; &lt;div class=&quot;placeholder s-t3k6fc&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt; &lt;time datetime=&quot;2025-03-03T20:04:06.711Z&quot; class=&quot;date s-hik11q&quot;&gt;March 3, 2025 at 8:04 PM&lt;/time&gt; &lt;div class=&quot;stats s-hik11q&quot;&gt;&lt;span class=&quot;stat s-hik11q&quot; title=&quot;1,158 likes&quot;&gt;&lt;svg class=&quot;icon&quot; fill=&quot;none&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; d=&quot;M12 5.768c6.162-6.25 16.725 5.358 0 14.732C-4.725 11.126 5.838-.482 12 5.768Z&quot;&gt;&lt;/path&gt;&lt;/svg&gt; &lt;span&gt;1,158&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;stat s-hik11q&quot; title=&quot;86 reposts&quot;&gt;&lt;svg class=&quot;icon&quot; fill=&quot;none&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path stroke=&quot;currentColor&quot; stroke-linecap=&quot;square&quot; stroke-width=&quot;2&quot; d=&quot;m17 3 3 3-3 3M7 21l-3-3 3-3m-2 3h15v-5M4 11V6h15&quot;&gt;&lt;/path&gt;&lt;/svg&gt; &lt;span&gt;86&lt;/span&gt;&lt;/span&gt; &lt;div class=&quot;gap s-hik11q&quot;&gt;&lt;/div&gt; &lt;a href=&quot;https://bsky.app/profile/did:plc:3danwc67lo7obz2fmdg6jxcr/post/3ljiqodr7q22f&quot; target=&quot;_blank&quot; class=&quot;permalink s-hik11q&quot;&gt;&lt;span&gt;Read 13 replies on Bluesky&lt;/span&gt;&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt; &lt;/bluesky-post&gt;
&lt;p&gt;However, this time, things went differently. As you can see, the issue is very
respectful, and the comments are also generally respectful. The team responded
&lt;a href=&quot;https://github.com/rust-lang/rustup/issues/4211#issuecomment-2695620307&quot;&gt;graciously&lt;/a&gt;, and decided to put in the work to &lt;a href=&quot;https://blog.rust-lang.org/2025/03/04/Rustup-1.28.1.html&quot;&gt;release a new
version&lt;/a&gt; to restore the previous behavior.&lt;/p&gt;
&lt;p&gt;I was kind of worried yesterday that this would end up being another Actix
situation. The Rust community has changed a lot over time, and while it’s still
pretty good overall, sometimes things can go poorly, just like with any random
group of thousands of people on the internet. But today, I’m grateful that
feedback was given constructively, it was taken with the spirit that it was
intended, and everyone should end up happy.&lt;/p&gt;
&lt;p&gt;If only every controversy went this way, maybe I wouldn’t be wondering about
coyotes.&lt;/p&gt;
&lt;hr/&gt;
&lt;p&gt;Here’s my post about this post on BlueSky:&lt;/p&gt;
&lt;bluesky-post src=&quot;at://did:plc:3danwc67lo7obz2fmdg6jxcr/app.bsky.feed.post/3ljnctebzec25&quot; data-pagefind-ignore=&quot;true&quot;&gt; &lt;div class=&quot;bluesky-embed s-3olstj&quot;&gt;&lt;div class=&quot;highlighted-post s-hik11q&quot;&gt;&lt;div class=&quot;meta s-hik11q&quot;&gt;&lt;a href=&quot;https://bsky.app/profile/did:plc:3danwc67lo7obz2fmdg6jxcr&quot; target=&quot;_blank&quot; class=&quot;avatar-wrapper s-hik11q&quot;&gt;&lt;img loading=&quot;lazy&quot; src=&quot;https://cdn.bsky.app/img/avatar/plain/did:plc:3danwc67lo7obz2fmdg6jxcr/bafkreidffwgsdli2xp56t3kfemk7bryow3mygu7zbvgcsxgsu3ntnp4hwm&quot; alt=&quot;&quot; class=&quot;avatar s-hik11q&quot;/&gt;&lt;/a&gt; &lt;a href=&quot;https://bsky.app/profile/did:plc:3danwc67lo7obz2fmdg6jxcr&quot; target=&quot;_blank&quot; class=&quot;name-wrapper s-hik11q&quot;&gt;&lt;bdi class=&quot;display-name-wrapper s-hik11q&quot;&gt;&lt;span class=&quot;display-name s-hik11q&quot;&gt;Steve Klabnik&lt;/span&gt;&lt;/bdi&gt; &lt;span class=&quot;handle s-hik11q&quot;&gt;@steveklabnik.com&lt;/span&gt;&lt;/a&gt; &lt;svg class=&quot;logo s-hik11q&quot; fill=&quot;none&quot; viewBox=&quot;0 0 320 286&quot;&gt;&lt;path fill=&quot;#0A7AFF&quot; d=&quot;M69.364 19.146c36.687 27.806 76.147 84.186 90.636 114.439 14.489-30.253 53.948-86.633 90.636-114.439C277.107-.917 320-16.44 320 32.957c0 9.865-5.603 82.875-8.889 94.729-11.423 41.208-53.045 51.719-90.071 45.357 64.719 11.12 81.182 47.953 45.627 84.785-80 82.874-106.667-44.333-106.667-44.333s-26.667 127.207-106.667 44.333c-35.555-36.832-19.092-73.665 45.627-84.785-37.026 6.362-78.648-4.149-90.071-45.357C5.603 115.832 0 42.822 0 32.957 0-16.44 42.893-.917 69.364 19.147Z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/div&gt;  &lt;p class=&quot;rich-text is-large s-1lecfnd&quot;&gt;A happy day for &lt;a target=&quot;_blank&quot; href=&quot;https://bsky.app/hashtag/rustlang&quot; class=&quot;hashtag s-1lecfnd&quot;&gt;#rustlang&lt;/a&gt; &lt;a target=&quot;_blank&quot; href=&quot;https://steveklabnik.com/writing/a-happy-day-for-rust/&quot; rel=&quot;noopener nofollow&quot; class=&quot;link s-1lecfnd&quot;&gt;steveklabnik.com/writing/a-ha...&lt;/a&gt;&lt;/p&gt; &lt;div class=&quot;embeds s-azdpbr&quot;&gt;&lt;a target=&quot;_blank&quot; href=&quot;https://steveklabnik.com/writing/a-happy-day-for-rust/&quot; rel=&quot;noopener noreferrer nofollow&quot; class=&quot;external-embed s-rtbqd8&quot;&gt;&lt;img loading=&quot;lazy&quot; src=&quot;https://cdn.bsky.app/img/feed_thumbnail/plain/did:plc:3danwc67lo7obz2fmdg6jxcr/bafkreibb62uzqrzuu7nzx4c2s46anoc6fztalrgpm5qucnoofgdizmwtbu&quot; alt=&quot;&quot; class=&quot;thumbnail s-rtbqd8&quot;/&gt; &lt;div class=&quot;meta s-rtbqd8&quot;&gt;&lt;p class=&quot;title s-rtbqd8&quot;&gt;A Happy Day for Rust&lt;/p&gt; &lt;p class=&quot;description s-rtbqd8&quot;&gt;I’m not sure where we go from here, and I’m not sure what we could have done to prevent this from happening. But I feel like this is a failure, and it’s set Rust back a bit, and I’m just plain sad.&lt;/p&gt; &lt;div class=&quot;domain s-rtbqd8&quot;&gt;&lt;svg class=&quot;icon&quot; fill=&quot;none&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path stroke=&quot;currentColor&quot; stroke-linecap=&quot;round&quot; stroke-width=&quot;2&quot; d=&quot;m4.172 8.07 3.94 2.957.977-1.941 3.887-.978 1.15-4.6M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Zm-6.078 4.865.973-1.946-2.869-1.928-1.89-.12-1.08 1.075 1.947 2.919h2.919Z&quot;&gt;&lt;/path&gt;&lt;/svg&gt; &lt;span class=&quot;domain-name&quot;&gt;steveklabnik.com&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/a&gt;&lt;/div&gt; &lt;time datetime=&quot;2025-03-05T15:39:41.341Z&quot; class=&quot;date s-hik11q&quot;&gt;March 5, 2025 at 3:39 PM&lt;/time&gt; &lt;div class=&quot;stats s-hik11q&quot;&gt;&lt;span class=&quot;stat s-hik11q&quot; title=&quot;185 likes&quot;&gt;&lt;svg class=&quot;icon&quot; fill=&quot;none&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; d=&quot;M12 5.768c6.162-6.25 16.725 5.358 0 14.732C-4.725 11.126 5.838-.482 12 5.768Z&quot;&gt;&lt;/path&gt;&lt;/svg&gt; &lt;span&gt;185&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;stat s-hik11q&quot; title=&quot;23 reposts&quot;&gt;&lt;svg class=&quot;icon&quot; fill=&quot;none&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path stroke=&quot;currentColor&quot; stroke-linecap=&quot;square&quot; stroke-width=&quot;2&quot; d=&quot;m17 3 3 3-3 3M7 21l-3-3 3-3m-2 3h15v-5M4 11V6h15&quot;&gt;&lt;/path&gt;&lt;/svg&gt; &lt;span&gt;23&lt;/span&gt;&lt;/span&gt; &lt;div class=&quot;gap s-hik11q&quot;&gt;&lt;/div&gt; &lt;a href=&quot;https://bsky.app/profile/did:plc:3danwc67lo7obz2fmdg6jxcr/post/3ljnctebzec25&quot; target=&quot;_blank&quot; class=&quot;permalink s-hik11q&quot;&gt;&lt;span&gt;Read 4 replies on Bluesky&lt;/span&gt;&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt; &lt;/bluesky-post&gt;</content:encoded></item><item><title>When should I use String vs &amp;str?</title><link>https://steveklabnik.com/writing/when-should-i-use-string-vs-str/</link><guid isPermaLink="true">https://steveklabnik.com/writing/when-should-i-use-string-vs-str/</guid><description>Rust has two main string types: String and &amp;str . Sometimes, people argue that these two types make Rust code difficult to write, because you have to think about which one you should be using in a given situation. My experience of writing Rust is that I don’t really think about…</description><pubDate>Wed, 16 Oct 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Rust has two main string types: &lt;code&gt;String&lt;/code&gt; and &lt;code&gt;&amp;amp;str&lt;/code&gt;. Sometimes, people argue
that these two types make Rust code difficult to write, because you have to
think about which one you should be using in a given situation. My experience
of writing Rust is that I don’t really think about this very much, and this
post is about some rules of thumb that you can use to be like me.&lt;/p&gt;
&lt;h2 id=&quot;level-1-dont-think-about-it-at-all&quot;&gt;Level 1: Don’t think about it at all&lt;/h2&gt;
&lt;p&gt;The very first thing you can do is follow the simplest rule:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Always use &lt;code&gt;String&lt;/code&gt;, never use &lt;code&gt;&amp;amp;str&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;That looks like this:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;rust&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;struct&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; Person&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    name&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; String&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;fn&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; first_word&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(words&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; String&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; String&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    words&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        .&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;split_whitespace&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        .&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;next&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        .&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;expect&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&amp;quot;words should not be empty&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        .&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;to_string&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This style means you may need to add &lt;code&gt;.to_string()&lt;/code&gt; or &lt;code&gt;.clone()&lt;/code&gt;
for things to work sometimes:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;rust&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;fn&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; main&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    let&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; sentence &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &amp;quot;Hello, world!&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;    println!&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&amp;quot;{}&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;first_word&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(sentence&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;to_string&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;()));&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    let&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; owned &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; String&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&amp;quot;A string&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;    // if we don&amp;#39;t clone here, we can&amp;#39;t use owned the second time&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;    println!&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&amp;quot;{}&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;first_word&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(owned&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;clone&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;()));&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;    println!&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&amp;quot;{}&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;first_word&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(owned));&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;But that’s okay, the compiler will let you know when you need to:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;text&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;error[E0382]: use of moved value: `owned`&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  --&amp;gt; src/main.rs:21:31&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;   |&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;18 |     let owned = String::from(&amp;quot;A string&amp;quot;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;   |         ----- move occurs because `owned` has type `String`, which does not implement the `Copy` trait&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;19 |&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;20 |     println!(&amp;quot;{}&amp;quot;, first_word(owned));&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;   |                               ----- value moved here&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;21 |     println!(&amp;quot;{}&amp;quot;, first_word(owned));&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;   |                               ^^^^^ value used here after move&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;   |&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;note: consider changing this parameter type in function `first_word` to borrow instead if owning the value isn&amp;#39;t necessary&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  --&amp;gt; src/main.rs:5:22&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;   |&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;5  | fn first_word(words: String) -&amp;gt; String {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;   |    ----------        ^^^^^^ this parameter takes ownership of the value&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;   |    |&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;   |    in this function&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;help: consider cloning the value if the performance cost is acceptable&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;   |&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;20 |     println!(&amp;quot;{}&amp;quot;, first_word(owned.clone()));&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;   |                                    ++++++++&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Hey, compiler, that’s a great idea. Let’s move on to level 2.&lt;/p&gt;
&lt;h2 id=&quot;level-2-prefer-str-for-function-parameters&quot;&gt;Level 2: prefer &lt;code&gt;&amp;amp;str&lt;/code&gt; for function parameters&lt;/h2&gt;
&lt;p&gt;A rule that’s a little better is this one:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Always use &lt;code&gt;String&lt;/code&gt; in structs, and for functions, use &lt;code&gt;&amp;amp;str&lt;/code&gt; for parameters
and &lt;code&gt;String&lt;/code&gt; types for return values.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This is what the compiler error for level 1 was suggesting we do instead of &lt;code&gt;.clone&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;That results in code that looks like this:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;rust&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;struct&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; Person&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    name&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; String&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;fn&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; first_word&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(words&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; &amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;str&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; String&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    words&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        .&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;split_whitespace&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        .&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;next&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        .&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;expect&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&amp;quot;words should not be empty&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        .&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;to_string&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;fn&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; main&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    let&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; sentence &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &amp;quot;Hello, world!&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;    println!&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&amp;quot;{}&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;first_word&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(sentence));&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    let&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; owned &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; String&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&amp;quot;A string&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;    println!&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&amp;quot;{}&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;first_word&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;owned));&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;    println!&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&amp;quot;{}&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;first_word&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;owned));&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We’re now doing much less copying. We do need to add a &lt;code&gt;&amp;amp;&lt;/code&gt; on
to &lt;code&gt;String&lt;/code&gt; values that we wish to pass into &lt;code&gt;first_word&lt;/code&gt;, but
that’s not too bad, the compiler will help us when we forget:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;text&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;error[E0308]: mismatched types&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  --&amp;gt; src/main.rs:20:31&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;   |&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;20 |     println!(&amp;quot;{}&amp;quot;, first_word(owned));&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;   |                    ---------- ^^^^^ expected `&amp;amp;str`, found `String`&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;   |                    |&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;   |                    arguments to this function are incorrect&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;   |&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;note: function defined here&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  --&amp;gt; src/main.rs:5:4&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;   |&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;5  | fn first_word(words: &amp;amp;str) -&amp;gt; String {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;   |    ^^^^^^^^^^ -----------&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;help: consider borrowing here&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;   |&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;20 |     println!(&amp;quot;{}&amp;quot;, first_word(&amp;amp;owned));&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;   |                               +&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Following this rule will get you through 95% of situations successfully. Yes,
that number was found via the very scientific process of “I made it up, but it
feels correct after writing Rust for the last twelve years.”&lt;/p&gt;
&lt;p&gt;For 4% of that last 5%, we can go to level 3:&lt;/p&gt;
&lt;h2 id=&quot;level-3-return-str-sometimes&quot;&gt;Level 3: return &lt;code&gt;&amp;amp;str&lt;/code&gt; sometimes&lt;/h2&gt;
&lt;p&gt;Here’s a slightly more advanced rule for certain circumstances:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Always use &lt;code&gt;String&lt;/code&gt; in structs, and for functions, use &lt;code&gt;&amp;amp;str&lt;/code&gt; for parameters.
If the return type of your function is derived from an argument and isn’t
mutated by the body, return &lt;code&gt;&amp;amp;str&lt;/code&gt;. If you run into any trouble here, return
&lt;code&gt;String&lt;/code&gt; instead.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;That would look like this:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;rust&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;struct&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; Person&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    name&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; String&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;// we&amp;#39;re returning a substring of words, so &amp;amp;str is appropriate&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;fn&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; first_word&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(words&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; &amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;str&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; &amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;str&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    words&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        .&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;split_whitespace&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        .&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;next&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        .&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;expect&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&amp;quot;words should not be empty&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;fn&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; main&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    let&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; sentence &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &amp;quot;Hello, world!&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;    println!&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&amp;quot;{}&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;first_word&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(sentence));&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    let&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; owned &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; String&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&amp;quot;A string&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;    println!&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&amp;quot;{}&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;first_word&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;owned));&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;    println!&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&amp;quot;{}&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;first_word&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;owned));&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This lets us remove a copy, we no longer have a &lt;code&gt;.to_string&lt;/code&gt; in the body of
&lt;code&gt;first_word&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Sometimes, we can’t do that though:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;rust&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;// because we are going to uppercase the first word, our return type can&amp;#39;t&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;// be &amp;amp;str anymore, because we aren&amp;#39;t actually returning a substring: we are&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;// creating our own new string.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;fn&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; first_word_uppercase&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(words&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; &amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;str&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; String&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    words&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        .&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;split_whitespace&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        .&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;next&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        .&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;expect&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&amp;quot;words should not be empty&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        .&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;to_uppercase&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;fn&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; main&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    let&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; sentence &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &amp;quot;Hello, world!&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;    println!&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&amp;quot;{}&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;first_word_uppercase&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(sentence));&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    let&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; owned &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; String&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&amp;quot;A string&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;    println!&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&amp;quot;{}&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;first_word_uppercase&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;owned));&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;    println!&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&amp;quot;{}&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;first_word_uppercase&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;owned));&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;How do you know that this is the case? Well, in this specific case,
&lt;code&gt;to_uppercase&lt;/code&gt; already returns a &lt;code&gt;String&lt;/code&gt;. So that’s a great hint.
If we tried to return a &lt;code&gt;&amp;amp;str&lt;/code&gt;, we’d get an error:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;rust&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;// this can&amp;#39;t work&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;fn&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; first_word_uppercase&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(words&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; &amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;str&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; &amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;str&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    &amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;words&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        .&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;split_whitespace&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        .&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;next&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        .&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;expect&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&amp;quot;words should not be empty&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        .&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;to_uppercase&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;would give us&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;text&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;error[E0515]: cannot return reference to temporary value&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  --&amp;gt; src/main.rs:7:5&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;   |&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;7  |        &amp;amp;words&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;   |  ______^-&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;   | | ______|&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;8  | ||         .split_whitespace()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;9  | ||         .next()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;10 | ||         .expect(&amp;quot;words should not be empty&amp;quot;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;11 | ||         .to_uppercase()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;   | ||                       ^&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;   | ||_______________________|&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;   |  |_______________________returns a reference to data owned by the current function&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;   |                          temporary value created here&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And that’s really it. Following this rule will get you through virtually every
scenario where you need to wonder about &lt;code&gt;String&lt;/code&gt; and &lt;code&gt;&amp;amp;str&lt;/code&gt;. With some practice,
you’ll internalize these rules, and when you feel comfortable with a level, you
can go up to the next one.&lt;/p&gt;
&lt;p&gt;What about that last 1% though? Well, there is a next level…&lt;/p&gt;
&lt;h2 id=&quot;level-4-when-to-use-str-in-a-struct&quot;&gt;Level 4: When to use &lt;code&gt;&amp;amp;str&lt;/code&gt; in a struct&lt;/h2&gt;
&lt;p&gt;Here’s the rule for level 4:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Should you use a &lt;code&gt;&amp;amp;str&lt;/code&gt; in a struct? If you’re asking that question, use
&lt;code&gt;String&lt;/code&gt;. When you need to use &lt;code&gt;&amp;amp;str&lt;/code&gt; in a struct, you’ll know.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Storing references in structs is useful, for sure, and it’s good that Rust
supports it. But you’re only going to need it in fairly specific scenarios,
and if you feel like you’re worrying about &lt;code&gt;String&lt;/code&gt; vs &lt;code&gt;&amp;amp;str&lt;/code&gt;, you’re just
not in the position to be worrying about the complexity of storing a &lt;code&gt;&amp;amp;str&lt;/code&gt;
in a struct yet.&lt;/p&gt;
&lt;p&gt;In fact, some people believe in this rule so strongly that they’re working
on a language where storing references in structs isn’t even possible, and
it’s a language I’ve found very interesting lately:
&lt;a href=&quot;https://www.hylo-lang.org/&quot;&gt;Hylo&lt;/a&gt;. They go a bit farther than that, even:
in Hylo, you think of everything as being values, rather than having references
at all. They think that you can write meaningful programs with this model.
But this isn’t a post about Hylo. I’ll write one of those eventually. My point
is just that you can really, truly, get away with not storing &lt;code&gt;&amp;amp;str&lt;/code&gt;s in structs
for a &lt;em&gt;lot&lt;/em&gt; of useful Rust programs. So it’s not really worth spending mental
energy on, until you determine that you must do so. That is the case when
you’ve profiled your program and determined that copying strings to and from
your struct is a big enough issue to bother with lifetimes.&lt;/p&gt;
&lt;p&gt;I hope you’ve found this helpful, and if you have any other rules of thumb
like this, I’d love to hear about them!&lt;/p&gt;
&lt;hr/&gt;
&lt;p&gt;Here’s my post about this post on BlueSky:&lt;/p&gt;
&lt;bluesky-post src=&quot;at://did:plc:3danwc67lo7obz2fmdg6jxcr/app.bsky.feed.post/3l6nkx54sij2w&quot; data-pagefind-ignore=&quot;true&quot;&gt; &lt;div class=&quot;bluesky-embed s-3olstj&quot;&gt;&lt;div class=&quot;highlighted-post s-hik11q&quot;&gt;&lt;div class=&quot;meta s-hik11q&quot;&gt;&lt;a href=&quot;https://bsky.app/profile/did:plc:3danwc67lo7obz2fmdg6jxcr&quot; target=&quot;_blank&quot; class=&quot;avatar-wrapper s-hik11q&quot;&gt;&lt;img loading=&quot;lazy&quot; src=&quot;https://cdn.bsky.app/img/avatar/plain/did:plc:3danwc67lo7obz2fmdg6jxcr/bafkreidffwgsdli2xp56t3kfemk7bryow3mygu7zbvgcsxgsu3ntnp4hwm&quot; alt=&quot;&quot; class=&quot;avatar s-hik11q&quot;/&gt;&lt;/a&gt; &lt;a href=&quot;https://bsky.app/profile/did:plc:3danwc67lo7obz2fmdg6jxcr&quot; target=&quot;_blank&quot; class=&quot;name-wrapper s-hik11q&quot;&gt;&lt;bdi class=&quot;display-name-wrapper s-hik11q&quot;&gt;&lt;span class=&quot;display-name s-hik11q&quot;&gt;Steve Klabnik&lt;/span&gt;&lt;/bdi&gt; &lt;span class=&quot;handle s-hik11q&quot;&gt;@steveklabnik.com&lt;/span&gt;&lt;/a&gt; &lt;svg class=&quot;logo s-hik11q&quot; fill=&quot;none&quot; viewBox=&quot;0 0 320 286&quot;&gt;&lt;path fill=&quot;#0A7AFF&quot; d=&quot;M69.364 19.146c36.687 27.806 76.147 84.186 90.636 114.439 14.489-30.253 53.948-86.633 90.636-114.439C277.107-.917 320-16.44 320 32.957c0 9.865-5.603 82.875-8.889 94.729-11.423 41.208-53.045 51.719-90.071 45.357 64.719 11.12 81.182 47.953 45.627 84.785-80 82.874-106.667-44.333-106.667-44.333s-26.667 127.207-106.667 44.333c-35.555-36.832-19.092-73.665 45.627-84.785-37.026 6.362-78.648-4.149-90.071-45.357C5.603 115.832 0 42.822 0 32.957 0-16.44 42.893-.917 69.364 19.147Z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/div&gt;  &lt;p class=&quot;rich-text is-large s-1lecfnd&quot;&gt;When should you use String vs &amp;amp;str? 

Some &lt;a target=&quot;_blank&quot; href=&quot;https://bsky.app/hashtag/rustlang&quot; class=&quot;hashtag s-1lecfnd&quot;&gt;#rustlang&lt;/a&gt; rules of thumb

&lt;a target=&quot;_blank&quot; href=&quot;https://steveklabnik.com/writing/when-should-i-use-string-vs-str/&quot; rel=&quot;noopener nofollow&quot; class=&quot;link s-1lecfnd&quot;&gt;steveklabnik.com/writing/when...&lt;/a&gt;&lt;/p&gt; &lt;div class=&quot;embeds s-azdpbr&quot;&gt;&lt;a target=&quot;_blank&quot; href=&quot;https://steveklabnik.com/writing/when-should-i-use-string-vs-str/&quot; rel=&quot;noopener noreferrer nofollow&quot; class=&quot;external-embed s-rtbqd8&quot;&gt; &lt;div class=&quot;meta s-rtbqd8&quot;&gt;&lt;p class=&quot;title s-rtbqd8&quot;&gt;When should I use String vs &amp;amp;str?&lt;/p&gt; &lt;p class=&quot;description s-rtbqd8&quot;&gt;&lt;/p&gt; &lt;div class=&quot;domain s-rtbqd8&quot;&gt;&lt;svg class=&quot;icon&quot; fill=&quot;none&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path stroke=&quot;currentColor&quot; stroke-linecap=&quot;round&quot; stroke-width=&quot;2&quot; d=&quot;m4.172 8.07 3.94 2.957.977-1.941 3.887-.978 1.15-4.6M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Zm-6.078 4.865.973-1.946-2.869-1.928-1.89-.12-1.08 1.075 1.947 2.919h2.919Z&quot;&gt;&lt;/path&gt;&lt;/svg&gt; &lt;span class=&quot;domain-name&quot;&gt;steveklabnik.com&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/a&gt;&lt;/div&gt; &lt;time datetime=&quot;2024-10-16T18:27:49.871Z&quot; class=&quot;date s-hik11q&quot;&gt;October 16, 2024 at 6:27 PM&lt;/time&gt; &lt;div class=&quot;stats s-hik11q&quot;&gt;&lt;span class=&quot;stat s-hik11q&quot; title=&quot;287 likes&quot;&gt;&lt;svg class=&quot;icon&quot; fill=&quot;none&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; d=&quot;M12 5.768c6.162-6.25 16.725 5.358 0 14.732C-4.725 11.126 5.838-.482 12 5.768Z&quot;&gt;&lt;/path&gt;&lt;/svg&gt; &lt;span&gt;287&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;stat s-hik11q&quot; title=&quot;43 reposts&quot;&gt;&lt;svg class=&quot;icon&quot; fill=&quot;none&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path stroke=&quot;currentColor&quot; stroke-linecap=&quot;square&quot; stroke-width=&quot;2&quot; d=&quot;m17 3 3 3-3 3M7 21l-3-3 3-3m-2 3h15v-5M4 11V6h15&quot;&gt;&lt;/path&gt;&lt;/svg&gt; &lt;span&gt;43&lt;/span&gt;&lt;/span&gt; &lt;div class=&quot;gap s-hik11q&quot;&gt;&lt;/div&gt; &lt;a href=&quot;https://bsky.app/profile/did:plc:3danwc67lo7obz2fmdg6jxcr/post/3l6nkx54sij2w&quot; target=&quot;_blank&quot; class=&quot;permalink s-hik11q&quot;&gt;&lt;span&gt;Read 30 replies on Bluesky&lt;/span&gt;&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt; &lt;/bluesky-post&gt;</content:encoded></item><item><title>Memory Safety is a Red Herring</title><link>https://steveklabnik.com/writing/memory-safety-is-a-red-herring/</link><guid isPermaLink="true">https://steveklabnik.com/writing/memory-safety-is-a-red-herring/</guid><description>TL;DR: I think that a focus on memory safe languages (MSLs) versus non memory-safe languages is a bit of a red herring. The actual distinction is slightly bigger than that: languages which have defined behavior by default, with a superset where undefined behavior is possible, vs…</description><pubDate>Thu, 21 Dec 2023 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;TL;DR:&lt;/p&gt;
&lt;p&gt;I think that a focus on memory safe languages (MSLs) versus non memory-safe
languages is a bit of a red herring. The actual distinction is slightly bigger
than that: languages which have defined behavior by default, with a superset
where undefined behavior is possible, vs languages which allow for undefined
behavior anywhere in your program. Memory safety is an important aspect of this,
but it is necessary, not sufficient. Rust’s marketing has historically focused
on memory safety, and I don’t think that was a bad choice, but I do wonder
sometimes. Finally, I wonder about the future of the C++ successor languages in
the face of coming legislation around MSLs for government procurement.&lt;/p&gt;
&lt;p&gt;Additionally, I would like to thank ixi for discussing some of this stuff with
me. I do not claim that they agree with me, these opinions are solely my own!
But talking about it helped me form those opinions.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&quot;threadid1&quot;&gt;ThreadId(1)&lt;/h2&gt;
&lt;p&gt;Today I have been programming in Rust for 11 years. I usually write some sort
of blog post reflecting on the year. This year, I am reflecting on some old
questions:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Should Rust have focused so much on memory safety in its advocacy?&lt;/li&gt;
&lt;li&gt;Does Rust conflate a more general concept of “safety” with “memory safety?”&lt;/li&gt;
&lt;li&gt;What do people even mean by “memory safe languages?”&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;But before we get there, we have to talk about some other things.&lt;/p&gt;
&lt;h2 id=&quot;threadid2&quot;&gt;ThreadId(2)&lt;/h2&gt;
&lt;p&gt;The other day, someone &lt;a href=&quot;https://news.ycombinator.com/item?id=38616605&quot;&gt;asked an interesting question on Hacker
News&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Can someone with a security background enlighten me, on why Python is on the
list of “memory safe” languages? Most of the python code I have worked with is
a thin wrapper on C. Wouldnt that make python vulnerable as well?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This is a very reasonable question! If you click the link, you’d see my answer:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;You are correct that if you call C from Python, you can run into problems. But
the fault there lies with the C, not the Python. Pure Python itself is memory
safe.&lt;/p&gt;
&lt;p&gt;Because memory safety is built on top of memory unsafety, it is generally
understood that when discussing things at this sort of level, that we are
speaking about the Python-only subset. (Same as any other memory safe language.)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;But this has been gnawing at me for a while. Like it’s one of those things that
“everybody knows what I mean.” But isn’t that kind of… bullshit? Like something
is wrong with your definitions. But on the other hand, if we accept FFI as
being not safe, and that since you can FFI from anywhere, that means it’s also
unsafe, then every single program is unsafe. Your operating system does not
offer memory-safe APIs. To do anything useful, you must call into the operating
system. This means every program would be infected via this conception of safety,
and therefore, as a definition, it would be useless.&lt;/p&gt;
&lt;p&gt;If we instead make an exception for a language’s runtime, which is allowed to
make unsafe calls, but users’ code is not, that would draw an appropriate
boundary: only write code in the guest language, and you don’t have to worry
about safety anymore. And I think that this sort of definition has been the
default for many years. You have “managed” languages which are safe, and you have
“unmanaged” languages which are unsafe. Unmanaged languages are used to implement
managed languages. What’s that? A Java runtime written in Java? A Ruby runtime
written in Ruby? Yeah those are weird exceptions. Ignore those. And those
“native extensions” that segfault? Well they aren’t written in the host language,
so of course that will happen, and yeah it’s kinda annoying when it happens, but
it’s fine. Sometimes you have to risk it for performance.&lt;/p&gt;
&lt;p&gt;I just don’t find this satisfying. It’s too vague. You just kinda know it when
you see it. Ignore FFI, and we’re good. And sometimes, you just can’t have safety.
What if you want to write a runtime? You’re gonna need to call into the system
directly, and now we’re back to unsafe, so just use an unsafe language. It is
what it is.&lt;/p&gt;
&lt;h2 id=&quot;threadid3&quot;&gt;ThreadId(3)&lt;/h2&gt;
&lt;p&gt;That comment is on an article titled &lt;a href=&quot;https://media.defense.gov/2023/Dec/06/2003352724/-1/-1/0/THE-CASE-FOR-MEMORY-SAFE-ROADMAPS-TLP-CLEAR.PDF&quot;&gt;The Case for Memory Safe
Roadmaps: Why Both C-Suite Executives and Technical Experts
Need to Take Memory Safe Coding Seriously
&lt;/a&gt;.
This document, published by &lt;a href=&quot;https://en.wikipedia.org/wiki/Five_Eyes&quot;&gt;the Five Eyes&lt;/a&gt;,
suggests… that executives and technical experts need to take memory safety
seriously. Call it boring if you want, but it is what it says on the tin.&lt;/p&gt;
&lt;p&gt;More specifically, it says:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Memory safe programming languages (MSLs) can eliminate memory safety
vulnerabilities.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;As well as an appendix, “Memory Safe Languages,” which describes C#, Go, Java,
Python, Rust, and Swift as memory safe languages.&lt;/p&gt;
&lt;p&gt;Finally, it says:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Programming languages such as C and C++ are examples of memory unsafe programming
languages that can lead to memory unsafe code and are still among the most widely used
languages today.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;But it also acknowledges the reality that sometimes you can get around memory
safety:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;MSLs, whether they use a garbage collection model or not, will almost
certainly need to rely on libraries written in languages such as C and C++.
Although there are efforts to re-write widely used libraries in MSLs, no such
effort will be able to re-write them all anytime soon.&lt;/p&gt;
&lt;p&gt;For the foreseeable future, most developers will need to work in a hybrid model
of safe and unsafe programming languages. Developers who start writing in an MSL
will need to call C and C++ libraries that are not memory safe. Likewise, there
are going to be situations where a memory unsafe application needs to call into
a memory safe library. When calling a memory unsafe component or application,
the calling application needs to be explicitly aware of—and limit any input
passed to—the defined memory bounds.&lt;/p&gt;
&lt;p&gt;The memory safety guarantees offered by MSLs are going to be qualified when data
flows across these boundaries. Other potential challenges include differences
in data marshalling, error handling, concurrency, debugging, and versioning.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Okay, that’s enough quoting from the report. And I swear I’m not about to say
nice things about it because I am cited as #42, though to be honest it’s real
fucking weird that searching “klabnik” on a page on defense.gov returns 1/1.
But I think this is an excellent formulation of the critical distinction between
the languages on one side of the line versus the other, though they make the
same conceptual mistake that I believe Rust may have: it’s not just about
memory unsafety. “safety” itself is basically the idea that most of the time,
you’re in a universe where everything is peachy keen, and occasionally, you’ll
need to reach across that line into the scary other place, but you gotta do what
you gotta do. But there is a line there. But that line is more abstract than
just memory safety.&lt;/p&gt;
&lt;h2 id=&quot;threadid4&quot;&gt;ThreadId(4)&lt;/h2&gt;
&lt;p&gt;Rust often describes itself as “data race free.” But what the heck is a data
race anyway? Here’s &lt;a href=&quot;https://blog.regehr.org/archives/490&quot;&gt;John Regehr&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;A data race happens when there are two memory accesses in a program where both:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;target the same location&lt;/li&gt;
&lt;li&gt;are performed concurrently by two threads&lt;/li&gt;
&lt;li&gt;are not reads&lt;/li&gt;
&lt;li&gt;are not synchronization operations&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;There are other definitions but this one is fine; it’s from Sebastian Burckhardt at Microsoft Research.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Oh. Well, I guess “Here’s Sebastian Burckhardt:” instead.&lt;/p&gt;
&lt;p&gt;Point is, data races are undefined behavior in Rust, and they’re also undefined
behavior in C++. When looking for a succinct citation for that fact, I came
across &lt;a href=&quot;https://www.hboehm.info/c++mm/why_undef.html&quot;&gt;this 2006 post by Hans Boehm&lt;/a&gt;.
Its first line:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Our proposed C++ memory model gives completely undefined semantics to programs
with data races.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I believe this was the model that was accepted, so that’s the best citation you’re
gonna get from me. Okay, as soon as I read that I said “come on Steve, that’s stupid,
make sure it’s not just trivial to actually find in the standard” and lo and
behold
&lt;a href=&quot;https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/n4849.pdf&quot;&gt;n4849&lt;/a&gt;
says:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The execution of a program contains a data race if it contains two potentially
concurrent conflicting actions, at least one of which is not atomic, and
neither happens before the other, except for the special case for
signal handlers described below. Any such data race results in undefined
behavior.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Okay, the real citation was easier. The article by Bohm is still fascinating.&lt;/p&gt;
&lt;p&gt;But data races aren’t undefined behavior in every programming language. For
example, let’s consider both Java and Go. Now I hate that I even have to
preemptively say this, but I am &lt;em&gt;not&lt;/em&gt; saying Java and Go are bad. I think
these are good decisions for both of the two languages. And I think their
decisions here are very informative. Language wars are stupid. Stop it.&lt;/p&gt;
&lt;p&gt;Java was the first time I remember hearing, “yeah you can have data races but
like, it’s fine” about. I kinda lodged that fact in the back of my brain, and
didn’t think about it much. But lately, I was wondering. So I went and read
the Java specification, and more specifically, &lt;a href=&quot;https://docs.oracle.com/javase/specs/jls/se21/html/jls-17.html&quot;&gt;Chapter
17&lt;/a&gt;. It contains
this text:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The semantics of operations other than inter-thread actions, such as reads of
array lengths (§10.7), executions of checked casts (§5.5, §15.16), and
invocations of virtual methods (§15.12), are not directly affected by data
races.&lt;/p&gt;
&lt;p&gt;Therefore, a data race cannot cause incorrect behavior such as returning the
wrong length for an array.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This is morally equivalent to “not undefined behavior” even though the
specification doesn’t define “undefined behavior” in the way that the C, C++,
and Rust specifications do. Notably, the specification also defines “data race”
in a slightly different way:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;When a program contains two conflicting accesses (§17.4.1) that are not
ordered by a happens-before relationship, it is said to contain a data race.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Not just any ordering or synchronization primitive, a happens-before relation
specifically. Fun! We have three technically-slightly different but basically
morally equivalent ways of defining a data race. Let’s do a fourth. Go also
allows data races. Sort of. From &lt;a href=&quot;https://go.dev/ref/mem&quot;&gt;the Go memory model&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;A data race is defined as a write to a memory location happening concurrently
with another read or write to that same location, unless all the accesses
involved are atomic data accesses as provided by the sync/atomic package.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Given that Rust provides atomic ordering operations in a submodule of its
standard library, Rust and Go agree here, though Go’s more specific about naming
it.&lt;/p&gt;
&lt;p&gt;But they also have this to say:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;While programmers should write Go programs without data races, there are
limitations to what a Go implementation can do in response to a data race. An
implementation may always react to a data race by reporting the race and
terminating the program. Otherwise, each read of a single-word-sized or
sub-word-sized memory location must observe a value actually written to that
location (perhaps by a concurrent executing goroutine) and not yet overwritten.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;So it’s not right, but it’s also not exactly UB. It goes on:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;These implementation constraints make Go more like Java or JavaScript, in that
most races have a limited number of outcomes, and less like C and C++, where the
meaning of any program with a race is entirely undefined, and the compiler may
do anything at all. Go’s approach aims to make errant programs more reliable and
easier to debug, while still insisting that races are errors and that tools can
diagnose and report them.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;While a Go program may exhibit what a Rust or C++ program would consider
undefined behavior, and it does also consider it an error, the consequences are
very different. You don’t get time travel. You get 998 instead of 1,000.&lt;/p&gt;
&lt;p&gt;(After publication, Edoardo Spadolini reached out to me and we had a productive
conversation about the above paragraph: while my overall point here is still
valid, there are slightly more serious consequences to UB in a Go program than
slightly incorrect sums. For example, torn writes to a slice can lead to serious
consequences, and there are other ways to write code that exploits UB to be
actively malicious, such as a function with the signature
&lt;code&gt;func Cast[T any](addr uintptr) *T&lt;/code&gt; that works. However, it’s also worth mentioning
that Go ships with a race detector, available by simply passing &lt;code&gt;-race&lt;/code&gt;. For some
interesting usage of this at scale, check out &lt;a href=&quot;https://www.uber.com/blog/dynamic-data-race-detection-in-go-code/&quot;&gt;this post by Uber&lt;/a&gt;. At the end of the day, this is still
very different than the “your whole program is invalid” style of issues you
can end up with in C or C++, I am slightly underselling the danger above.)&lt;/p&gt;
&lt;p&gt;Go also provides &lt;a href=&quot;https://go.dev/ref/spec#Package_unsafe&quot;&gt;an unsafe package&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The built-in package unsafe, known to the compiler and accessible through the
import path “unsafe”, provides facilities for low-level programming including
operations that violate the type system. A package using unsafe must be vetted
manually for type safety and may not be portable.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Oh yeah, I forgot, Java also has &lt;code&gt;sun.misc.unsafe&lt;/code&gt;, essentially the same thing.
They have actually wanted to remove it for a long time, and some progress has
been made, but it’s not quite gone yet. &lt;a href=&quot;https://blogs.oracle.com/javamagazine/post/the-unsafe-class-unsafe-at-any-speed&quot;&gt;The Unsafe Class: Unsafe at Any
Speed&lt;/a&gt;
is a good explanation of the topic.&lt;/p&gt;
&lt;h2 id=&quot;threadid5&quot;&gt;ThreadId(5)&lt;/h2&gt;
&lt;p&gt;One weird thing about suggesting that the borrow checker is only about memory
safety, and that memory safety means the absence of data races, is that memory
safety is more than just the absence of data races. Consider a problem that
requires no threads to become an issue: iterator invalidation. And different
languages have different answers to this issue:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;In C++, it is undefined behavior.&lt;/li&gt;
&lt;li&gt;In Java, some data structures detect this and throw a &lt;code&gt;ConcurrentModificationException&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;In JavaScript, Ruby, and other languages, you often get “weird” behavior:&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;ruby&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;numbers&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; [&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;3&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;4&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;numbers.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;each&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; do&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; |number|&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;  p&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; number&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  numbers.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;shift&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;end&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;p&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; numbers&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;prints&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;text&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;1&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;3&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;[3, 4]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;But you don’t get full-blown time-travel undefined behavior. Sort of like this
code in Rust:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;rust&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;fn&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; main&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    let&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; i &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; i32&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;MAX&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; +&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 1&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;    println!&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;{i}&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Okay in this case because it’s all at compile time Rust can detect it:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;text&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;error: this arithmetic operation will overflow&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt; --&gt; src/main.rs:2:13&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  |&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;2 |     let i = i32::MAX + 1;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  |             ^^^^^^^^^^^^ attempt to compute `i32::MAX + 1_i32`, which would overflow&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  |&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  = note: `#[deny(arithmetic_overflow)]` on by default&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;But in the general case, you won’t get a compile error. You may get a panic, you
may get &lt;code&gt;-2147483648&lt;/code&gt;. It’s weird. But it’s not full-blown time-travel undefined
behavior.&lt;/p&gt;
&lt;p&gt;Anyway, back to iterator invalidation:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;In Rust, it is prevented at compile time.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This is neat! This is cool! This is good! And it’s pretty unique to Rust.&lt;/p&gt;
&lt;p&gt;It is nice when our programs do what we expect, instead of what we don’t expect.
It is even nicer when, if our programs don’t do what we expect, we have some sort
of waypost, some sort of sign where the problem might be. What “nice” means may
be a bit different in different languages, but the boundary is the important
part: we’re gonna have to potentially violate the rules somewhere, so at least
give us some help when that inevitably goes wrong. Over here, logic bugs may
happen, some weird behavior may result, but over there? There be dragons.
Nobody can save you out there. Tread carefully.&lt;/p&gt;
&lt;h2 id=&quot;threadid6&quot;&gt;ThreadId(6)&lt;/h2&gt;
&lt;p&gt;If we think about all of these designs, they all are very similar conceptually:
safe code is the default, but you can call into some sort of unsafe facility.
And everyone is very clear on the relationship between the two: while the unsafe
facility exists to be used, it must uphold the rules that the safe world relies
on. And that means that safety and unsafety have a super/sub-set relationship.
In the core is unsafety. But at some point, we draw a line, and on top of that
line, safety exists.&lt;/p&gt;
&lt;p&gt;In Rust, we often talk about how unsafe is great, because it clearly draws a
line around code with which serious bugs may happen. More specifically, while
most people describe it as “where memory safety can originate from” or similar,
it’s actually slightly broader than that: it’s where undefined behavior can
originate from.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://doc.rust-lang.org/reference/behavior-considered-undefined.html&quot;&gt;The nomicon&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Rust code is incorrect if it exhibits any of the behaviors in the following
list. This includes code within unsafe blocks and unsafe functions. unsafe
only means that avoiding undefined behavior is on the programmer; it does not
change anything about the fact that Rust programs must never cause undefined
behavior.&lt;/p&gt;
&lt;p&gt;It is the programmer’s responsibility when writing unsafe code to ensure that
any safe code interacting with the unsafe code cannot trigger these behaviors.
unsafe code that satisfies this property for any safe client is called sound;
if unsafe code can be misused by safe code to exhibit undefined behavior, it
is unsound.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This is not a new insight, but basically, unsafe is like FFI in a managed
language. It’s not something you do often. But it is something you sometimes
have to do. And when you do, you can at least contain the danger: the problem
has to lie somewhere behind that veil. You have clear points to begin your
search into where the issues lie, should the abyss claim another soul.&lt;/p&gt;
&lt;p&gt;In some ways I’m also repeating another older slogan Rust had: “memory safety
without garbage collection.” But it’s more like “no UB and no garbage collection.”
Gosh, why didn’t we put &lt;em&gt;that&lt;/em&gt; on the website? Practically rolls right off the
tongue. What makes Rust appealing, and I think especially to the “non-systems”
crowd, is that it shares a property of many managed languages, that of “no
undefined behavior by default,” with a property of many systems languages, that
of “no runtime, as little overhead as possible.” And sure, there’s an escape
hatch, but it’s rarely used, and clearly separates the two worlds. This is a
fundamentally different way of viewing the world than “unsafe by default.”&lt;/p&gt;
&lt;p&gt;Another way in which there’s an interesting split here in language design
is between the scripting languages like Ruby, Python, and JavaScript, and
languages like Rust, Go, and Java, is that the boundary in the former is purely
FFI, while in the latter, there are also unsafe faculties in the host language
itself, as well as with FFI. In all three cases, they’re behind either a specific
package or &lt;code&gt;unsafe {}&lt;/code&gt;, but they give you some interesting tools that don’t
require you to use another language to use. I think this is an under-appreciated
part of the overall design space.&lt;/p&gt;
&lt;h2 id=&quot;threadsinto_iterfor_eacht-tjoinunwrap&quot;&gt;threads.into_iter().for_each(|t| t.join().unwrap());&lt;/h2&gt;
&lt;p&gt;So: did Rust focus too much on memory safety? And what should newer languages
do in this area?&lt;/p&gt;
&lt;p&gt;Well, I think that in some sense, the answer is obviously “no, Rust did not
focus too much on memory safety.” Rust has been wildly successful, reaching
heights that I only could dream about eleven years ago. Yes, usually I have
tried to be fairly tempered when talking about Rust’s successes, and some
folks still try to claim Rust is still super niche. But when I think about the
ways that Rust touched even this blog post, it’s staggering: I wrote this post
in VS: Code, which uses Rust, on Windows, which has Rust in the kernel. I
published it to GitHub, which uses Rust for code search. I previewed it in
Chrome, which uses some Rust today and may start having more tomorrow. It’s
hosted on Vercel, which uses Rust in projects like turbopack, though maybe not
in the critical path for this post. When you read it, the bytes probably passed
through CloudFlare, which uses a ton of Rust, and maybe you’re reading this in
Firefox, which is about 12% Rust. And maybe you’re on Asahi Linux, where the
GPU drivers are written in Rust. Rust has Made It, and is here to stay. And
the marketing we used got us here. So in some sense, it would be silly to
declare said messaging a failure.&lt;/p&gt;
&lt;p&gt;However, I also wonder what else could have been. Could Rust have grown faster
with a different message? Maybe. That said, what would that message be?
“Undefined behavior is scary?” I’m not sure that’s as compelling, even if I think
it’s actually a bigger deal. While memory unsafety is only part of undefined
behavior, it is the part that is easy to understand: pointers are the bane of
every C newbie. It has consequences that are easy to understand: security
vulnerabilities are bad. Has Rust &lt;em&gt;really&lt;/em&gt; conflated “memory safety” and “safety”
that much? I don’t actually think so. People still talk about SQL injection,
about Remote Code Execution, about Cross Site Scripting. People don’t &lt;em&gt;really&lt;/em&gt;
believe that just because it’s written in Rust, bugs are impossible. Sure you
can find a few comments on the internet as such, but the big organizations that
are using Rust for meaningful work do not take this position. Given &lt;a href=&quot;https://en.wikipedia.org/wiki/Amdahl%27s_law&quot;&gt;Amdahl’s
Law&lt;/a&gt;, if 70% of security
vulnerabilities are related to memory safety, focusing so strongly on it makes
sense, as fixing that will give you a much larger impact than other things.&lt;/p&gt;
&lt;p&gt;So what should new languages do here? Well, pretty much the only language that
is gaining developer mindshare that’s new and is memory unsafe by default is
Zig. I think Andrew is very sharp, and a tremendous engineer. I am very
interested to see how things shake out there. But as a language, it does not
appeal to me personally, because I think we’ve sort of moved past “unsafe by
default.” That being said, it’s also not that Zig is exactly like other
languages in this space either: if we are willing to go beyond “memory unsafe vs
memory safe at compile time” as a strict binary, and instead look at “memory
unsafe at compile time” itself, we see a pretty big gradient. Zig is doing a
bunch of things to mitigate issues where possible. Maybe “safe enough” truly is
safe enough. Time will tell. But beyond that, you also don’t have to go full
Rust in the design space. Rust wants to be a language that you can (and at
Oxide,  we do) use at the lowest levels of the system. But also memory safe.
And extremely fast. These constraints mean that Rust takes on a lot of
complexity in the type system, where languages that are willing to relax these
things wouldn’t have to. Here are three languages that I think are sort of
“post-Rust” in a sense, that are learning from Rust but putting their own
twist on things:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.hylo-lang.org/&quot;&gt;Hylo&lt;/a&gt; (formerly Val) tries to, in their own words,
“strengthens [value semantics], while de-emphasizing reference semantics”.
This lets them avoid a lot of Rust’s complexity. Hylo looks more explicitly
to Swift than Rust for positive inspiration in many cases, but I’m including
it here anyway, as I’ve sort of ended up not talking about Swift in this post.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://austral-lang.org/&quot;&gt;Austral&lt;/a&gt; is “if affine types are good for systems
programming, linear types are even better.” Austral also believes that parsimony
is a virtue in language design, and that linear types can replace a lot of
different features in other programming languages, while also eschewing other
features that they deem as not carrying their weight.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.modular.com/max/mojo&quot;&gt;Mojo&lt;/a&gt;, “the usability of Python with the
performance of C.” It also has this sort of “lower into a more complex language”
idea; you can Just Write Python for the most part and it works, but if you want
to get fancier, you can. &lt;a href=&quot;https://github.com/modularml/mojo/blob/main/proposals/lifetimes-and-provenance.md&quot;&gt;Lifetimes are a current
proposal.&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I think there are some other languages that are forming the next big cohort of
programming languages, and they’re interesting too, but these three I think have
the most explicit connection to Rust in the design and goals of the language
itself. Shout out to Nu, Inko, Gleam, Roc, Oil Shell, Unison, and others. Lots
of cool stuff going on.&lt;/p&gt;
&lt;h2 id=&quot;int-atexitvoid-funcvoid&quot;&gt;int atexit(void (*func)(void))&lt;/h2&gt;
&lt;p&gt;There is one way in which the question “is the focus on memory unsafety
misguided?” is much more serious than battles in the comment sections of
various fora: the government.&lt;/p&gt;
&lt;p&gt;We talked about this earlier, but various government organizations have been
slowly putting out recommendations that organizations should be moving towards
MSLs. And the first reactions to these were always “well they’re not laws so
they don’t have teeth” as well as “laws are inevitably coming.” To be honest,
I have mostly been in the former camp, and viewed the later as fearmongering.
Sure, maybe someday, but like, dipping your toes in does not mean that you’re
about to cannonball moments later.&lt;/p&gt;
&lt;p&gt;But then I got &lt;a href=&quot;https://news.ycombinator.com/item?id=38700267&quot;&gt;this interesting reply from David Tolnay on Hacker
News&lt;/a&gt;. In it, he refers me to
&lt;a href=&quot;https://adspthepodcast.com/about/&quot;&gt;ADSP: The Podcast&lt;/a&gt;, and more specifically,
&lt;a href=&quot;https://adspthepodcast.com/2023/12/15/Episode-160.html&quot;&gt;Episode 160: Rust &amp;#x26; Safety at Adobe with Sean
Parent&lt;/a&gt;. In it, Sean
makes reference to two pieces of legislation, &lt;a href=&quot;https://www.congress.gov/bill/118th-congress/house-bill/2670&quot;&gt;one in the
US&lt;/a&gt;
and &lt;a href=&quot;https://digital-strategy.ec.europa.eu/en/library/cyber-resilience-act&quot;&gt;one in
the EU&lt;/a&gt;.
Now, I am not a politican, and these bills are huge, so I wasn’t able to figure
out how these bills do this specifically, but to quote Sean:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The one in the U.S. that’s pending basically says that the Department of
Defense is going to within 270 days of the bill passing (and it’s a funding bill
which means it will probably pass late this year - early next year) that the
Department of Defense will establish guidelines around safety and security
including memory safety for software products purchased by Department of
Defense. The E.U. has a similar wording in a bill that’s slowly winding its way
through their channels. I don’t have insight into when that will pass. The U.S.
one will almost certainly pass here within a month or two.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This sounds much more realistic, of course. Now, this does not mean that
C++ is outlawed or something silly like that, but it does mean that using Rust
could become a more serious competitive advantage when it comes to selling to
government: if you don’t need an exception for your product, that’s an advantage
over a product which does.&lt;/p&gt;
&lt;p&gt;This all also may go the way of another anecdote Sean talks about in the past:
when a similar bill tried to mandate POSIX compliance. What I’m saying is, go
listen to the podcast. And while this still isn’t something as wild as “not
using MSLs is illegal,” it is really shocking to me how quickly things seem to
be moving in that vague direction, though of course it will never actually
arrive there. There seems to be at least some sort of thinking that’s not
immediately lauged out of the room that memory unsafety could be a consumer
safety issue in a similar sense that other unsafe materials are a consumer
safety issue. Is that right? I’m not sure, but it seems to be where the
conversation is heading.&lt;/p&gt;
&lt;p&gt;So where does that leave existing widely used memory-unsafe languages? Well,
the C++ community has… had a wide variety of discussions on this topic. I
should also say I mean “community” at large, and the committee feels like it
has a big divide as well. Now I should re-iterate that while I pay attention to
the C++ standardization process, I am very much an outsider: I have never
attended a meeting, I have no direct involvement in these things, I just read
a lot. And while historically most of the community wrote Rust off as a novelty,
I think that at this point, those with their head in the sand about Rust’s usage
are mostly a fringe minority. But the big question that remains is, what to do?&lt;/p&gt;
&lt;p&gt;Two approaches have appeared:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Improve the safety of C++ in some fashion.&lt;/li&gt;
&lt;li&gt;Create a “successor language” that will fix C++‘s problems.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;What is interesting to me about these approaches is that they are both good,
for different reasons. The former is a sort of harm reduction approach: don’t
let the perfect be the enemy of the good. &lt;a href=&quot;https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p3023r1.html&quot;&gt;What can we do today to improve the
lives of a ton of
people?&lt;/a&gt;
But if you want to move into the realm of an MSL, you have to break backwards
compatibility. This is tantamount to just doing #2 in the first place, and so
some are cutting straight to that approach. But if we look at it in a slightly
different way, an interesting thing happens:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;breaking backwards compatibility vs not&lt;/li&gt;
&lt;li&gt;memory safety by default vs not&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This leads to four approaches:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;We do not break backwards compatibility, and we ignore the memory safety
issue (this is the ‘do nothing’ option).&lt;/li&gt;
&lt;li&gt;We do not break backwards compatibility, but we try to make things as memory
safe as possible given the constraints we have.&lt;/li&gt;
&lt;li&gt;We break backwards compatibility, and we try to make things as memory safe as
possible but still remain unsafe.&lt;/li&gt;
&lt;li&gt;We break backwards compatibility, and we become memory safe by default.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The first option is seemingly untenable, but is also where I see C heading.
There’s seemingly not nearly as much desire for movement in the C space as the
C++ space, even though I am following what JeanHeyd Meneide is doing and
appreciate it.&lt;/p&gt;
&lt;p&gt;The second option is how I view at least one of the possible C++ successor
languages, &lt;a href=&quot;https://www.circle-lang.org/&quot;&gt;Circle&lt;/a&gt;. Circle is incredibly
interesting and is worth its own post. But in short, it is a C++ compiler that
also implements a lot of extensions, both ones that are proposals in the
committee, but also ones that its author is interested in. He has been doing
lifetime experiments.&lt;/p&gt;
&lt;p&gt;The third option is where the most famous successor languages live:
&lt;a href=&quot;https://github.com/carbon-language/carbon-lang&quot;&gt;Carbon&lt;/a&gt; and
&lt;a href=&quot;https://github.com/hsutter/cppfront&quot;&gt;cpp2&lt;/a&gt;. I haven’t gotten to spend a ton of
time with either of these yet, but they explicitly aim to do to C++ what C++ did
to C, or what TypeScript did to JavaScript: create a new language for new code,
while allowing you to use the older language for older code. This allows them
to break backwards compatibility more easily: new code can more easily be
written under the new constraints. This gives them a larger degree of freedom
to make changes, which may be necessary to move the needle significantly on
the safety issue. But to my knowledge, they do not attempt to be memory safe
by default. They’re conceptually similar to Zig in this way.&lt;/p&gt;
&lt;p&gt;But what about a fourth option? What if someone did a TypeScript for C++, but
one that was closer to what Rust does? You might argue that this is basically
just Rust? (Interestingly, it is also sort of what Zig is with C: you can use
the same compiler to compile a mixed codebase, which is close enough in my
opinion.) What makes me worry about option #3 is that it doesn’t pass the
seeming test that is coming: memory safe by default. I still think moving
to a #3 style solution is better than staying with #1, but is that enough?
I don’t know, time will tell. I wonder to what degree you can get “C++ but memory
safe” without just being Rust. As we talked about earlier, most languages that
are trying to improve on Rust in this space are willing to trade off some core
constraints on Rust’s design to get them, but C++ and Rust share the same
constraints. That said, it would take a tremendous amount of hubris to declare
that Rust is the final, ultimate, best language in the “memory safe without GC”
space. Rust has made a lot of mistakes too. Maybe reflecting on those will make
for a good twelfth year post. Someone get started on Rust++, please!&lt;/p&gt;
&lt;p&gt;The reason that today is my Rust-a-versary is that I usually play with a new
language over Christmas break, and in 2012, that language was Rust. Maybe this
Christmas, I’ll give cpp2 a try.&lt;/p&gt;
&lt;p&gt;In the final minutes before publishing this, I also found another &lt;a href=&quot;https://www.cisa.gov/sites/default/files/2023-12/CSAC_TAC_Recommendations-Memory-Safety_Final_20231205_508.pdf&quot;&gt;interesting
report&lt;/a&gt;.
This is a report to the CISA director by the Technical Advisory Council on
how to engage with the memory safety question. Rust has 17 mentions. I haven’t
read it yet, but I figured I’d include it here.&lt;/p&gt;</content:encoded></item><item><title>Updating Buck</title><link>https://steveklabnik.com/writing/updating-buck/</link><guid isPermaLink="true">https://steveklabnik.com/writing/updating-buck/</guid><description>Hey there! A shorter post today, but I wanted to continue my series on Buck by going over some things that have changed since this series started. Updating Buck Lots of great stuff has been happening since the initial release of buck2, and we’d like to take advantage of that. If…</description><pubDate>Mon, 08 May 2023 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Hey there! A shorter post today, but I wanted to continue my series on Buck
by going over some things that have changed since this series started.&lt;/p&gt;
&lt;h2 id=&quot;updating-buck&quot;&gt;Updating Buck&lt;/h2&gt;
&lt;p&gt;Lots of great stuff has been happening since the initial release of buck2, and
we’d like to take advantage of that. If we try and update things, though,
we’ll get (well, you might not, but I did) an error:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;console&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;~&gt; cargo +nightly-2023-03-07 install --git https://github.com/facebook/buck2.git buck2&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;&amp;#x3C;snipped&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;   Replacing C:\Users\steve\.cargo\bin\buck2.exe&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;error: failed to move `C:\Users\steve\.cargo\bin\cargo-installYqDCSV\buck2.exe` to `C:\Users\steve\.cargo\bin\buck2.exe`&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;Caused by:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;  Access is denied. (os error 5)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;(Why yes, my console prompt has changed…)&lt;/p&gt;
&lt;p&gt;See on Windows, we can’t replace a program that’s running, while it’s running.
On other systems, this may work for you. However, it’s probably a good idea to
not take advantage of this particular feature, because of the underlying
cause: buck runs a daemon in the background. This daemon is still going. Trying
to replace it while it’s running means you’ll still have the old one going
around in the back, and while that’s fine (is it? I don’t actually know), best
to cleanly shut down first. So do this:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;console&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;~\Documents\GitHub\buck-rust-hello&gt; buck2 killall&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;Killed buck2.exe (4788). C:\Users\steve\.cargo\bin\buck2.exe --isolation-dir v2 daemon --dont-daemonize&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;Killed buck2.exe (40200). C:\Users\steve\.cargo\bin\buck2.exe --isolation-dir v2 daemon --dont-daemonize&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;buck2 killall&lt;/code&gt; will kill every instance of the daemon. As you can see, it found
two of mine, and shut them down. As you can see, you want to run this command
from within one of your projects.&lt;/p&gt;
&lt;p&gt;And now an upgrade works.&lt;/p&gt;
&lt;h2 id=&quot;update-reindeer&quot;&gt;Update Reindeer&lt;/h2&gt;
&lt;p&gt;If you’re building Rust code and using Reindeer, like we talked about in the
last post, go ahead and grab that too. Lots of good stuff in there:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;console&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;~&gt; cargo install --git https://github.com/facebookincubator/reindeer/ reindeer -f&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now that we’re all updated, let’s fix up our project to make use of the latest
changes that are relevant.&lt;/p&gt;
&lt;h2 id=&quot;update-the-prelude&quot;&gt;Update the prelude&lt;/h2&gt;
&lt;p&gt;I no longer need my weird toolchain hacks to get MSVC Rust working. Thank you
dtolnay! 🙏&lt;/p&gt;
&lt;p&gt;Let’s pull in changes to the prelude:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;console&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;~\Documents\GitHub\buck-rust-hello&gt; cd prelude&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;~\Documents\GitHub\buck-rust-hello\prelude&gt; git fetch origin&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;remote: Enumerating objects: 28, done.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;remote: Counting objects: 100% (28/28), done.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;remote: Compressing objects: 100% (6/6), done.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;remote: Total 17 (delta 12), reused 15 (delta 10), pack-reused 0&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;Unpacking objects: 100% (17/17), 3.60 KiB | 102.00 KiB/s, done.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;From https://github.com/facebook/buck2-prelude&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;   920d3f2..370cd4d  main       -&gt; origin/main&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;~\Documents\GitHub\buck-rust-hello\prelude&gt; git reset --hard origin/main&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;HEAD is now at 370cd4d Http_archive execution platform hack&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;~\Documents\GitHub\buck-rust-hello\prelude&gt; cd ..&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;~\Documents\GitHub\buck-rust-hello&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And remove the hack (if you had to do it too) in &lt;code&gt;toolchains\BUCK&lt;/code&gt;:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;system_cxx_toolchain(&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    name = &quot;cxx&quot;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    visibility = [&quot;PUBLIC&quot;],&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;No more &lt;code&gt;link.exe&lt;/code&gt; stuff!&lt;/p&gt;
&lt;h2 id=&quot;fix-some-configuration&quot;&gt;Fix some configuration&lt;/h2&gt;
&lt;p&gt;Some good changes have landed in the &lt;code&gt;buck2 init&lt;/code&gt; subcommand that we’ll want
to add ourselves.&lt;/p&gt;
&lt;p&gt;First up, we should &lt;a href=&quot;https://github.com/facebook/buck2/commit/54e1eb5e29eca8a021579b859d0a34c73754eb2a&quot;&gt;add an empty file named &lt;code&gt;.buckroot&lt;/code&gt; to the root of our
repository&lt;/a&gt;.
Because buck works with your filesystem hierarchy, it can and will traverse
upwards looking for things at times. Adding this file ensures that if it does
so, it will stop before it starts trying to traverse even higher. There’s no
need for anything in the file, as the contents are ignored.&lt;/p&gt;
&lt;p&gt;I think this kind of change is an interesting way to look at the usability of
various systems. Adding an empty file here is &lt;em&gt;sort of&lt;/em&gt; “more complex” than
say, Cargo. But it’s also more explicit. Which means it can be more… I want
to say “legible”, if you also read insufferable books like I do sometimes. And
therefore, easier. Anyway, more thoughts on all of this in the future.&lt;/p&gt;
&lt;p&gt;Next, we have a change that is demonstrated by this example. Can you guess
what it is?&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;console&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;~\Documents\GitHub\buck-rust-hello&gt; buck2 run //src/bin:hello_world&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;File changed: root//.git/modules/prelude&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;Build ID: 1a24b418-acdb-4d23-a5e1-6e9b644c01e6&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;Jobs completed: 83. Time elapsed: 1.9s. Cache hits: 0%. Commands: 3 (cached: 0, remote: 0, local: 3)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;There’s no reason for buck to be watching our &lt;code&gt;.git&lt;/code&gt; directory for changes. And
that’s why &lt;a href=&quot;https://github.com/facebook/buck2/commit/2083261102e867bce2b6385b78b598e758b424a8&quot;&gt;it is now put in the default
configuration&lt;/a&gt;
when you &lt;code&gt;buck2 init --git&lt;/code&gt;. But we’ve gotta make that change ourselves. Open
up your &lt;code&gt;.buckconfig&lt;/code&gt; and add this at the bottom:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;toml&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;project&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;ignore = .&lt;/span&gt;&lt;span style=&quot;color:#FDAEB7;font-style:italic&quot;&gt;git&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We want it to ignore the &lt;code&gt;.git&lt;/code&gt; directory. Seems good.&lt;/p&gt;
&lt;p&gt;… I lied though, there’s one more improvement we want to make: we also don’t
want buck to bother listening to the &lt;code&gt;target&lt;/code&gt; directory either, as those files
are for Cargo’s output. So what we &lt;em&gt;actually&lt;/em&gt; want is this:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;toml&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;project&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;ignore = .&lt;/span&gt;&lt;span style=&quot;color:#FDAEB7;font-style:italic&quot;&gt;git, target&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;After doing that we’ll want to &lt;code&gt;buck2 kill&lt;/code&gt; to shut the daemon down, so that
it can pick up our new configuration on the next boot.&lt;/p&gt;
&lt;h2 id=&quot;regenerating-reindeer&quot;&gt;Regenerating reindeer&lt;/h2&gt;
&lt;p&gt;Since we’ve got new bugfixes in Reindeer too, let’s regenerate our config
for our dependencies:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;console&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;~\Documents\GitHub\buck-rust-hello&gt; reindeer --third-party-dir third-party buckify&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;[WARN  reindeer::fixups] semver-1.0.17 has a build script, but I don&apos;t know what to do with it: Unresolved build script at ..\..\..\..\.cargo\registry\src\github.com-1ecc6299db9ec823\semver-1.0.17\build.rs. Dependencies:&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We still have to deal with the build script! We didn’t talk about the
contents of &lt;code&gt;third-party\BUCK&lt;/code&gt; last time, and we won’t this time either. If you
want to see what’s changed, you can take a peek though. One change that we
didn’t explicitly talk about before, but you may end up noticing, is that it did
not generate a target to try and build our build script.&lt;/p&gt;
&lt;p&gt;Let’s try it out now:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;console&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;~\Documents\GitHub\buck-rust-hello&gt; buck2 run //src/bin:hello_world&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;File changed: root//BUCK&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;File changed: root//third-party/BUCK&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;File changed: root//third-party&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;Build ID: 2eb0c121-d1fb-43d2-b8a4-f923d8dda657&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;Jobs completed: 20. Time elapsed: 1.1s. Cache hits: 0%. Commands: 2 (cached: 0, remote: 0, local: 2)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Nice. Also note that we aren’t seeing any more &lt;code&gt;.git&lt;/code&gt; or &lt;code&gt;target&lt;/code&gt; changes, not
that we’ve run anything that would inherently change those files, but go ahead,
invoke Cargo or git, and then build again. You shouldn’t see notifications about
those directories anymore.&lt;/p&gt;
&lt;h2 id=&quot;fixing-some-breakage&quot;&gt;Fixing some breakage&lt;/h2&gt;
&lt;p&gt;Speaking of invoking Cargo, remember how I said this in the last post?&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;We do have two different Cargo.tomls now. That is a bit of a bummer. But at
least it is easy to determine if there’s a problem: dependency failures are
loud, and if you’re building with both in CI, you’ll notice if stuff goes wrong.
There also may be a solution to this I’m just not aware of.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Well…&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;console&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;~\Documents\GitHub\buck-rust-hello&gt; cargo run&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;   Compiling hello_world v0.1.0 (C:\Users\steve\Documents\GitHub\buck-rust-hello)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;error[E0432]: unresolved import `semver`&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; --&gt; src\bin\main.rs:1:5&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;  |&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;1 | use semver::{BuildMetadata, Prerelease, Version, VersionReq};&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;  |     ^^^^^^ use of undeclared crate or module `semver`&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;For more information about this error, try `rustc --explain E0432`.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;error: could not compile `hello_world` due to previous error&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Going back and re-reading my last post, I did have a &lt;code&gt;cargo add semver&lt;/code&gt; in
there, so maybe I just forgot to commit that in my last post. Just in case,
we’ll fix that:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;console&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;~\Documents\GitHub\buck-rust-hello&gt; cargo add semver&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;    Updating crates.io index&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;      Adding semver v1.0.17 to dependencies.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;             Features:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;             + std&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;             - serde&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;With that, &lt;code&gt;cargo build&lt;/code&gt; and &lt;code&gt;cargo run&lt;/code&gt; are back in business.&lt;/p&gt;
&lt;p&gt;We also have… well “breakage” isn’t exactly right, but we have a buck
configuration issue. Let’s try to build every target:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;console&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;~\Documents\GitHub\buck-rust-hello&gt; buck2 build ...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;Error running analysis for `root//:build (prelude//platforms:default#fb50fd37ce946800)`&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;Caused by:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;    0: Error looking up configured node root//:build (prelude//platforms:default#fb50fd37ce946800)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;    1: `root//src/bin:hello_world` is not visible to `root//:build` (run `buck2 uquery --output-attribute visibility root//src/bin:hello_world` to check the visibility)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;Build ID: 51657a07-112c-46b4-a2eb-91d60a4b0aed&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;Jobs completed: 8. Time elapsed: 0.0s.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;BUILD FAILED&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We didn’t declare that our binary was visible anywhere, and so when we try and
build it, it isn’t happy. We do want this to be public, so change &lt;code&gt;src\bin\BUCK&lt;/code&gt;
by adding this &lt;code&gt;visibility&lt;/code&gt; line near the end. It should look like this:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;toml&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FDAEB7;font-style:italic&quot;&gt;rust_binary(&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    name = &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;hello_world&quot;&lt;/span&gt;&lt;span style=&quot;color:#FDAEB7;font-style:italic&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    srcs = [&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;main.rs&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color:#FDAEB7;font-style:italic&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    crate_root = &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;main.rs&quot;&lt;/span&gt;&lt;span style=&quot;color:#FDAEB7;font-style:italic&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    deps = [&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;        &quot;//third-party:semver&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    ]&lt;/span&gt;&lt;span style=&quot;color:#FDAEB7;font-style:italic&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    visibility = [&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;PUBLIC&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color:#FDAEB7;font-style:italic&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FDAEB7;font-style:italic&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And now that will work:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;console&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;~\Documents\GitHub\buck-rust-hello&gt; buck2 build ...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;File changed: root//src/bin/BUCK&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;Build ID: 9da23da4-3f99-4e78-8c58-ae5e2f1facaa&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;Jobs completed: 25. Time elapsed: 0.6s. Cache hits: 0%. Commands: 3 (cached: 0, remote: 0, local: 3)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;BUILD SUCCEEDED&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Okay, now that we’ve fixed both Cargo &lt;em&gt;and&lt;/em&gt; buck… let’s make sure that isn’t
gonna happen again. We aren’t testing any of this. So it broke. Just like I said
it was easy to not let break. Sigh.&lt;/p&gt;
&lt;p&gt;We’re going to use GitHub Actions because this is already on GitHub. I’m sure
you can adapt it to your setup of choice.&lt;/p&gt;
&lt;p&gt;Put this in &lt;code&gt;.github\workflows\ci.yml&lt;/code&gt;:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;yaml&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;CI&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;on&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;  pull_request&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;  push&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;    branches&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: [&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;main&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;jobs&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;  test&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;    name&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;${{matrix.name || format(&apos;Rust {0}&apos;, matrix.rust)}}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;    runs-on&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;${{matrix.os || &apos;ubuntu&apos;}}-latest&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;    strategy&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;      fail-fast&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;false&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;      matrix&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;        include&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;          - &lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;rust&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;nightly&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;          - &lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;rust&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;beta&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;          - &lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;rust&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;stable&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;          - &lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;rust&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;1.69.0&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;          - &lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;Cargo on macOS&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;            rust&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;nightly&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;            os&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;macos&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;          - &lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;Cargo on Windows (msvc)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;            rust&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;nightly-x86_64-pc-windows-msvc&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;            os&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;windows&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;    steps&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;      - &lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;uses&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;actions/checkout@v3&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;      - &lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;uses&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;dtolnay/rust-toolchain@master&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;        with&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;          toolchain&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;${{matrix.rust}}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;      - &lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;run&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;cargo check&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;      - &lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;run&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;cargo run&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;  buck&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;    name&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;Buck2 on ${{matrix.os == &apos;ubuntu&apos; &amp;#x26;&amp;#x26; &apos;Linux&apos; || matrix.os == &apos;macos&apos; &amp;#x26;&amp;#x26; &apos;macOS&apos; || matrix.os == &apos;windows&apos; &amp;#x26;&amp;#x26; &apos;Windows&apos; || &apos;???&apos;}}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;    runs-on&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;${{matrix.os}}-latest&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;    if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;github.event_name != &apos;pull_request&apos;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;    strategy&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;      matrix&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;        os&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: [&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;ubuntu&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;macos&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;windows&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;    steps&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;      - &lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;uses&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;actions/checkout@v3&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;        with&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;          submodules&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;true&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;      - &lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;uses&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;dtolnay/rust-toolchain@stable&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;        with&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;          components&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;rust-src&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;      - &lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;uses&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;dtolnay/install-buck2@latest&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;      - &lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;run&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;buck2 build ...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;      - &lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;run&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;buck2 run //src/bin:hello_world&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;      - &lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;uses&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;actions/cache/restore@v3&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;        id&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;cache&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;        with&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;          path&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;~/.cargo/bin/reindeer${{matrix.os == &apos;windows&apos; &amp;#x26;&amp;#x26; &apos;.exe&apos; || &apos;&apos;}}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;          key&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;${{matrix.os}}-reindeer&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;      - &lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;run&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;cargo install --git https://github.com/facebookincubator/reindeer reindeer&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;        if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;steps.cache.outputs.cache-hit != &apos;true&apos;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;      - &lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;uses&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;actions/cache/save@v3&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;        if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;steps.cache.outputs.cache-hit != &apos;true&apos;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;        with&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;          path&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;~/.cargo/bin/reindeer${{matrix.os == &apos;windows&apos; &amp;#x26;&amp;#x26; &apos;.exe&apos; || &apos;&apos;}}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;          key&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;${{steps.cache.outputs.cache-primary-key}}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;      - &lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;run&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;reindeer buckify&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;        working-directory&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;third-party&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;        if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;matrix.os == &apos;ubuntu&apos;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;      - &lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;Check reindeer-generated BUCK file up to date&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;        run&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;git diff --exit-code&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;        if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;matrix.os == &apos;ubuntu&apos;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is… you guessed it, based off of &lt;a href=&quot;https://github.com/dtolnay/cxx/blob/master/.github/workflows/ci.yml&quot;&gt;dtolnay’s CI for
cxx&lt;/a&gt;.
What can I say, he writes good code. This version is a bit stripped down, since
this is primarily a project for showing off a build system, rather than a
regular project. This has:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Builds with Cargo on Linux against nightly, beta, stable, and 1.69.0 as a sort of MSRV check.&lt;/li&gt;
&lt;li&gt;Builds with Cargo on MacOS and Windows against nightly Rust.&lt;/li&gt;
&lt;li&gt;Buck on Linux, MacOS and Windows against stable Rust.&lt;/li&gt;
&lt;li&gt;On Linux, checks that we have comitted any relevant changes to dependencies.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This does not have:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A “fail if there are any warnings” build&lt;/li&gt;
&lt;li&gt;A clippy build&lt;/li&gt;
&lt;li&gt;A full matrix of every os/language/build system combination&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;or other things you may want out of a build. Again, you’ll probably want to
customize this heavily, but this is what I’m going to do here.&lt;/p&gt;
&lt;h2 id=&quot;wrapping-up&quot;&gt;Wrapping up&lt;/h2&gt;
&lt;p&gt;And with that, we are done! Next post we’re going to deal with that build
script. And use some crates that have more intense dependencies, and get them
all working.&lt;/p&gt;
&lt;p&gt;As always, you can &lt;a href=&quot;https://github.com/steveklabnik/buck-rust-hello/commit/914e3aa7cdc269b2536f8118255eae12bf552f8d&quot;&gt;check out the code&lt;/a&gt; at this point if you’d like.&lt;/p&gt;</content:encoded></item><item><title>Using Crates.io with Buck</title><link>https://steveklabnik.com/writing/using-cratesio-with-buck/</link><guid isPermaLink="true">https://steveklabnik.com/writing/using-cratesio-with-buck/</guid><description>In a previous post , I laid out the basics of building a Rust project with buck2 . We compared and contrasted it with Cargo. But what about one of the biggest and best features that Cargo has to offer, the ability to use other Rust packages from crates.io? They don’t use buck, so…</description><pubDate>Thu, 27 Apr 2023 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;In &lt;a href=&quot;using-buck-to-build-rust-projects&quot;&gt;a previous post&lt;/a&gt;, I laid out the basics
of building a Rust project with &lt;a href=&quot;https://buck2.build/&quot;&gt;buck2&lt;/a&gt;. We compared and
contrasted it with Cargo. But what about one of the biggest and best features
that Cargo has to offer, the ability to use other Rust packages from crates.io?
They don’t use buck, so how can we integrate them into our build?&lt;/p&gt;
&lt;p&gt;This post represents how to do this at the time that this was posted; future
posts may update or change something that happens here. Here’s a hopefully
complete but possibly incomplete list of updates and the posts that talk
about it:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;build-script-build&lt;/code&gt; target is no longer generated, see “Updating Buck”&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;depending-on-semver&quot;&gt;Depending on semver&lt;/h2&gt;
&lt;p&gt;Let’s use the &lt;code&gt;semver&lt;/code&gt; package example as our program. I am choosing this for
a few reasons:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;I used to be involved in maintaining it, and I’m sentimental&lt;/li&gt;
&lt;li&gt;It’s authored by dtolnay, who authors many great Rust crates.&lt;/li&gt;
&lt;li&gt;More specifically than that, his excellent &lt;a href=&quot;https://github.com/dtolnay/cxx/&quot;&gt;cxx library&lt;/a&gt; maintains build rules for Cargo, Buck, and Bazel, and examining how he uses Buck in cxx helped me write both the last post and this one. I wanted to make sure to shout that out.&lt;/li&gt;
&lt;li&gt;It’s pure Rust (this is easier than something that depends on C, since as I mentioned I’m still having an issue or two with getting my own C toolchain working so far).&lt;/li&gt;
&lt;li&gt;It has one optional dependecy on serde, but no others. Again, this is just easier, not a fundamental limitation.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Here’s the example, from &lt;a href=&quot;https://crates.io/crates/semver&quot;&gt;the page on crates.io&lt;/a&gt;:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;rust&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;use&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; semver&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;BuildMetadata&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;Prerelease&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;Version&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;VersionReq&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;};&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;fn&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; main&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    let&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; req &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; VersionReq&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;parse&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;&gt;=1.2.3, &amp;#x3C;1.8.0&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;unwrap&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;    // Check whether this requirement matches version 1.2.3-alpha.1 (no)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    let&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; version &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; Version&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        major&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 1&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        minor&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 2&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        patch&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 3&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        pre&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; Prerelease&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;new&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;alpha.1&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;unwrap&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        build&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; BuildMetadata&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;EMPTY&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    };&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;    assert!&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;!&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;req&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;matches&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;#x26;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;version));&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;    // Check whether it matches 1.3.0 (yes it does)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    let&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; version &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; Version&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;parse&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;1.3.0&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;unwrap&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;    assert!&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(req&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;matches&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;#x26;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;version));&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Let’s change &lt;code&gt;src/bin/main.rs&lt;/code&gt; to contain this code. What do we need to do
to add this with Cargo?&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;console&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;buck-rust-hello〉cargo add semver&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;      Adding semver v1.0.17 to dependencies.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;             Features:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;             + std&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;             - serde&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;buck-rust-hello〉cargo run&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;   Compiling semver v1.0.17&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;   Compiling hello_world v0.1.0 (C:\Users\steve\Documents\GitHub\buck-rust-hello)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;    Finished dev [unoptimized + debuginfo] target(s) in 0.71s&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;     Running `target\debug\main.exe`&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;buck-rust-hello〉&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Easy enough! We expect no output, becuase the asserts should pass. (Note that
we didn’t ask for the &lt;code&gt;serde&lt;/code&gt; feature, so we aren’t using it, and therefore
don’t depend on anything other than &lt;code&gt;semver&lt;/code&gt;.)&lt;/p&gt;
&lt;h2 id=&quot;how-cargo-handles-this&quot;&gt;How Cargo handles this&lt;/h2&gt;
&lt;p&gt;Before we move on, let’s talk for a moment about what Cargo actually does here.&lt;/p&gt;
&lt;p&gt;First, &lt;code&gt;cargo add&lt;/code&gt; has added this to our &lt;code&gt;Cargo.toml&lt;/code&gt;:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;[dependencies]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;semver = &quot;1.0.17&quot;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is the latest release of semver at the time of this writing.&lt;/p&gt;
&lt;p&gt;When we &lt;code&gt;cargo build&lt;/code&gt;, Cargo will figure out all of the crates we need. It will
then check the cache for the source code for that crate, and if it’s not there,
download it. On my system, this lives here:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt; ~\.cargo\registry\src\github.com-1ecc6299db9ec823\semver-1.0.17\&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This means we have a &lt;em&gt;global&lt;/em&gt; cache of source code.&lt;/p&gt;
&lt;p&gt;Cargo will then compile &lt;code&gt;semver&lt;/code&gt;, as you can see in the output above. It places
that output in the &lt;code&gt;target&lt;/code&gt; directory, more specifically&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;.\target\debug\deps&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This directory will contain &lt;code&gt;libsemver-ded1559592aad8f7.rlib&lt;/code&gt;,
&lt;code&gt;libsemver-ded1559592aad8f7.rmeta&lt;/code&gt;, and &lt;code&gt;semver-ded1559592aad8f7.d&lt;/code&gt;. These have
hashes embedded in them so that if we had multiple versions of &lt;code&gt;semver&lt;/code&gt; in our
project, they can be disambiguated. If you’re not familiar with &lt;code&gt;rustc&lt;/code&gt; output:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;rlib files are simlar to archive files, like Unix &lt;code&gt;ar&lt;/code&gt;. The details are not standard, and may change at any time. Object code lives in here, as well as other things.&lt;/li&gt;
&lt;li&gt;rmeta files contain crate metadata. This can be used for &lt;code&gt;cargo check&lt;/code&gt;, for example.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;.d&lt;/code&gt; files are a dependency file. This format comes from gcc/make, and is sorta standardized. This is in theory useful for use with other build systems, but we won’t be using this today.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Cargo will then build our project, passing in &lt;code&gt;libsemver-*.rlib&lt;/code&gt; as a
dependency.&lt;/p&gt;
&lt;p&gt;If you’re curious about the exact commands and flags, &lt;code&gt;cargo build -v&lt;/code&gt; will
show that. Make sure to &lt;code&gt;cargo clean&lt;/code&gt; first, or else you’ll get no output, given
that we’ve already built this project.&lt;/p&gt;
&lt;p&gt;For example, here’s the &lt;code&gt;rustc&lt;/code&gt; invocation that Cargo makes for building this step:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;text&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;rustc --crate-name main --edition=2021 src\bin\main.rs --error-format=json --json=diagnostic-rendered-ansi,artifacts,future-incompat --crate-type bin --emit=dep-info,link -C embed-bitcode=no -C debuginfo=2 -C metadata=c398fba113f38e08 --out-dir C:\Users\steve\Documents\GitHub\buck-rust-hello\target\debug\deps -C incremental=C:\Users\steve\Documents\GitHub\buck-rust-hello\target\debug\incremental -L dependency=C:\Users\steve\Documents\GitHub\buck-rust-hello\target\debug\deps --extern hello_world=C:\Users\steve\Documents\GitHub\buck-rust-hello\target\debug\deps\libhello_world-c5b898f1ca338cca.rlib --extern semver=C:\Users\steve\Documents\GitHub\buck-rust-hello\target\debug\deps\libsemver-ded1559592aad8f7.rlib&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Since we are not using Cargo, we need to replace all of that stuff, and get
Buck to generate that &lt;code&gt;rustc&lt;/code&gt; line, or at least, some equivalent of it.&lt;/p&gt;
&lt;p&gt;Let’s talk about the various things we need to do:&lt;/p&gt;
&lt;h3 id=&quot;the-mismatch&quot;&gt;The mismatch&lt;/h3&gt;
&lt;p&gt;Let’s start with one thing that is basically the same: &lt;code&gt;buck-out&lt;/code&gt; and &lt;code&gt;target&lt;/code&gt;
are both directories in our project that cache the output of our build. Yeah
the name and details are different, but we’re not going to try and somehow
unify these, as they’re both considered implementaiton details of the
respective systems, and trying to get them to share is a lot of work for not
much gain.&lt;/p&gt;
&lt;p&gt;Buck does not have a central registry of packages that we can download code
from.&lt;/p&gt;
&lt;p&gt;Buck is interested in reproducable builds, and therefore, a global cache of
source code doesn’t make as much sense. You want the code stored locally, with
your project. The dreaded (or beloved) vendoring.&lt;/p&gt;
&lt;p&gt;Buck does not understand the crate index, Cargo configuration for a given
package, and other implementation details. As a more general build system,
those are pretty much out of scope.&lt;/p&gt;
&lt;p&gt;Lucikly, other people have done a lot of work here.&lt;/p&gt;
&lt;h3 id=&quot;reindeer&quot;&gt;Reindeer&lt;/h3&gt;
&lt;p&gt;Enter &lt;a href=&quot;https://github.com/facebookincubator/reindeer/&quot;&gt;Reindeer&lt;/a&gt;. Reindeer is a
project that will help us bridge this gap. Here’s how this will work: Reindeer
will create and (mostly) manage a &lt;code&gt;third-party&lt;/code&gt; directory for us. It will
generate &lt;code&gt;BUCK&lt;/code&gt; files that we can then use to depend on these external crates.
We can even choose to vendor our sources or not.&lt;/p&gt;
&lt;p&gt;You can install reindeer through Cargo:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;console&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&gt; cargo install --git https://github.com/facebookincubator/reindeer/ reindeer&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Let’s set this up. First off, we need to create some files:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;console&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&gt; mkdir third-party&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&gt; code third-party&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;\C&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;argo.toml &lt;/span&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;# or vim, or whatever&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In that &lt;code&gt;Cargo.toml&lt;/code&gt;, we’ll need to put this:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;toml&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;workspace&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;package&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;name = &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;rust-third-party&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;version = &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;0.0.0&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;publish = &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;false&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;edition = &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;2021&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;# Dummy target to keep Cargo happy&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;[[&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;bin&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;]]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;name = &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;fake&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;path = &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;/dev/null&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;dependencies&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;semver = &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;1.0.17&quot;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We’re creating a fake package here, so nothing truly matters except the
&lt;code&gt;[dependencies]&lt;/code&gt; section. Here we depend on &lt;code&gt;semver&lt;/code&gt; as usual.&lt;/p&gt;
&lt;p&gt;We’re also going to configure Reindeer to not vendor our source code, because
that’s how I prefer to do things. Vendoring was the default behavior, with
non-vendoring being added very recently, so if you prefer to vendor, that
workflow works very well&lt;/p&gt;
&lt;p&gt;Anyway put this in &lt;code&gt;third-party/reindeer.toml&lt;/code&gt;:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;toml&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;vendor = &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;false&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So run this inside of your &lt;code&gt;third-party&lt;/code&gt; directory:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;console&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;〉cd third-party&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;〉reindeer buckify&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;[WARN  reindeer::fixups] semver-1.0.17 has a build script, but I don&apos;t know what to do with it: Unresolved build script at vendor\semver\build.rs. Dependencies:&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Oh no, build scripts! Yeah I said that I picked &lt;code&gt;semver&lt;/code&gt; because it should be easy,
but it does have a build script, which is another Cargo-specific feature. Now,
the &lt;code&gt;semver&lt;/code&gt; crate’s build script is used as a feature to support older versions
of the compiler; all it does is detect old versions and then spit out some
configuration to make sure to not use the newer features of the language. This
is why this is a warning, not an error; in this case, we don’t actually need
the build script since we are using a new compiler. So, we are going to skip this
&lt;em&gt;for now&lt;/em&gt;, but we’ll come back and fix it.&lt;/p&gt;
&lt;p&gt;At this point, &lt;code&gt;reindeer&lt;/code&gt; has generated a &lt;code&gt;BUCK&lt;/code&gt; file for &lt;code&gt;semver&lt;/code&gt;. Let’s see
what targets we have now:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;console&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;〉buck2 targets //...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;Jobs completed: 4. Time elapsed: 0.0s.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;root//:build&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;root//src/bin:hello_world&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;root//src/lib:hello_world&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;root//third-party:semver&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;root//third-party:semver-1.0.17&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;root//third-party:semver-1.0.17-build-script-build&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We have a few new ones! One for &lt;code&gt;semver&lt;/code&gt;, one for the specific version of
&lt;code&gt;semver&lt;/code&gt;, and one for the build script of &lt;code&gt;semver&lt;/code&gt;. The general &lt;code&gt;semver&lt;/code&gt; is
an alias for &lt;code&gt;semver-1.0.17&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Do you know how to modify our build so that buck builds successfully?&lt;/p&gt;
&lt;p&gt;Here’s the answer: change &lt;code&gt;src\bin\BUCK&lt;/code&gt;:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;rust_binary(&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    name&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &quot;hello_world&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    srcs&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; [&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;main.rs&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;],&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    crate_root&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &quot;main.rs&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    deps&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; [&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;        &quot;//third-party:semver&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    ],&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And now we can build and run:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;console&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;〉buck2 run //src/bin:hello_world&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;File changed: root//src/bin/BUCK&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;Build ID: b18ba58d-8a77-439a-9d95-6051f3cf21d4&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;Jobs completed: 26. Time elapsed: 1.9s. Cache hits: 0%. Commands: 3 (cached: 0, remote: 0, local: 3)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Success! Our program has no output, if the assertions failed we would have
gotten something, but this is expected given the example code.&lt;/p&gt;
&lt;p&gt;Now, whenever we need to add or remove a dependency, we can modify
&lt;code&gt;third-party\Cargo.toml&lt;/code&gt;, re-run the &lt;code&gt;buckify&lt;/code&gt; command, and we’re good.&lt;/p&gt;
&lt;p&gt;We &lt;em&gt;do&lt;/em&gt; have two different &lt;code&gt;Cargo.toml&lt;/code&gt;s now. That is a bit of a bummer. But
at least it is easy to determine if there’s a problem: dependency failures are
loud, and if you’re building with both in CI, you’ll notice if stuff goes wrong.
There also may be a solution to this I’m just not aware of.&lt;/p&gt;
&lt;p&gt;If you’d like to see the whole thing at this point, &lt;a href=&quot;https://github.com/steveklabnik/buck-rust-hello/commit/2abd1ada7dbbc7f89cd8678eace1e07b3df2ae2f&quot;&gt;this
commit&lt;/a&gt;
should have you covered.&lt;/p&gt;
&lt;p&gt;This should get you going with building more advanced projects in Rust using
buck2. In the next post, we’ll talk about fixups, which you’ll need for
dependencies that are more complex than &lt;code&gt;semver&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;By the way, if you’re interested in this stuff, I’ve &lt;a href=&quot;https://discord.gg/ZTEmwypZ6K&quot;&gt;made a Discord for buck
fans&lt;/a&gt;. Come hang out, chat about stuff, ask
questions, it’s gonna be a good time.&lt;/p&gt;</content:encoded></item><item><title>Using buck to build Rust projects</title><link>https://steveklabnik.com/writing/using-buck-to-build-rust-projects/</link><guid isPermaLink="true">https://steveklabnik.com/writing/using-buck-to-build-rust-projects/</guid><description>A few days ago, Facebook/Meta/idk announced that buck2 is now open source . Buck2 is an extensible and performant build system written in Rust and designed to make your build experience faster and more efficient. As it just so happens, I have taken an increasing interest in build…</description><pubDate>Thu, 13 Apr 2023 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;A few days ago, Facebook/Meta/idk &lt;a href=&quot;https://engineering.fb.com/2023/04/06/open-source/buck2-open-source-large-scale-build-system/&quot;&gt;announced that buck2 is now open
source&lt;/a&gt;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Buck2 is an extensible and performant build system written in Rust and
designed to make your build experience faster and more efficient.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;As it just so happens, I have taken an increasing interest in build systems
lately. I have mostly ignored the cool kids’ build system things, because
I have never worked at a FAANG, or at a true monorepo shop. I also personally
try and avoid the JVM wherever possible, and the first generation of these tools
were all built on top of it. (Yes, that bias may be outdated, I’m not saying
&lt;em&gt;you&lt;/em&gt; should avoid the JVM, just stating my own bias up front.)&lt;/p&gt;
&lt;p&gt;So this timing was perfect! Let’s explore what using buck looks like.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;A brief aside: listen, I have no love for Facebook. I &lt;a href=&quot;im-deleting-my-facebook-tonight&quot;&gt;deleted my
account&lt;/a&gt; almost a dozen years ago. That
doesn’t mean I’m not interested in using good tools they produce. If you
feel differently, fine, but that’s not what I want to talk about today, so
I’m not going to.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Oh, one last bit before I begin: I’m not going to do a lot of motivating on
“why would you want to use Buck?” in this post. There’s a few reasons for that,
but for now, if that’s what you’re looking for, this post isn’t it. We’re doing
this purely for the novelty of trying out some new tech right now. I will
probably end up with a post giving better motivations at some point in the
future, but I think it makes more sense once you see how it works, rather than
starting there.&lt;/p&gt;
&lt;p&gt;This post represents how to do this at the time that this was posted; future
posts may update or change something that happens here. Here’s a hopefully
complete but possibly incomplete list of updates and the posts that talk
about it:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;buck2 init&lt;/code&gt; also creates a file named &lt;code&gt;.buckroot&lt;/code&gt;, see “Updating Buck”&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;getting-started-with-buck2&quot;&gt;Getting started with buck2&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://buck2.build/docs/getting_started/&quot;&gt;The Getting Started page&lt;/a&gt; will give
you instructions on installing buck. As of this moment, the instructions are:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;console&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;$ rustup install nightly-2023-01-24&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;$ cargo +nightly-2023-01-24 install --git https://github.com/facebook/buck2.git buck2&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is mega-convenient for me as a Rust user, but probably not if you don’t
have Rust installed. That said, this is a first release, and so I don’t expect
anything fancier. This is what &lt;code&gt;cargo install&lt;/code&gt; is good for!&lt;/p&gt;
&lt;p&gt;Let’s make a new directory, &lt;code&gt;hello&lt;/code&gt;:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;console&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;$ mkdir buck-rust-hello&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;$ cd buck-rust-hello&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To initialize a project, we use this command:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;console&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;$ buck2 init --git&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Before we move forward, let’s examine what this generated for us.&lt;/p&gt;
&lt;h2 id=&quot;initial-project-files&quot;&gt;Initial project files&lt;/h2&gt;
&lt;p&gt;We now have this stuff in our directory:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;text&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;$ git add .&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;$ git status&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;On branch main&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;No commits yet&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Changes to be committed:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  (use &quot;git rm --cached &amp;#x3C;file&gt;...&quot; to unstage)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        new file:   .buckconfig&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        new file:   .gitignore&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        new file:   .gitmodules&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        new file:   BUCK&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        new file:   prelude&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        new file:   toolchains/BUCK&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Let’s talk about each of these in turn.&lt;/p&gt;
&lt;h3 id=&quot;buckconfig&quot;&gt;&lt;code&gt;.buckconfig&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;The &lt;code&gt;.buckconfig&lt;/code&gt; file is… a configuration file for Buck, go figure. It looks
like this:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;toml&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;repositories&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;root = .&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;prelude = p&lt;/span&gt;&lt;span style=&quot;color:#FDAEB7;font-style:italic&quot;&gt;relude&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;toolchains = t&lt;/span&gt;&lt;span style=&quot;color:#FDAEB7;font-style:italic&quot;&gt;oolchains&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;none = n&lt;/span&gt;&lt;span style=&quot;color:#FDAEB7;font-style:italic&quot;&gt;one&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;repository_aliases&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;config = p&lt;/span&gt;&lt;span style=&quot;color:#FDAEB7;font-style:italic&quot;&gt;relude&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;fbcode = n&lt;/span&gt;&lt;span style=&quot;color:#FDAEB7;font-style:italic&quot;&gt;one&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;fbsource = n&lt;/span&gt;&lt;span style=&quot;color:#FDAEB7;font-style:italic&quot;&gt;one&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;buck = n&lt;/span&gt;&lt;span style=&quot;color:#FDAEB7;font-style:italic&quot;&gt;one&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;parser&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;target_platform_detector_spec = t&lt;/span&gt;&lt;span style=&quot;color:#FDAEB7;font-style:italic&quot;&gt;arget:root//...-&gt;prelude//platforms:default&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That &lt;code&gt;none = none&lt;/code&gt; is kind of amusing. Regardless of that, this file is
extremely important: it configures the entire thing. In a sense, it’s like
&lt;code&gt;Cargo.toml&lt;/code&gt;: just like a package is defined by the existence of a &lt;code&gt;Cargo.toml&lt;/code&gt;,
a &lt;code&gt;.buckconfig&lt;/code&gt; defines the existence of a… cell. Which defines a package.
We’ll get there. Point is, this is the top level configuration. We say that
the repository root is in the current directory, we’d like to use the default
prelude and toolchains.&lt;/p&gt;
&lt;p&gt;I uh… I don’t know what the &lt;code&gt;none = none&lt;/code&gt; is for. It might just be a bug.
I haven’t seen it in some of the other config files I’ve poked at. Let’s just
leave that alone for now. I do have a suspicion though… and it involves the
next section.&lt;/p&gt;
&lt;p&gt;We also have a table for repository aliases. I couldn’t find any documentation
on this, but I would imagine this means we could use the name &lt;code&gt;config&lt;/code&gt; instead
of &lt;code&gt;prelude&lt;/code&gt; later. Looks like we don’t have any way to refer to &lt;code&gt;fbcode&lt;/code&gt; and
&lt;code&gt;fbsource&lt;/code&gt;, which makes sense, and same with &lt;code&gt;buck&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;(I wonder if this is what the &lt;code&gt;none = none&lt;/code&gt; is about above, defining a sort of
“none repository” that we can then alias these to.)&lt;/p&gt;
&lt;p&gt;Finally, we have a parser table, with one entry, pointing out where a thing
exists. I know this configures Buck’s parser, but other than that… I’m sure
I’ll figure it out eventually.&lt;/p&gt;
&lt;h3 id=&quot;gitmodules--prelude&quot;&gt;&lt;code&gt;.gitmodules&lt;/code&gt; &amp;#x26; &lt;code&gt;prelude&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;We have a git submodule, pointing to
&lt;code&gt;https://github.com/facebook/buck2-prelude.git&lt;/code&gt;,
that lives at the &lt;code&gt;prelude&lt;/code&gt; directory. If you poke around in there, you’ll
find a bunch of &lt;code&gt;.bzl&lt;/code&gt; files that implement useful features for us to use.
We’ll get into those in a moment, but the point is that this is sort of like
a ‘standard library’ if you will. You could also not use it and define your own.
If you’re that kind of person.&lt;/p&gt;
&lt;h3 id=&quot;gitignore&quot;&gt;&lt;code&gt;.gitignore&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;A very simple &lt;code&gt;.gitignore&lt;/code&gt; will be created, that contains one line: &lt;code&gt;/buck-out&lt;/code&gt;.
This is where buck stores artifacts produced by your builds, so we don’t want
that checked into version control.&lt;/p&gt;
&lt;h3 id=&quot;buck&quot;&gt;&lt;code&gt;BUCK&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;Now we get to the good stuff. Here’s the generated &lt;code&gt;BUCK&lt;/code&gt; file:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;txt&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;# A list of available rules and their signatures can be found here: https://buck2.build/docs/generated/starlark/prelude/prelude.bzl&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;genrule(&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    name = &quot;hello_world&quot;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    out = &quot;out.txt&quot;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    cmd = &quot;echo BUILT BY BUCK2&gt; $OUT&quot;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;genrule&lt;/code&gt; is like a function, provided by our prelude. If you’re curious, the
implementation is in &lt;code&gt;prelude/genrule.bzl&lt;/code&gt;. This command, as you may imagine,
sets up a rule, named &lt;code&gt;hello_world&lt;/code&gt;, that produces a file called &lt;code&gt;out.txt&lt;/code&gt;.
It does this by running the &lt;code&gt;cmd&lt;/code&gt;. Nice and straightforward. We’ll give that
a try in a moment, but first, one last file:&lt;/p&gt;
&lt;h3 id=&quot;toolchainsbuck&quot;&gt;&lt;code&gt;toolchains/BUCK&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;This file describes a toolchain. Here’s the contents:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;text&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;load(&quot;@prelude//toolchains:genrule.bzl&quot;, &quot;system_genrule_toolchain&quot;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;system_genrule_toolchain(&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    name = &quot;genrule&quot;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    visibility = [&quot;PUBLIC&quot;],&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This loads a certain rule from the prelude, and then defines this as a public
toolchain. We can define as many toolchains as we want here, for example, if
we wanted to build both Rust and Python, we could define both toolchains here
for later use.&lt;/p&gt;
&lt;p&gt;The “genrule” toolchain is used to generate files from a shell command, as we
saw before with our rule that produces &lt;code&gt;out.txt&lt;/code&gt;. So, in my understanding, here
we are defining that we wish to actually use that. And then, in the &lt;code&gt;BUCK&lt;/code&gt; file,
we’re using this toolchain to implement our rule.&lt;/p&gt;
&lt;h2 id=&quot;invoking-our-first-build&quot;&gt;Invoking our first build&lt;/h2&gt;
&lt;p&gt;Okay, let’s actually give this a shot. To instruct Buck to build something, we
invoke it with the “target pattern” as an argument. Let’s ask Buck what targets
it knows how to build. To do this:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;console&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;C:\Users\steve\Documents\GitHub\buck-rust-hello〉buck2 targets //...                                                     04/10/2023 02:01:50 PM&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;Build ID: cd778a29-2ba4-484b-8956-dc67f6fc0625&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;Jobs completed: 4. Time elapsed: 0.0s.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;root//:hello_world&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The &lt;code&gt;//...&lt;/code&gt; is a “target pattern.” The &lt;code&gt;/...&lt;/code&gt; means “all build targets in build
files in subdirectories”, and &lt;code&gt;/&lt;/code&gt; means our root directory, so &lt;code&gt;//...&lt;/code&gt; means
“all targets in all build files in all subdirectories.” By passing this target
to &lt;code&gt;buck2 targets&lt;/code&gt;, we can see every target in the project. This shows our
one target we’ve defined, &lt;code&gt;root://:hello_world&lt;/code&gt;. This name was defined in our
&lt;code&gt;BUCK&lt;/code&gt; file above. If you change that to&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;genrule(&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    name&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &quot;lol&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;then &lt;code&gt;buck2 targets //...&lt;/code&gt; would show &lt;code&gt;root://:lol&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Let’s actually build our target:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;console&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;〉buck2 build //:hello_world&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;File changed: root//BUCK&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;Build ID: 73f4b797-2238-47bc-8e43-7ffcb2b7d9b7&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;Jobs completed: 36. Time elapsed: 0.0s. Cache hits: 0%. Commands: 1 (cached: 0, remote: 0, local: 1)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;BUILD SUCCEEDED&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Okay the build succeeded, but where is our &lt;code&gt;out.txt&lt;/code&gt;? We can ask buck!&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;console&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;〉buck2 build //:hello_world --show-output&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;Build ID: 7ce93845-ab1e-4b0a-9274-51fed9f9e295&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;Jobs completed: 3. Time elapsed: 0.0s.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;BUILD SUCCEEDED&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;root//:hello_world buck-out\v2\gen\root\fb50fd37ce946800\__hello_world__\out\out.txt&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It lives in a deeply nested subdirectory of &lt;code&gt;buck-out&lt;/code&gt;, a new top-level directory
that was created for us. If you remember from before, this directory is ignored
in our &lt;code&gt;.gitignore&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;If we look at the file, you can see it contains the text we wanted it to
contain.&lt;/p&gt;
&lt;p&gt;Let’s build a second time!&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;console&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;〉buck2 build //:hello_world&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;File changed: root//.git/index.lock&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;File changed: root//.git&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;File changed: root//.git/modules/prelude/index.lock&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;31 additional file change events&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;Build ID: c00e4bfa-a1f8-40c7-a61c-2a394dca5da5&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;Jobs completed: 5. Time elapsed: 0.0s.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;BUILD SUCCEEDED&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Buck has noticed that we’ve changed some files, but since our rule doesn’t
depend on any of them, we’re good to go.&lt;/p&gt;
&lt;h2 id=&quot;building-some-rust-code&quot;&gt;Building some Rust code&lt;/h2&gt;
&lt;p&gt;Okay, &lt;code&gt;echo&lt;/code&gt; to a file is fun, but let’s actually build some Rust. Create a
file, &lt;code&gt;hello.rs&lt;/code&gt;:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;rust&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;fn&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; main&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;    println!&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;Hello, world!&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;and then update the &lt;code&gt;BUCK&lt;/code&gt; file to this:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;rust_binary(&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    name&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &quot;hello_world&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    srcs&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; [&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;hello.rs&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;],&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    crate_root&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &quot;hello.rs&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This says “hey, we’re building a Rust binary, it has this target name, these
source files, and the crate root lives here.” Given we only have one file,
there’s some reptition. It happens. Let’s build:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;console&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;〉buck2 build //:hello_world&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;File changed: root//BUCK&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;Error running analysis for `root//:hello_world (prelude//platforms:default#fb50fd37ce946800)`&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;Caused by:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;    0: Error looking up configured node root//:hello_world (prelude//platforms:default#fb50fd37ce946800)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;    1: Error looking up configured node toolchains//:cxx (prelude//platforms:default#fb50fd37ce946800) (prelude//platforms:default#fb50fd37ce946800)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;    2: looking up unconfigured target node `toolchains//:cxx`&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;    3: Unknown target `cxx` from package `toolchains//`.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;       Did you mean one of the 1 targets in toolchains//:BUCK?&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;Build ID: f126ce07-efe8-41d3-8aae-8b7d31a4dafc&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;Jobs completed: 4. Time elapsed: 0.0s.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;BUILD FAILED&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Oops! We didn’t set up a rust toolchain! Let’s do that now. Edit
&lt;code&gt;toolchains/BUCK&lt;/code&gt;:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;load(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;@prelude//toolchains:rust.bzl&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;system_rust_toolchain&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;system_rust_toolchain(&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    name&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &quot;rust&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    default_edition&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &quot;2021&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    visibility&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; [&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;PUBLIC&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;],&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And… when we build again, the same error. Now. I am not 100% sure what’s
going on here, but this is what we need to do:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;load(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;@prelude//toolchains:rust.bzl&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;system_rust_toolchain&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;load(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;@prelude//toolchains:genrule.bzl&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;system_genrule_toolchain&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;load(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;@prelude//toolchains:cxx.bzl&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;system_cxx_toolchain&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;load(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;@prelude//toolchains:python.bzl&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;system_python_bootstrap_toolchain&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;system_genrule_toolchain(&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    name&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &quot;genrule&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    visibility&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; [&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;PUBLIC&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;],&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;system_rust_toolchain(&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    name&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &quot;rust&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    default_edition&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &quot;2021&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    visibility&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; [&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;PUBLIC&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;],&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;system_cxx_toolchain(&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    name&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &quot;cxx&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    visibility&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; [&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;PUBLIC&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;],&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;system_python_bootstrap_toolchain(&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    name&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &quot;python_bootstrap&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    visibility&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; [&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;PUBLIC&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;],&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I &lt;em&gt;believe&lt;/em&gt; that this is because, to compile the Rust compiler, we need
Python and a C++ compiler. Well, I &lt;em&gt;did&lt;/em&gt; believe that, but after digging into
things some more, it’s that the Rust toolchain from the prelude depends on
the CXX toolchain in the prelude, because the Rust toolchain invokes the C
compiler to invoke the linker. I’m still not 100% sure why Python needs to be
in there. Anyway.&lt;/p&gt;
&lt;p&gt;Now, when I run, I got this:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;console&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;〉buck2 build //:hello_world -v 3&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;Action failed: prelude//python_bootstrap/tools:win_python_wrapper (symlinked_dir resources)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;Internal error: symlink(original=../../../../../../../../../prelude/python_bootstrap/tools/win_python_wrapper.bat, link=C:\Users\steve\Documents\GitHub\buck-rust-hello\buck-out\v2\gen\prelude\fb50fd37ce946800\python_bootstrap\tools\__win_python_wrapper__\resources\win_python_wrapper.bat): A required privilege is not held by the client. (os error 1314)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;Build ID: 57a66885-f7e7-474b-a782-b49fc4425be9&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;Jobs completed: 14. Time elapsed: 0.0s.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;BUILD FAILED&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;Failed to build &apos;prelude//python_bootstrap/tools:win_python_wrapper (prelude//platforms:default#fb50fd37ce946800)&apos;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I got this becuase I’m on Windows, and Windows restricts the ability to create
symlinks by default. Turning on “Developer Mode” (which I’m surprised that I
haven’t had to turn on so far yet), I get further:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&amp;#x3C;whole bunch of output&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  = note: &apos;clang++&apos; is not recognized as an internal or external command,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;          operable program or batch file.&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here’s that “invokes the compiler to get the linker” thing I was referring to
above.&lt;/p&gt;
&lt;p&gt;Now… by default, the Rust support is for the GNU version of the Windows
toolchain. I never use that. Upstream has said that they want everything
to be supported, so that change will come at some point, maybe by the time
you read this! But in the meantime, I could get my (pure Rust) projects
building with two small patches:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;diff&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;diff --git a/prelude/toolchains/cxx.bzl b/prelude/toolchains/cxx.bzl&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;index c57b7b8..dc14ca7 100644&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FDAEB7&quot;&gt;&lt;span style=&quot;user-select: none;&quot;&gt;-&lt;/span&gt;-- a/prelude/toolchains/cxx.bzl&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;&lt;span style=&quot;user-select: none;&quot;&gt;+&lt;/span&gt;++ b/prelude/toolchains/cxx.bzl&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0;font-weight:bold&quot;&gt;@@ -39,7 +39,7 @@&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; def _system_cxx_toolchain_impl(ctx):&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;         CxxToolchainInfo(&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;             mk_comp_db = ctx.attrs.make_comp_db,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;             linker_info = LinkerInfo(&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FDAEB7&quot;&gt;&lt;span style=&quot;user-select: none;&quot;&gt;-&lt;/span&gt;                linker = RunInfo(args = [&quot;clang++&quot;]),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;&lt;span style=&quot;user-select: none;&quot;&gt;+&lt;/span&gt;                linker = RunInfo(args = [&quot;link&quot;]),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;                 linker_flags = [&quot;-fuse-ld=lld&quot;] + ctx.attrs.link_flags,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;                 archiver = RunInfo(args = [&quot;ar&quot;, &quot;rcs&quot;]),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;                 archiver_type = archiver_type,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;diff --git a/prelude/toolchains/rust.bzl b/prelude/toolchains/rust.bzl&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;index 8172090..4545d55 100644&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FDAEB7&quot;&gt;&lt;span style=&quot;user-select: none;&quot;&gt;-&lt;/span&gt;-- a/prelude/toolchains/rust.bzl&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;&lt;span style=&quot;user-select: none;&quot;&gt;+&lt;/span&gt;++ b/prelude/toolchains/rust.bzl&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0;font-weight:bold&quot;&gt;@@ -23,7 +23,7 @@&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; _DEFAULT_TRIPLE = select({&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;         # default when we&apos;re able; but for now buck2 doesn&apos;t work with the MSVC&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;         # toolchain yet.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;         &quot;config//cpu:arm64&quot;: &quot;aarch64-pc-windows-gnu&quot;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FDAEB7&quot;&gt;&lt;span style=&quot;user-select: none;&quot;&gt;-&lt;/span&gt;        &quot;config//cpu:x86_64&quot;: &quot;x86_64-pc-windows-gnu&quot;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;&lt;span style=&quot;user-select: none;&quot;&gt;+&lt;/span&gt;        &quot;config//cpu:x86_64&quot;: &quot;x86_64-pc-windows-msvc&quot;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;     }),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; })&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now a build works!&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;console&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;〉buck2 build //:hello_world&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;File changed: root//BUCK&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;File changed: root//.git/index.lock&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;File changed: root//.git&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;6 additional file change events&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;Build ID: 65fc80aa-7bfa-433a-bfa7-57919147b550&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;Jobs completed: 65. Time elapsed: 1.0s. Cache hits: 0%. Commands: 1 (cached: 0, remote: 0, local: 1)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;BUILD SUCCEEDED&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We can run it to see the output:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;console&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;〉buck2 run //:hello_world&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;Build ID: 78b0ca23-2c7c-4c02-a161-bba15e3b38bd&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;Jobs completed: 3. Time elapsed: 0.0s.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;hello world&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Same idea as &lt;code&gt;cargo run&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Speaking of &lt;code&gt;cargo run&lt;/code&gt;, what might this look like with Cargo? Well, we can create
a &lt;code&gt;Cargo.toml&lt;/code&gt;:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;toml&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;package&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;name = &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;hello_world&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;version = &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;0.1.0&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;edition = &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;2021&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;[[&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;bin&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;]]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;name = &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;hello_world&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;path = &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;hello.rs&quot;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;and try it out. Oh, and you’ll probably want to put &lt;code&gt;target&lt;/code&gt; into your
&lt;code&gt;.gitignore&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Let’s build. The “benchmark” command in nushell is sort of like &lt;code&gt;time&lt;/code&gt; on a
UNIX system:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;console&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;〉benchmark { cargo build }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;   Compiling hello_world v0.1.0 (C:\Users\steve\Documents\GitHub\buck-rust-hello)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;    Finished dev [unoptimized + debuginfo] target(s) in 0.34s&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;416ms 490us 100ns&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;〉benchmark { cargo build }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;    Finished dev [unoptimized + debuginfo] target(s) in 0.00s&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;77ms 317us 200ns&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Not too bad, a bit under half a second for the initial build, and near immediate
on a subsequent build. What about buck?&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;console&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;〉benchmark { buck2 build //:hello_world -v 3 }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;Running action: &amp;#x3C;snip&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;Build ID: 47ebd9f1-3394-4f72-a0fb-02c936035d2b&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;Jobs completed: 58. Time elapsed: 0.8s. Cache hits: 0%. Commands: 1 (cached: 0, remote: 0, local: 1)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;BUILD SUCCEEDED&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;945ms 557us&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;〉benchmark { buck2 build //:hello_world -v 3 }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;Build ID: 5eed24e8-a540-454f-861a-855464aba3c9&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;Jobs completed: 3. Time elapsed: 0.0s.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;BUILD SUCCEEDED&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;78ms 274us 100ns&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Not too shabby; Buck is a &lt;em&gt;teeny&lt;/em&gt; bit slower on the initial build, but when stuff
is cached, both are the same speed. All of this is fast enough to qualify as
“basically instant.”&lt;/p&gt;
&lt;h2 id=&quot;adding-a-library&quot;&gt;Adding a library&lt;/h2&gt;
&lt;p&gt;Let’s up the complexity a bit, by adding a library that we want to depend on.
Here’s a &lt;code&gt;lib.rs&lt;/code&gt;:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;rust&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;pub&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; fn&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; print_hello&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;    println!&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;Hello, world!&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We want to change our top-level &lt;code&gt;BUCK&lt;/code&gt; to add this:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;diff&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;&lt;span style=&quot;user-select: none;&quot;&gt;+&lt;/span&gt;rust_library(&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;&lt;span style=&quot;user-select: none;&quot;&gt;+&lt;/span&gt;    name = &quot;print_hello&quot;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;&lt;span style=&quot;user-select: none;&quot;&gt;+&lt;/span&gt;    srcs = [&quot;lib.rs&quot;],&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;&lt;span style=&quot;user-select: none;&quot;&gt;+&lt;/span&gt;    edition = &quot;2021&quot;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;&lt;span style=&quot;user-select: none;&quot;&gt;+&lt;/span&gt;    visibility = [&quot;PUBLIC&quot;],&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;&lt;span style=&quot;user-select: none;&quot;&gt;+&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;&lt;span style=&quot;user-select: none;&quot;&gt;+&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; rust_binary(&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;     name = &quot;hello_world&quot;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;     srcs = [&quot;hello.rs&quot;],&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;     crate_root = &quot;hello.rs&quot;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;&lt;span style=&quot;user-select: none;&quot;&gt;+&lt;/span&gt;    deps = [&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;&lt;span style=&quot;user-select: none;&quot;&gt;+&lt;/span&gt;        &quot;:print_hello&quot;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;&lt;span style=&quot;user-select: none;&quot;&gt;+&lt;/span&gt;    ],&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; )&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here, we make a new library, &lt;code&gt;print_hello&lt;/code&gt;, and then make our binary depend
on it.&lt;/p&gt;
&lt;p&gt;Let’s change the code in &lt;code&gt;main.rs&lt;/code&gt; to use the library:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;rust&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;fn&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; main&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;    println!&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;hello world&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;    print_hello&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;print_hello&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And that’s it! Let’s examine our targets:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;console&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;〉buck2 targets //...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;Build ID: 4646f2e7-0ea3-4d59-8590-3da0708ce96e&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;Jobs completed: 4. Time elapsed: 0.0s.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;root//:hello_world&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;root//:print_hello&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;They’re both there! We can now build one, the other, or everything:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;console&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;# build everything&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;〉buck2 build //...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;# build just the library&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;〉buck2 build //:print_hello&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;# build &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;just&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; the binary, this will of course &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;end&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; up building the library too&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;〉buck2 build //:print_hello&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Let’s make sure it still prints our output:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;console&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;〉buck2 run //:hello_world&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;Build ID: d76c80fb-dd77-463a-86a1-b6443cea10f6&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;Jobs completed: 3. Time elapsed: 0.0s.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;Hello, world!&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Nice.&lt;/p&gt;
&lt;p&gt;Let’s compare that to Cargo. Modify &lt;code&gt;Cargo.toml&lt;/code&gt;:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;[lib]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;name = &quot;print_hello&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;path = &quot;lib.rs&quot;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;and build:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;console&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;〉cargo run&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;   Compiling hello_world v0.1.0 (C:\Users\steve\Documents\GitHub\buck-rust-hello)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;    Finished dev [unoptimized + debuginfo] target(s) in 0.42s&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;     Running `target\debug\hello_world.exe`&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;Hello, world!&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Nice.&lt;/p&gt;
&lt;h3 id=&quot;more-cargo-ish&quot;&gt;more cargo-ish&lt;/h3&gt;
&lt;p&gt;Before we move forward, this isn’t &lt;em&gt;exactly&lt;/em&gt; an apples to apples comparison; we’ve been doing a
lot of configuration for Cargo that we normally wouldn’t have to do, and also,
what if you already have a Cargo project, but you want to try out Buck with it?&lt;/p&gt;
&lt;p&gt;Do this:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;console&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&gt; mkdir src&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&gt; mv hello.rs src/main.rs&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&gt; mv lib.rs src/main.rs&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And delete the configuration from &lt;code&gt;Cargo.toml&lt;/code&gt;, leaving just the &lt;code&gt;package&lt;/code&gt; table.
Finally, we need to change &lt;code&gt;src/main.rs&lt;/code&gt;, given that we’re using the default
crate name for the library crate, which is &lt;code&gt;hello_world&lt;/code&gt; and not &lt;code&gt;print_hello&lt;/code&gt;:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;rust&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;fn&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; main&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;    hello_world&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;print_hello&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;After this, &lt;code&gt;cargo build&lt;/code&gt; works just fine. But what about Buck?&lt;/p&gt;
&lt;p&gt;So. We have a bit of weirdness here, and I’m not sure if it’s actually
work-around-able in Buck or not, since I’m still learning this myself. But
if we do the basic translation, we’ll get an error. Let’s try it. This is
how you modify the &lt;code&gt;BUCK&lt;/code&gt; file:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;rust_library(&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    name&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &quot;hello_world&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    srcs&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; glob([&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;src/**/*.rs&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;]),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    edition&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &quot;2021&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    visibility&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; [&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;PUBLIC&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;],&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;rust_binary(&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    name&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &quot;hello_world&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    srcs&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; [&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;src/main.rs&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;],&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    crate_root&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &quot;src/main.rs&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    deps&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; [&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;        &quot;:print_hello&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    ],&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Cargo produces a binary and a library, both called &lt;code&gt;hello_world&lt;/code&gt;, but buck
doesn’t like that:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;console&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;〉buck2 run //:hello_world&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;Error evaluating build file: `root//:BUCK`&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;Caused by:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;    Traceback (most recent call last):&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;      * BUCK:8, in &amp;#x3C;module&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;          rust_binary(&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;    error: Attempted to register target root//:hello_world twice, re-run the command with `--target-call-stacks` to obtain a call stack of the first registration&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;      --&gt; BUCK:8:1&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;       |&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;     8 | / rust_binary(&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;     9 | |     name = &quot;hello_world&quot;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;    10 | |     srcs = [&quot;src/main.rs&quot;],&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;    11 | |     crate_root = &quot;src/main.rs&quot;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;    12 | |     deps = [&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;    13 | |         &quot;:print_hello&quot;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;    14 | |     ],&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;    15 | | )&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;       | |_^&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;       |&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;Build ID: d6a8925d-0180-4308-bcb9-fbc888e7eca1&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;Jobs completed: 4. Time elapsed: 0.0s.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;BUILD FAILED&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It’s like hey! You have two targets named &lt;code&gt;hello_world&lt;/code&gt;! That’s confusing!
It also reveals a difference between Buck and Cargo. With Cargo, if you remember
our configuration, we had to point it to the crate root. From there, Cargo just
leans on &lt;code&gt;rustc&lt;/code&gt; to load up all of the other files that may be required if you
have a bunch of modules. But with Buck, we need to tell it up front which files we use.
So as you can see above:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    srcs &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; glob([&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;src/**/*.rs&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;]),&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We can use the &lt;code&gt;glob&lt;/code&gt; command to glob up all of our files, which is nice, but
it’s… it’s actually wrong. We want to glob everything &lt;em&gt;except&lt;/em&gt; &lt;code&gt;main.rs&lt;/code&gt;.
If &lt;code&gt;main.rs&lt;/code&gt; were to change, this would try and re-build both the binary and
the library, in my understanding. So that’s annoying.&lt;/p&gt;
&lt;p&gt;It’s not just annoying for Buck, though. Having both a &lt;code&gt;src/main.rs&lt;/code&gt; and a
&lt;code&gt;src/lib.rs&lt;/code&gt; has led to so much confusion from beginners over the years. At some
point, someone puts &lt;code&gt;mod lib;&lt;/code&gt; into &lt;code&gt;src/main.rs&lt;/code&gt; and everything goes to hell.
The original intention of this layout, to make simple things simple, is a good
idea, but I think that sadly, we missed the mark here. Luckily, Cargo also
supports a &lt;code&gt;bin&lt;/code&gt; directory:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;console&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&gt; mkdir src/bin&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&gt; mv src/main.rs src/bin&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We can still &lt;code&gt;cargo run&lt;/code&gt; and &lt;code&gt;cargo build&lt;/code&gt; and this all works just fine.
This doesn’t fix our glob issue, though, because &lt;code&gt;src/bin&lt;/code&gt; is still inside
of &lt;code&gt;src&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;I &lt;em&gt;think&lt;/em&gt;, in the abstract, I’d prefer a layout like &lt;code&gt;src/{lib,bin}&lt;/code&gt;. You want
things to not really be nested. So let’s do that. Both Cargo and Buck can
handle it! It’s just not as nice as being purely default in Cargo, since that
convention is so strong.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;console&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;# &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; you&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; didn&apos;t do this above&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&gt; mkdir src/bin&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&gt; mv src/main.rs src/bin&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&gt; mkdir src/lib&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&gt; mv src/lib.rs src/lib/print_hello.rs&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We have to change &lt;code&gt;src/bin/main.rs&lt;/code&gt; to use &lt;code&gt;hello_world&lt;/code&gt; again&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;rust&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;fn&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; main&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;    hello_world&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;print_hello&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And we have to re-add some configuration into &lt;code&gt;Cargo.toml&lt;/code&gt;:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;toml&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;lib&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;path = &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;src/lib/print_hello.rs&quot;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Everything should build just fine. But what about Buck?&lt;/p&gt;
&lt;p&gt;So, once you start getting into subdirectories, you can also start using
multiple &lt;code&gt;BUCK&lt;/code&gt; files. So we can empty out our root &lt;code&gt;BUCK&lt;/code&gt; file (I’m leaving it
existing but empty, if you want to delete it you can but you’ll recreate it in
the next part anyway), and create two new ones. Here’s &lt;code&gt;src/lib/BUCK&lt;/code&gt;:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;rust_library(&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    name&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &quot;hello_world&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    srcs&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; glob([&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;**/*.rs&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;]),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    crate_root&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &quot;print_hello.rs&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    edition&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &quot;2021&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    visibility&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; [&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;PUBLIC&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;],&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;and &lt;code&gt;src/bin/BUCK&lt;/code&gt;:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;rust_binary(&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    name&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &quot;hello_world&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    srcs&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; [&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;main.rs&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;],&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    crate_root&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &quot;main.rs&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    deps&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; [&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;        &quot;:hello_world&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    ],&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We added in a &lt;code&gt;crate_root&lt;/code&gt; to the library as well. Okay, let’s try this:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;console&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;〉buck2 run //:hello_world&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;File changed: root//src/lib/BUCK&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;Unknown target `hello_world` from package `root//`.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;Did you mean one of the 0 targets in root//:BUCK?&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;Build ID: d5059fc9-8001-47c4-ba5a-6ba605a4182c&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;Jobs completed: 2. Time elapsed: 0.0s.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;BUILD FAILED&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Oops! Since we moved files around, the names of our targets have changed. Let’s
examine them:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;console&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;〉buck2 targets //...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;Build ID: c4165964-cb87-49b4-8afe-4a3fc2c526bc&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;Jobs completed: 4. Time elapsed: 0.0s.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;root//src/bin:hello_world&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;root//src/lib:hello_world&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We had only seen very basic target patterns, but this is enough to show off:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;root/src/bin:hello_world&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;can be read as&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The “hello_world” target defined in &lt;code&gt;/src/bin/BUCK&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Our target names changing also means we made one mistake in our new &lt;code&gt;BUCK&lt;/code&gt; files.
Let’s give it a try:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;console&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;〉buck2 run //src/bin:hello_world&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;Error running analysis for `root//src/bin:hello_world (prelude//platforms:default#fb50fd37ce946800)`&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;Caused by:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;    0: Error looking up configured node root//src/bin:hello_world (prelude//platforms:default#fb50fd37ce946800)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;    1: Cyclic computation detected when computing key `root//src/bin:hello_world (prelude//platforms:default#fb50fd37ce946800)`, which forms a cycle in computation chain: `root//src/bin:hello_world (prelude//platforms:default#fb50fd37ce946800),root//src/bin:hello_world (prelude//platforms:default#fb50fd37ce946800)`&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;Build ID: 930ab541-c2dd-44f5-aef1-f6658a2b7c53&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;Jobs completed: 2. Time elapsed: 0.0s.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;BUILD FAILED&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Right. Our binary depends on &lt;code&gt;:hello_world&lt;/code&gt;, which it is itself named &lt;code&gt;hello_world&lt;/code&gt;,
so there’s a problem. But that’s just it, we don’t want to depend on any old
&lt;code&gt;hello_world&lt;/code&gt;, we want to depend on our libary. Can you write out the target
pattern that should go in &lt;code&gt;src/bin/BUCK&lt;/code&gt;?&lt;/p&gt;
&lt;p&gt;It looks like this:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    deps &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; [&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;        &quot;//src/lib:hello_world&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    ],&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;“The &lt;code&gt;hello_world&lt;/code&gt; target in &lt;code&gt;/src/lib/BUCK&lt;/code&gt;. Perfect. And now it works!&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;console&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;〉buck2 run //src/bin:hello_world&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;File changed: root//src/bin/BUCK&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;Build ID: c6d2fdaa-298a-425a-9091-d3f6b38c4336&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;Jobs completed: 12. Time elapsed: 0.5s. Cache hits: 0%. Commands: 1 (cached: 0, remote: 0, local: 1)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;Hello, world!&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It kinda stinks to have to type all of that out. Luckily, Buck supports aliases
for target patterns. Take our top-level &lt;code&gt;BUCK&lt;/code&gt; file, and add this:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;alias(&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    name&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &quot;build&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    actual&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &quot;//src/bin:hello_world&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;    visibility&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; [&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;PUBLIC&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;],&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And now we can use it:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;console&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;〉buck2 build&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;Build ID: a87ed1e2-cfab-47b0-830e-407217997fd7&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;Jobs completed: 2. Time elapsed: 0.0s.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;BUILD SUCCEEDED&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Fun.&lt;/p&gt;
&lt;p&gt;Okay! This is getting a bit long, so let’s end there. We have more to learn
before buck can actually replace Cargo in our normal development workflow, but
I hope this helped you see how you could get started with Buck if you wanted to.&lt;/p&gt;
&lt;p&gt;If you want to check out this on your own, I’ve published this on GitHub:
&lt;a href=&quot;https://github.com/steveklabnik/buck-rust-hello/tree/024ef54ba45627e87a65aaf2f69c6661198c336c&quot;&gt;https://github.com/steveklabnik/buck-rust-hello/tree/024ef54ba45627e87a65aaf2f69c6661198c336c&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Next up, we’ll be tackling other features, like “using crates from crates.io.”
No promises on when that’ll get published though!&lt;/p&gt;</content:encoded></item><item><title>Rust&apos;s Golden Rule</title><link>https://steveklabnik.com/writing/rusts-golden-rule/</link><guid isPermaLink="true">https://steveklabnik.com/writing/rusts-golden-rule/</guid><description>I find myself thinking about a particular design principle of Rust today. I’m not sure I’ve ever seen it named specifically before, but it gets referred to from time to time, and I think it’s an under-rated but very important aspect of why Rust works so well. I was going to refer…</description><pubDate>Mon, 27 Mar 2023 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I find myself thinking about a particular design principle of Rust today. I’m
not sure I’ve ever seen it named specifically before, but it gets referred to
from time to time, and I think it’s an under-rated but very important aspect
of why Rust works so well. I was going to refer to it as “the signature is the
contract” today, but then I ended up changing it. Regardless of that, if someone
else has already written this out somewhere, and used a different name, please
let me know!&lt;/p&gt;
&lt;p&gt;Magic: the Gathering is a really interesting project. I say “project” rather
than “card game” because while it is a card game, it also pioneered a whole
bunch of incedental other things that had big effects on related hobbies.&lt;/p&gt;
&lt;p&gt;I learned MtG in the late 90s. The rules were a bit different then, but many
of them are the same. The very first rule I was taught was sort of the “Magic
Golden Rule,” though in today’s Comprehensive Rulebook, there are four of them.
This one is still the first, though:&lt;/p&gt;
&lt;blockquote&gt;
&lt;ol start=&quot;101&quot;&gt;
&lt;li&gt;The Magic Golden Rules&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;101.1. Whenever a card’s text directly contradicts these rules, the card takes
precedence. The card overrides only the rule that applies to that specific
situation. The only exception is that a player can concede the game at any
time (see rule 104.3a).&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This rule is the most important rule because it kind of creates the spaces of
possibilities for cards: many cards exist to tweak, modify, or break some sort
of fundamental rule.&lt;/p&gt;
&lt;p&gt;That being said, all these years later, this idea is so pervasive in games like
this that it’s barely even considered an actual rule. It’s just part of the
physics of the genre, it’s how these games work. Yet it’s critical to the
entire enterprise.&lt;/p&gt;
&lt;p&gt;Rust also has a rule. It’s kinda funny, because in some senses, this rule
is almost the opposite of Magic’s, if you can even stretch the comparison this
far. Here it is:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Whenever the body of a function contradicts the function’s signature, the
signature takes precedence; the signature is right and the body is wrong.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This rule is also so pervasive in Rust that we take it for granted, but it
is really, truly important. I think it is also important for Rust users to
internalize the implications of this rule, so that they know why certain things
work the way that they do.&lt;/p&gt;
&lt;p&gt;Here is the most famous implication of this rule: Rust does not infer function
signatures. If it did, changing the body of the function would change its
signature. While this is convenient in the small, it has massive ramifications.&lt;/p&gt;
&lt;p&gt;Consider this example program:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;rust&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;fn&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; foo&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(x&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; i32&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;-&gt;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; i32&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;    dbg!&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(x);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    x&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This function prints out &lt;code&gt;x&lt;/code&gt;, and then returns it. Nothing fancy going on here,
this is just random stuff to make an example. This compiles just fine. But let’s
imagine that we have a version of Rust that infers our signatures. So we could
type this instead:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;rust&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;fn&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; foo&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(x) {&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is what a Ruby-ish Rust might look like; we declare the name of our
argument but not its type, and we don’t declare a return type. Now, let’s
do a small refactoring, we’re gonna comment out the final value there:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;rust&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;fn&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; foo&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(x) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;    dbg!&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(x);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;    //x&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;the final expression has changed; it’s no longer &lt;code&gt;x&lt;/code&gt;, but instead is &lt;code&gt;()&lt;/code&gt;,
which is what &lt;code&gt;dbg!(x);&lt;/code&gt; evaluates to. Because of type inference, the inferrred
type of &lt;code&gt;foo&lt;/code&gt; is now &lt;code&gt;fn(i32) -&gt; ()&lt;/code&gt;. Our function typechecks! It’s all good,
right?&lt;/p&gt;
&lt;p&gt;Well, no:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;text&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;error[E0369]: cannot add `{integer}` to `()`&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt; --&gt; src/lib.rs:5:11&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  |&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;5 |         y + 1&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  |         - ^ - {integer}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  |         |&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  |         ()&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Wait, what? We don’t have a &lt;code&gt;y + 1&lt;/code&gt; anywhere in our code?! Where’s that
error coming from… &lt;code&gt;src/lib.rs:5&lt;/code&gt;. What’s at the top of &lt;code&gt;lib.rs&lt;/code&gt;?&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;rust&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;mod&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; bar&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    fn&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; baz&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;() &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;-&gt;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; i32&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        let&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; y &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; crate::&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;foo&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;5&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        y &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 1&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Oh. Some other code was using &lt;code&gt;foo&lt;/code&gt;. When its signature changed, we broke
this invocation. It’s nice that alt-Rust caught this for us, but this error is
(would be, anyway!) really bad: no longer is it telling us that our code
is wrong, but instead points to some other code somewhere else we weren’t even
messing with. Sure, we can go “hey why is &lt;code&gt;y&lt;/code&gt; &lt;code&gt;()&lt;/code&gt;?” and then figure it out,
but compare that to today’s error:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;text&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;error[E0308]: mismatched types&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  --&gt; src/lib.rs:9:19&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;   |&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;9  | fn foo(x: i32) -&gt; i32 {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;   |    ---            ^^^ expected `i32`, found `()`&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;   |    |&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;   |    implicitly returns `()` as its body has no tail or `return` expression&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;10 |     dbg!(x);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;   |            - help: remove this semicolon to return this value&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This error is far better: it points out that the body of our function
contradicts the signature. It points out what in our body is generating the
value that contradicts the signature. And it doesn’t complain about callers.&lt;/p&gt;
&lt;p&gt;So sure, this gets us nicer error messages, but is that really a big deal?
I think it is, but it’s not the only implication here. I’d like to talk about
two more: one that’s clearly an advantage, and one that has led to some pain
that people would like to resolve. Balance :)&lt;/p&gt;
&lt;p&gt;First, the one that’s an advantage. The advantage is modularity. That makes
some forms of analysis much more reasonable, or sometimes even possible, as
opposed to super difficult. Because everything you need for memory safety is
described in the signature of the function, Rust doesn’t need to examine your
entire program to determine if there’s some shenanigans going on elsewhere.
This is far, far less work than just checking the signatures of the functions
you call. Each function can be checked in isolation, and then assembled
together. This is a very nice property.&lt;/p&gt;
&lt;p&gt;Second, where this leads to some pain. Users have nicknamed this one “borrow
splitting,” or “partial borrowing.” It looks like this:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;rust&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;struct&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; Point&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    x&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; i32&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    y&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; i32&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;impl&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; Point&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    pub&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; fn&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; x_mut&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;#x26;mut&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; self&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;-&gt;&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; &amp;#x26;mut&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; i32&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        &amp;#x26;mut&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; self&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;x&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    pub&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; fn&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; y_mut&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;#x26;mut&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; self&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;-&gt;&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; &amp;#x26;mut&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; i32&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        &amp;#x26;mut&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; self&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;y&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I find accessors, and especially mutators, to be where this sort of thing pops
up most often. This is the classic example. The above code is fine, but if we
try to do this:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;rust&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;// this doesn&apos;t work&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;impl&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; Point&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    pub&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; fn&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; calculate&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;#x26;mut&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; self&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;-&gt;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; i32&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        let&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; x &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; self&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;x_mut&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        let&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; y &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; self&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;y_mut&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;        // yes I picked multiplication because this looks kinda funny&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        *&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;x &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;*&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; *&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;y&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;// we would call it like this:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;let&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; answer &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; p&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;calculate&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We get this:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;text&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;error[E0499]: cannot borrow `*self` as mutable more than once at a time&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  --&gt; src/lib.rs:19:17&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;   |&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;18 |         let x = self.x_mut();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;   |                 ------------ first mutable borrow occurs here&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;19 |         let y = self.y_mut();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;   |                 ^^^^^^^^^^^^ second mutable borrow occurs here&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;20 |         &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;21 |         *x * *y&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;   |         -- first borrow later used here&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;However, if we didn’t have these accessors, &lt;code&gt;x&lt;/code&gt; and &lt;code&gt;y&lt;/code&gt; were instead just
public, this very similar free function:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;rust&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;fn&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; calculate&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(x&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; &amp;#x26;mut&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; i32&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, y&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; &amp;#x26;mut&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; i32&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;-&gt;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; i32&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    *&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;x &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;*&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; *&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;y&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;// called like this:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;let&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; answer &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; calculate&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;#x26;mut&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; point&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;x, &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;#x26;mut&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; point&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;y);&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;works just fine. Why? Because of the signatures. This signature:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;rust&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;pub&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; fn&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; calculate&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;#x26;mut&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; self&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;-&gt;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; i32&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;and these signatures:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;rust&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;pub&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; fn&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; x_mut&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;#x26;mut&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; self&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;-&gt;&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; &amp;#x26;mut&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; i32&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;pub&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; fn&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; y_mut&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;#x26;mut&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; self&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;-&gt;&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; &amp;#x26;mut&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; i32&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;says “hey, I am going to borrow all of &lt;code&gt;self&lt;/code&gt; mutably,” which implies an
exclusive reference to &lt;code&gt;self&lt;/code&gt;. That the body of &lt;code&gt;calculate&lt;/code&gt; borrows two
different parts of &lt;code&gt;self&lt;/code&gt; independently is 100% irrelevant, that’s what the
signature says! And so rustc looks at this and says “hey wait a minute,
calling &lt;code&gt;x_mut&lt;/code&gt; borrows &lt;code&gt;self&lt;/code&gt; mutably, and calling &lt;code&gt;y_mut&lt;/code&gt; borrows &lt;code&gt;self&lt;/code&gt;
mutably. That’s aliasing! Bad programmer!&lt;/p&gt;
&lt;p&gt;Whereas in the second example, this signature:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;rust&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;fn&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; calculate&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(x&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; &amp;#x26;mut&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; i32&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, y&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; &amp;#x26;mut&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; i32&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;-&gt;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; i32&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;says “hey, I have two mutable references, to two different integers.” And
at the call site, Rust sees that we’re creating two different borrows to two
different integers, even though they’re both part of our &lt;code&gt;point&lt;/code&gt;, and so it
okays things.&lt;/p&gt;
&lt;p&gt;This is kind of a pain in the butt! But what it saves us from is that scary
action at a distance in our typecheck example. Imagine that Rust somehow
inferred that the first version was okay, due to the body only being disjoint.
What happens in the future, when we refactor our function, and the borrows need
to change? That would have the same problem as before; we’d get weird errors
elsewhere in our code. There have been some proposals over the years to possibly
fix this pain point, but it’s a tough one. Putting “here’s the fields I’m
borrowing in the body” into the signature, in order to conform with the Golden
Rule, looks very odd. Maybe something will happen here, maybe not. I have
complicated feelings.&lt;/p&gt;
&lt;p&gt;So beyond error messages and making accessors/mutators awkward, how does this
affect you day to day? Well, one way is that I find I end up paying more
attention to signatures and less attention to bodies, when I’m trying to sort
something out. In many cases, what you’re doing in the body is irrelevant, I
care only about what your signature affords me. This isn’t &lt;em&gt;quite&lt;/em&gt; as true
as in some pure functional languages, but it has that vague feel to it. Another
way, and a slightly bigger one, has to do with the relationships between types
and TDD, but I think I’m going to save that for its own post.&lt;/p&gt;</content:encoded></item><item><title>Too many words about Rust&apos;s function syntax</title><link>https://steveklabnik.com/writing/too-many-words-about-rusts-function-syntax/</link><guid isPermaLink="true">https://steveklabnik.com/writing/too-many-words-about-rusts-function-syntax/</guid><description>There’s a famous quote by Eleanor Roosevelt: great minds discuss semantics, average minds discuss syntax and small minds discuss syntax of comments (Apologies, Phil Wadler.) I’d like to preface this post that I do not consider this to be an actual proposal to change Rust, even a…</description><pubDate>Tue, 03 Jan 2023 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;There’s a famous quote by Eleanor Roosevelt:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;great minds discuss semantics, average minds discuss syntax and small minds discuss syntax of comments&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;(Apologies, Phil Wadler.)&lt;/p&gt;
&lt;p&gt;I’d like to preface this post that I do &lt;em&gt;not&lt;/em&gt; consider this to be an actual
proposal to change Rust, even a pre-RFC. I don’t think that making changes like
this has enough benefits once a language is as established as Rust is. Consider
this post more of some musings about some things that there wasn’t really time
to truly consider when Rust was younger, so that maybe someone who’s making a
new language can learn from those things early enough in its life to do so.&lt;/p&gt;
&lt;p&gt;Also, I am not the first person to think about this, but I have lost the
previous post to time. There also may be a newfangled language that has this or
similar syntax already I’m not aware of. If you know of similar previous
proposals or languages, please let me know so that I can link to them here.&lt;/p&gt;
&lt;p&gt;Anyway, consider this post a “Steve decided to write up a thing instead of
just tweeting, it is not particularly well thought out but at least it’s down
on paper” kind of thing. A serious proposal here, even if I thought the idea was
good in general, which to repeat again, I do not, would require examining a lot
more corner cases than I do in this post.&lt;/p&gt;
&lt;p&gt;With all of that out of the way, let’s begin.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&quot;the-fn-syntax&quot;&gt;The fn syntax&lt;/h2&gt;
&lt;p&gt;Rust does a really good job of being orthogonal in many ways. While it isn’t a
tiny language, that things fit together nicely is one of the things that can
make it feel a lot smaller, in my opinion. There’s one thing, though, that
is really a bit inconsistent today, and that’s the syntax and semantics of
functions.&lt;/p&gt;
&lt;p&gt;Let me explain: you declare a function item (read: define a function) like this:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;rust&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;fn&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; foo&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(x&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; i32&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;-&gt;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; i32&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;    todo!&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Simple enough. However, there’s a lot more going on for more complex
declarations. &lt;a href=&quot;https://doc.rust-lang.org/1.66.0/reference/items/functions.html&quot;&gt;Here&lt;/a&gt; is the beginning of the current grammar
of functions:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;text&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Function :&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;   FunctionQualifiers fn IDENTIFIER GenericParams?&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;      ( FunctionParameters? )&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;      FunctionReturnType? WhereClause?&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;      ( BlockExpression | ; )&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I read this like this: “A function consists of some function qualifiers, fn,
an identifier, and an optional list of generic parameters. We then have some
optional function parameters inside of parenthesis, an optional return type,
an optional where clause, and then a block expression or a semicolon.”&lt;/p&gt;
&lt;p&gt;This is in sharp contrast to a C-style function definition, which would
look like this:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;c&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;int&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; foo&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;int&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt; x&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;    // todo&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In general, most new languages have tended to settle closer to Rust’s syntax
here than C’s. There are a few reasons, and it’s not like Rust invented this
style in the first place. One of the core nice things about Rust style syntax
is that &lt;code&gt;fn IDENTIFIER&lt;/code&gt;, that is, if you want to find out where &lt;code&gt;foo()&lt;/code&gt; is
defined, grep for &lt;code&gt;fn foo&lt;/code&gt; and you can find it pretty quickly. You can’t
do this as well with the &lt;code&gt;int&lt;/code&gt; syntax. Some code styles have you write&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;c&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;int&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;foo&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;int&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt; x&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;    // todo&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Notably, the GNU project uses this style:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;It is also important for function definitions to start the name of the
function in column one. This helps people to search for function definitions,
and may also help certain tools recognize them.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;You instead grep for &lt;code&gt;^foo&lt;/code&gt;, and you can get a similar benefit.&lt;/p&gt;
&lt;p&gt;So, what’s bad about this syntax? Well, there are useful ‘modifiers’ to
functions, and Rust has added some and may add more in the future. For example,
if we want &lt;code&gt;foo&lt;/code&gt; to be callable in a const context, we’d make it a &lt;code&gt;const fn&lt;/code&gt;:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;rust&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; fn&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; foo&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(x&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; i32&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;-&gt;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; i32&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;    todo!&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That’s all well and good, we still even retain the “grep for &lt;code&gt;fn&lt;/code&gt;” idea here,
but these are &lt;em&gt;also&lt;/em&gt; useful on arbitrary blocks of code:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;rust&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;let&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; x &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; const&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;    1&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; +&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 2&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;};&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is of course a trivial example that’s not very useful, but it shows off
the syntax here. My point is… this starts to feel a bit… nonuniform. In
the function delcaration, we put const at the front, but when it’s any other
block expression, we put it right before the block. Rust’s function bodies
are similar to blocks in other ways, such as the whole “evaluates to the final
expression” thing. But they’re different when they’re being used to describe
the body of a function. That’s a bit less than ideal.&lt;/p&gt;
&lt;p&gt;We could try the naive thing:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;rust&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;fn&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; foo&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(x&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; i32&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;-&gt;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; i32&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; const&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;    todo!&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is… weird, but it does sort of unify some syntaxes. We now can turn
any block of code, including a function body, &lt;code&gt;const&lt;/code&gt; by adding the &lt;code&gt;const&lt;/code&gt;
right before the opening brace. However… I kinda shudder at &lt;code&gt;i32 const&lt;/code&gt;.
There’s not enough separation between the return type and the modifier to make
quick sense of things, in my opinion. However, there’s another small tweak we
could make here. But first, a small divergence into another corner of Rust’s
syntax: variables.&lt;/p&gt;
&lt;h2 id=&quot;variables&quot;&gt;Variables&lt;/h2&gt;
&lt;p&gt;Rust also has a different syntax for variable declaration. Like C, it’s similar
to its function declaration syntax:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;rust&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;// Rust&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;let&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; x&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; i32&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 5&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;c&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;// C&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;int&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; x &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 5&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We have &lt;code&gt;let&lt;/code&gt; instead of &lt;code&gt;fn&lt;/code&gt;, we have the &lt;code&gt;name: type&lt;/code&gt; instead of &lt;code&gt;type name&lt;/code&gt;.
We can also declare a variable but not initialize it:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;rust&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;let&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; x&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; i32&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Rust will make us initialize it before we use it, but we can declare the
variable on its own, and then give it an initial value later.&lt;/p&gt;
&lt;p&gt;But what’s this has to do with functions?&lt;/p&gt;
&lt;h2 id=&quot;a-marginally-better-syntax&quot;&gt;A marginally better syntax&lt;/h2&gt;
&lt;p&gt;Functions also happen to have a “declare the signature but not the body” syntax
in Rust too, though it’s almost exclusively used in an FFI context. Remember
the very end of our grammar?&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;and then a block expression or a semicolon.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;If we have a function &lt;code&gt;foo&lt;/code&gt; that we’re calling through FFI, we can define it
like this:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;rust&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;#[link(name &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &quot;something&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;extern&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    fn&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; foo&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(x&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; i32&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;-&gt;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; i32&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We don’t provide a body, but we do provide a semicolon. This is strikingly
similar to the variable syntax. So why not have the regular function definition
also follow the variable syntax?&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;rust&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;fn&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; foo&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(x&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; i32&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;-&gt;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; i32&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;    todo!&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We’ve now added one little extra bit to the grammar: a &lt;code&gt;=&lt;/code&gt; after the return
type, if any. This one little change allows us to unify the rest of the syntax
around blocks more easily:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;rust&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;// full signature&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;fn&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; foo&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(x&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; i32&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;-&gt;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; i32&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;    todo!&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;};&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;// empty return type&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;fn&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; foo&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(x&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; i32&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;    todo!&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;};&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;// const&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;fn&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; foo&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(x&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; i32&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;-&gt;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; i32&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; const&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;    todo!&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;};&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I happen to &lt;em&gt;really&lt;/em&gt; like this. It’s a pretty small tweak but I think it
cleans stuff up nicely.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;text&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;let name = value;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;fn name() = value;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Where both could be values or blocks, with &lt;code&gt;let&lt;/code&gt; it’s most often a value but
with &lt;code&gt;fn&lt;/code&gt; it’s most often a block. The symmetry pleases me.&lt;/p&gt;
&lt;p&gt;(Sharp readers will also notice the introduction of a semicolon. Leaving it
off would be closer to the old syntax, requring it would be similar to the
variable syntax, but then that would diverge from the other item declaration
syntax… I don’t feel strongly about it but just in case anyone noticed I
figured I’d mention that as well, yet another rabbit hole to chase down.)&lt;/p&gt;
&lt;h2 id=&quot;going-too-far&quot;&gt;Going too far&lt;/h2&gt;
&lt;p&gt;This of course raises another divergence. But I’m not sure that fixing this one
is worth it; it starts to get &lt;em&gt;too&lt;/em&gt; weird, I think. But maybe I’m wrong. This
one is about the types.&lt;/p&gt;
&lt;p&gt;One of the things that makes &lt;code&gt;name: type&lt;/code&gt; syntax nicer than &lt;code&gt;type name&lt;/code&gt; syntax
is that it degrades nicely in the presence of type inference:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;rust&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;// Rust&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;let&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; x&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; i32&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 5&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;let&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; x &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 5&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;c&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;// C23 (https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3007.htm)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;int&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; x &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 5&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;auto x &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 5&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Rust’s function syntax isn’t like this though, partially because there’s no
type inference on function signatures, so there’s not a lot of pressure for
it to degrade nicely. The choice not to offer inference is the right one for
Rust, but for a future language where that’s not the case, we could unify
them with something like this:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;rust&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;// explicit type&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;fn&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; foo&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(x)&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; fn&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;i32&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;-&gt;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; i32&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;    todo!&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;// inferred&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;fn&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; foo&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(x) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;    todo!&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This one… this may be too far afield. And, while Rust doesn’t have named
parameters, and possibly never will, I have no idea how this style of syntax
would work with that. There’s also some repetition of &lt;code&gt;fn&lt;/code&gt; here that might be
worth trying to remove, but I’m trying to make the smallest possible deltas
from existing syntax here, and &lt;code&gt;fn(i32) -&gt; i32&lt;/code&gt; &lt;em&gt;is&lt;/em&gt; the type of that function
in today’s syntax.&lt;/p&gt;
&lt;p&gt;What I mostly take away from this part of the exercise is that consistency is
a good goal, but it’s not the &lt;em&gt;only&lt;/em&gt; goal. Even if Rust didn’t allow for
inference, making its function declaration syntax be like this may have simply
been a bridge too far for wide adoption. Rust already takes a lot of flak for
being weird, and spending some &lt;a href=&quot;/writing/the-language-strangeness-budget&quot;&gt;Strangeness Budget&lt;/a&gt; to unify these
syntaxes probably wouldn’t be the right choice. But maybe I’m too conservative!
Given that Rust already takes that flak, maybe a bigger jump would have been
okay here. Who knows.&lt;/p&gt;
&lt;p&gt;… actually, we have one way to find out, I guess. This is &lt;em&gt;very&lt;/em&gt; similar
to the syntax that Herb Sutter came up with for &lt;a href=&quot;https://github.com/hsutter/cppfront&quot;&gt;cppfront&lt;/a&gt;:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;rust&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;foo&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (x&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; i32&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;-&gt;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; i32&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;    // todo&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;There’s no &lt;code&gt;fn&lt;/code&gt; preceding. The type syntax works a bit differently. But it’s
close. And Herb is targetting the people who I’d be most worried about hating
this syntax: C++ folks. Maybe this idea isn’t so farfetched at all. He’s
also got an example of how making it any expression after the &lt;code&gt;=&lt;/code&gt; can be
nice for one-liner functions. If we applied this to our fake Rust syntax:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;rust&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;fn&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; main&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;() &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; println!&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;Hello, world!&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;fn&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; hello&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(name)&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; fn&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;#x26;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;str&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; println!&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;Hello, {name}!&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That’s kinda nice too.&lt;/p&gt;</content:encoded></item><item><title>Are out parameters idiomatic in Rust?</title><link>https://steveklabnik.com/writing/are-out-parameters-idiomatic-in-rust/</link><guid isPermaLink="true">https://steveklabnik.com/writing/are-out-parameters-idiomatic-in-rust/</guid><description>There is a pretty straightforward design pattern called “out parameters” that you may have heard of before. In short, the question is, does your function wear pants… err, I mean, does your function modify data like this: fn foo () -&gt; i32 { // body elided } let x = foo (); or like…</description><pubDate>Fri, 16 Oct 2020 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;There is a pretty straightforward design pattern called “out parameters” that you may have heard of before. In short, the question is, does your function wear pants… err, I mean, does your function modify data like this:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;rust&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;fn&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; foo&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;() &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;-&gt;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; i32&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;    // body elided&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;let&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; x &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; foo&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;or like this:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;rust&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;fn&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; foo&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(out&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; &amp;#x26;mut&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; i32&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;    // body elided&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;let&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; mut&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; x &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 0&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;foo&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;#x26;mut&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; x);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That is, does your function return a value, or modify a parameter?&lt;/p&gt;
&lt;p&gt;There are a number of different reasons you may or may not use one or the other of these techniques in different languages, and they often depend on the semantics of the language itself.&lt;/p&gt;
&lt;p&gt;In Rust, you almost always want to return a value from a function, that is, prefer option one over option two. There are a few reasons for this.&lt;/p&gt;
&lt;p&gt;The first is that it’s generally semantically more accurate. Your function is producing a value of some kind, so it should, well, produce a value. Additionally, with Rust’s relatively rich data type support, it’s easy to do things like return a tuple if you need to return more than one thing.&lt;/p&gt;
&lt;p&gt;The second is that, in some languages and with some compilers, the out parameter is a performance optimization that you as a programmer do by hand. Imagine if I wasn’t returning an &lt;code&gt;i32&lt;/code&gt;, which is just a few bytes. The most straightforward way of implementing the function in assembly is to copy the return value from the function to its parent’s stack. This also may be required by your ABI. Now, I am not an expert here, so I am not 100% sure of the exact current state of things, but at least in theory, optimizations can be done by the compiler. This is a pretty well-known optimization, see &lt;a href=&quot;https://en.wikipedia.org/wiki/Copy_elision&quot;&gt;Wikipedia for more&lt;/a&gt;. But, I think that we do already do this today in some cases, if I compile both of these functions:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;rust&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;fn&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; returns_huge&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(out&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; &amp;#x26;mut&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; [&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;u64&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;; &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;1024&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;]) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    *&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;out &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; [&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;; &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;1024&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;];&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;fn&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; returns_huge&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;() &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;-&gt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; [&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;u64&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;; &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;1024&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;] {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    [&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;; &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;1024&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I get identical assembly:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;rust&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;playground&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;returns_huge&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; # &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;@&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;playground&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;returns_huge&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;# &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;%&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;bb&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    movl    &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;$&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;8192&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;%&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;edx                     # imm &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 0x2000&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    xorl    &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;%&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;esi, &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;%&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;esi&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    jmpq    &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;*&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;memset&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;@&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;GOTPCREL&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;%&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;rip)          # &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;TAILCALL&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;                                        # &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;--&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; End&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; function&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;However, it is possible that this breaks for other examples, and so you may, may, may want to move to an out parameter if you see extraneous copies appear in your performance profiling.&lt;/p&gt;
&lt;p&gt;C++ guarantees this optimization in certain circumstances; it would be really nice for Rust to do so as well. My understanding is that’s the intention.&lt;/p&gt;
&lt;h2 id=&quot;when-you-should-use-out-parameters&quot;&gt;When you should use out parameters&lt;/h2&gt;
&lt;p&gt;There is one case where it is idiomatic to use an out parameter in Rust though. That’s when you are writing into some kind of buffer, and you want to be able to allow your caller to provide the buffer to you, rather than making a new one. This would allow the caller to re-use the same buffer for multiple operations.&lt;/p&gt;
&lt;p&gt;(I say “buffer” here but really, this generalizes to any sort of grow-able container, to be clear. I am using “buffer” in a loose sense here.)&lt;/p&gt;
&lt;p&gt;You can see this play out in the Rust standard library. &lt;code&gt;std::io::Read&lt;/code&gt; looks like this:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;rust&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;pub&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; trait&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; Read&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    fn&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; read&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;#x26;mut&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; self&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, buf&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; &amp;#x26;mut&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; [&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;u8&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;]) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;-&gt;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; Result&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;usize&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This accepts a &lt;code&gt;&amp;#x26;mut [u8]&lt;/code&gt; rather than returning a new buffer. This allows for significant savings by re-using a buffer. For example, in &lt;a href=&quot;https://doc.rust-lang.org/stable/book/ch02-00-guessing-game-tutorial.html&quot;&gt;Chapter 2 of the book&lt;/a&gt;, we have this example:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;rust&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;use&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; rand&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;Rng&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;use&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; std&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;cmp&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;Ordering&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;use&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; std&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;io;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;fn&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; main&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;    println!&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;Guess the number!&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    let&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; secret_number &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; rand&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;thread_rng&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;()&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;gen_range&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;101&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    loop&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;        println!&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;Please input your guess.&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        let&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; mut&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; guess &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; String&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;new&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;        io&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;stdin&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;            .&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;read_line&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;#x26;mut&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; guess)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;            .&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;expect&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;Failed to read line&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        let&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; guess&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; u32&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; match&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; guess&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;trim&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;()&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;parse&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;            Ok&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(num) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&gt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; num,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;            Err&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(_) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&gt;&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; continue&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        };&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;        println!&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;You guessed: {}&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, guess);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        match&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; guess&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;cmp&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;#x26;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;secret_number) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;            Ordering&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;Less&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&gt;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; println!&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;Too small!&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;            Ordering&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;Greater&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&gt;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; println!&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;Too big!&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;            Ordering&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;Equal&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&gt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;                println!&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;You win!&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;                break&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We aren’t &lt;em&gt;quite&lt;/em&gt; properly re-using the buffer here, but we could modify this to look like this:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;rust&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;use&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; rand&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;Rng&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;use&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; std&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;cmp&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;Ordering&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;use&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; std&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;io;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;fn&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; main&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;    println!&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;Guess the number!&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    let&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; secret_number &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; rand&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;thread_rng&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;()&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;gen_range&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;101&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    let&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; mut&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; guess &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; String&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;new&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    loop&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;        println!&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;Please input your guess.&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        guess&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;clear&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;        io&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;stdin&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;            .&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;read_line&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;#x26;mut&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; guess)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;            .&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;expect&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;Failed to read line&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        let&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; guess&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; u32&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; match&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; guess&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;trim&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;()&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;parse&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;            Ok&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(num) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&gt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; num,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;            Err&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(_) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&gt;&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; continue&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        };&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;        println!&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;You guessed: {}&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, guess);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        match&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; guess&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;cmp&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;#x26;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;secret_number) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;            Ordering&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;Less&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&gt;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; println!&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;Too small!&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;            Ordering&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;Greater&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&gt;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; println!&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;Too big!&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;            Ordering&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;Equal&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&gt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;                println!&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;You win!&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;                break&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here, we create our string outside of the loop, and then on each iteration of the loop, clear it. Clearing it does not deallocate the backing memory; it only changes the length to zero. When the next line is read in, if it’s smaller than the existing size of the string, it won’t allocate any new memory. This would not be possible if &lt;code&gt;stdin()&lt;/code&gt; returned a new &lt;code&gt;String&lt;/code&gt; every time, so even though the out parameter is a bit less nice to use, it can be much faster.&lt;/p&gt;
&lt;p&gt;It took 26 releases of Rust for &lt;a href=&quot;https://doc.rust-lang.org/stable/std/fs/fn.read.html&quot;&gt;&lt;code&gt;std::fs::read&lt;/code&gt;&lt;/a&gt; and &lt;a href=&quot;https://doc.rust-lang.org/stable/std/fs/fn.read_to_string.html&quot;&gt;&lt;code&gt;std::fs::read_to_string&lt;/code&gt;&lt;/a&gt; to be added for this reason; we eventually did because in many cases, you don’t care about re-using the buffer, and these functions are nicer to use, but they weren’t included originally because they’re pretty simple, and are built on top of the re-usable solutions:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;rust&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;pub&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; fn&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; read_to_string&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;P&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; AsRef&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;Path&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&gt;&gt;(path&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; P&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;-&gt;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; io&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;Result&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;String&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    fn&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; inner&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(path&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; &amp;#x26;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;Path&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;-&gt;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; io&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;Result&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;String&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        let&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; mut&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; file &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; File&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;open&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(path)&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;?&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        let&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; mut&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; string &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; String&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;with_capacity&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;initial_buffer_size&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;#x26;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;file));&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        file&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;read_to_string&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;#x26;mut&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; string)&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;?&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;        Ok&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(string)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;    inner&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(path&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;as_ref&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;())&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That said, I am exceedingly glad we did add them. It is a much nicer user experience.&lt;/p&gt;
&lt;p&gt;(You may be wondering “what’s up with that inner function there?”… that maybe deserves another post! It’s not neccesary, strictly speaking, but is another case of “the compiler does not do an optimization yet so write some code in a strange way by hand.”)&lt;/p&gt;</content:encoded></item><item><title>The CXX Debate</title><link>https://steveklabnik.com/writing/the-cxx-debate/</link><guid isPermaLink="true">https://steveklabnik.com/writing/the-cxx-debate/</guid><description>Let’s talk about safe and unsafe in Rust. To review, Rust has a concept of “unsafe code.” Unsafe Rust is a superset of safe Rust, letting you do some extra things that are dangerous. It’s your job as a programmer to verify that your code is playing by the rules, because the…</description><pubDate>Sat, 22 Aug 2020 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Let’s talk about safe and unsafe in Rust.&lt;/p&gt;
&lt;p&gt;To review, Rust has a concept of “unsafe code.” Unsafe Rust is a superset of safe Rust, letting you do some extra things that are dangerous. It’s your job as a programmer to verify that your code is playing by the rules, because the compiler cannot check them for you.&lt;/p&gt;
&lt;p&gt;Imagine we have a C program, &lt;code&gt;add.c&lt;/code&gt; that looks like this:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;c&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;#include&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &amp;#x3C;stdint.h&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;uint32_t&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; add_one&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;uint32_t&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt; x&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    return&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; x &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 1&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We can call this function from Rust like this:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;rust&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;extern&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    fn&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; add_one&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(x&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; u32&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;-&gt;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; u32&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;fn&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; main&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    let&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; x &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 5&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    let&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; y &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; unsafe&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; { &lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;add_one&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(x) };&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;    println!&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;{}&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, y);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We need to invoke &lt;code&gt;unsafe&lt;/code&gt; here because any &lt;code&gt;extern&lt;/code&gt; function doesn’t come from Rust; it comes from another language, and it’s possible that that function does something that would cause undefined behavior. We look at &lt;code&gt;add_one&lt;/code&gt;, see that it’s not violating any rules, and we’re good.&lt;/p&gt;
&lt;p&gt;However, we know that we can pass any &lt;code&gt;u32&lt;/code&gt; to this function, and it’s safe. We don’t need to example the value of the argument every single time, they’re all fine. So we do this:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;rust&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;mod&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; internal&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    extern&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        pub&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; fn&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; add_one&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(x&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; u32&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;-&gt;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; u32&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;fn&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; add_one&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(x&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; u32&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;-&gt;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; u32&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    unsafe&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;        internal&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;add_one&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(x)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;fn&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; main&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    let&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; x &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 5&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    let&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; y &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; add_one&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(x);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;    println!&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;{}&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, y);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is a classic way that unsafe code gets used in Rust; we have our binding, &lt;code&gt;internal::add_one&lt;/code&gt;, and our wrapper, &lt;code&gt;add_one&lt;/code&gt;. The wrapper is safe, but uses unsafe internally. This is totally fine! The idea is that this gives us a sort of “seam” in our code. Imagine that &lt;code&gt;add_one&lt;/code&gt; would do bad things if we passed it a number less than five. We could use our wrapper to check this:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;rust&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;// we would use a real error type in real code but we&apos;re using () here because we don&apos;t&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;// actually care about the error handling here.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;fn&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; add_one&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(x&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; u32&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;-&gt;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; Result&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;u32&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, ()&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; x &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 5&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        return&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; Err&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(());&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    unsafe&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;        Ok&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;internal&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;add_one&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(x))&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;But, &lt;code&gt;add_one&lt;/code&gt; doesn’t need to do this. Every &lt;code&gt;u32&lt;/code&gt; we pass is totally fine.&lt;/p&gt;
&lt;p&gt;Nothing so far is controversial here, this is just background and setup. The purpose of these examples is for you to read and ask yourself, “Is this okay? How do I feel about this?”&lt;/p&gt;
&lt;p&gt;Somewhere after this point, opinions start to diverge.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;Our C library is growing new functionality! Here it is:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;c&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;#include&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &amp;#x3C;stdint.h&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;uint32_t&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; add_one&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;uint32_t&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt; x&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    return&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; x &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 1&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;uint32_t&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; add_two&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;uint32_t&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt; x&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    return&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; x &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 2&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We can now add two, not only one. Amazing, I know. Let’s write another wrapper:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;rust&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;mod&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; internal&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    extern&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        pub&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; fn&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; add_one&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(x&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; u32&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;-&gt;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; u32&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        pub&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; fn&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; add_two&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(x&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; u32&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;-&gt;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; u32&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;fn&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; add_one&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(x&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; u32&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;-&gt;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; u32&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    unsafe&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;        internal&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;add_one&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(x)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;fn&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; add_two&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(x&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; u32&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;-&gt;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; u32&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    unsafe&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;        internal&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;add_two&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(x)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;fn&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; main&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    let&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; x &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 5&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    let&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; y &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; add_one&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(x);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    let&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; z &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; add_two&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(x);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;    println!&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;{}, {}&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, y, z);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Two functions, both have an unsafe binding, and a safe wrapper.&lt;/p&gt;
&lt;p&gt;Is this okay? How do you feel about this?&lt;/p&gt;
&lt;p&gt;Now, imagine we had 100 of these functions. Writing this all out ends up being a massive amount of error-prone boilerplate. Heck, I almost forgot to switch to &lt;code&gt;internal::add_two&lt;/code&gt; after I copy/pasted the new function there. Rust has a tool to abstract over code like this: macros! So let’s refactor our code with a macro:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;rust&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;macro_rules!&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; call_c&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;    // implementation elided&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;call_c!&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    fn&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; add_one&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(x&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; u32&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;-&gt;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; u32&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    fn&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; add_two&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(x&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; u32&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;-&gt;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; u32&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;fn&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; main&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    let&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; x &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 5&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    let&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; y &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; add_one&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(x);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    let&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; z &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; add_two&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(x);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;    println!&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;{}, {}&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, y, z);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I am not showing you the macro because the exact contents are gnarly and immaterial to the point. I also think that maybe this needs to be a procedural macro not a &lt;code&gt;macro_rules&lt;/code&gt; macro but again, those details don’t really matter. The point is, we have a macro, it generates the exact same structure that we had before.&lt;/p&gt;
&lt;p&gt;Is this okay? How do you feel about this?&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;This wrapper is also known as &lt;a href=&quot;https://github.com/dtolnay/cxx&quot;&gt;CXX&lt;/a&gt;. The syntax is slightly different, but conceptually, this is what it is doing. The reason it is controversial is that some people do not in fact feel that the above macro is okay. The reason that they feel it is not okay is that you do not write &lt;code&gt;unsafe&lt;/code&gt; by hand, yet, if you’re not careful, things can go wrong. I think this is a totally understandable and reasonable reaction, but I also don’t think that it makes a ton of sense once you actually dig into the details.&lt;/p&gt;
&lt;p&gt;We actually don’t need C to think about this problem, we can do this with unsafe Rust purely. And I think that using unsafe Rust makes it a bit more clear, so let’s talk about this in some more depth, but purely with Rust.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;unsafe&lt;/code&gt; keyword has two, complimentary uses. It can be used to require your caller to check invariants, and it can be used to tell the compiler “I have checked the invariants.” In other words:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;rust&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;// I am leaving off parameters and return types because it doesn&apos;t matter, but real code&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;// would of course have them.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;// When calling foo, please check some invariants.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;unsafe&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; fn&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; foo&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;    // ...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;// I have checked the invaraints, and this is okay to do.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;unsafe&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;    foo&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The compiler forces these combinations of things; using a feature that generates a requirement to check something will require you to also declare that you’ve checked it. These requirements bubble up, in other words, we can also pass that obligation to our callers:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;rust&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;unsafe&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; fn&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; foo&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;   // ...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;fn&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; bar1&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;    // I have checked the invariants, and this is okay to do&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    unsafe&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;        foo&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;// I have not checked the invariants, so since I&apos;m calling foo, you must check&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;// the invariants&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;unsafe&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; fn&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; bar2&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;    foo&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Rust’s built-in FFI works like &lt;code&gt;bar2&lt;/code&gt;; if the contents of &lt;code&gt;foo&lt;/code&gt; are written in another language, it has to be unsafe. This means that, even if it is perfectly safe to call &lt;code&gt;foo&lt;/code&gt; with any possible arguments, or in any circumstances, we still need to write a wrapper.&lt;/p&gt;
&lt;p&gt;CXX’s take on FFI is that it works like &lt;code&gt;bar1&lt;/code&gt;; by using the library we are saying “hey, I know that &lt;code&gt;foo&lt;/code&gt; is safe in all circumstances, so please generate the wrapper for me.” In other words, in some sense, it pushes the unsafe block across the other side of the boundary, because that’s where it actually belongs in this case.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;This has generated a lot of feelings on both sides. The people who don’t like it are upset that the letters &lt;code&gt;[&apos;u&apos;, &apos;n&apos;, &apos;s&apos;, &apos;a&apos;, &apos;f&apos;, &apos;e&apos;]&lt;/code&gt; are not present, and feel that this makes it quite easy to make a mistake and accidentally use the macro on some code that is not actually safe to call in all circumstances. The people who do like it argue that when you have a large number of calls that are actually safe, using a macro to abstract them away is fine, like you’d abstract away any other boilerplate. Sometimes, repeating the same thing over and over again makes mistakes more likely, not less.&lt;/p&gt;
&lt;p&gt;In the meantime, &lt;a href=&quot;https://www.reddit.com/r/rust/comments/ielvxu/the_cxx_debate/g2i1r7a/?context=3&quot;&gt;dtolnay has decided&lt;/a&gt; to change the macro and re-add the &lt;code&gt;unsafe&lt;/code&gt; token, which helps assuage the fears of the people who are upset. But it also centralizes these sorts of uses of &lt;code&gt;unsafe&lt;/code&gt;, which helps achieve the goals of the library in the first place. I am continually impressed by dtolnay’s ability to design libraries, and hope he keeps writing Rust code forever.&lt;/p&gt;
&lt;p&gt;Anyway, if you were wondering what this all was about, that’s my take on it. I personally feel that CXX is fine the way that it is, but I’m also happy with this compromise, and hope that others are too.&lt;/p&gt;</content:encoded></item><item><title>How often does Rust change?</title><link>https://steveklabnik.com/writing/how-often-does-rust-change/</link><guid isPermaLink="true">https://steveklabnik.com/writing/how-often-does-rust-change/</guid><description>I’ve been thinking a lot lately about how often Rust changes. There are some people that assert that Rust stays fairly static these days, and there are some people who say Rust is still changing far too much. In this blog post, I want to make a data driven analysis of this…</description><pubDate>Sat, 11 Apr 2020 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I’ve been thinking a lot lately about how often Rust changes. There are some people that assert that Rust stays fairly static these days, and there are some people who say Rust is still changing far too much. In this blog post, I want to make a &lt;em&gt;data driven&lt;/em&gt; analysis of this question. First, I will present my hypothesis. Next, my methodology. Then, we’ll talk about the results. Afterward, we’ll discuss possible methodological issues, and possible directions for further research.&lt;/p&gt;
&lt;p&gt;As &lt;a href=&quot;https://twitter.com/adam_chal/status/1248705340163620866&quot;&gt;said on twitter&lt;/a&gt;:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://svbtleusercontent.com/66pLpg8EDEH5dvt5BGQ7LH0xspap_small.jpg&quot; alt=&quot;https://svbtleusercontent.com/66pLpg8EDEH5dvt5BGQ7LH0xspap_small.jpg&quot;&gt;&lt;/p&gt;
&lt;h2 id=&quot;the-hypothesis&quot;&gt;The hypothesis&lt;/h2&gt;
&lt;p&gt;My personal take on Rust changing: to me, it feels like we had more change in the past than we have today. The changes are also getting more minor. This will be my hypothesis.&lt;/p&gt;
&lt;h2 id=&quot;the-methodology&quot;&gt;The methodology&lt;/h2&gt;
&lt;p&gt;There are tons of different ways that we could measure the question “how often does Rust change?” So before I started collecting data, I had to decide some details.&lt;/p&gt;
&lt;p&gt;I realized that my premise here is about how people &lt;em&gt;feel&lt;/em&gt; about Rust. So, how do they tend to understand how Rust changes? Well, the primary way that we communicate change to the Rust community is through release blog posts. So I decided to start there.&lt;/p&gt;
&lt;p&gt;What I did was, I opened up every release blog post for Rust, from 1.0.0 to 1.42.0, in a new tab. For fun, I also opened the release notes for 1.43, which will come out soon.&lt;/p&gt;
&lt;p&gt;I then looked at every single change announced, and categorized them as follows:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;adds syntax?&lt;/li&gt;
&lt;li&gt;language&lt;/li&gt;
&lt;li&gt;standard library&lt;/li&gt;
&lt;li&gt;toolchain&lt;/li&gt;
&lt;li&gt;major&lt;/li&gt;
&lt;li&gt;medium&lt;/li&gt;
&lt;li&gt;minor&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I initially included “deprecation” and “soundness” as categories too, but I ended up not including them. More on that later.&lt;/p&gt;
&lt;p&gt;From here, I had to decide what these categories &lt;em&gt;meant&lt;/em&gt;. What standard would I be using here? Here’s the easier ones:&lt;/p&gt;
&lt;p&gt;&lt;em&gt;language&lt;/em&gt; changes mean some sort of modification to the language definition. These are additive changes, thanks to our stability policy, but they’re new additions.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;standard library&lt;/em&gt; means a change to the standard library, primarily, new functions, new types, new methods, stuff like that. This one is pretty simple as a criteria but there’s some small interesting methodological issues we’ll get into later.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;toolchain&lt;/em&gt; changes related to &lt;code&gt;cargo&lt;/code&gt;, &lt;code&gt;rustup&lt;/code&gt;, new compiler target support, stuff like that. Not part of the language proper, but part of the Rust distribution and things Rust programmers would use.&lt;/p&gt;
&lt;p&gt;Now, for the harder ones:&lt;/p&gt;
&lt;p&gt;&lt;em&gt;major&lt;/em&gt;/&lt;em&gt;medium&lt;/em&gt;/&lt;em&gt;minor&lt;/em&gt; changes are how big of a change I think that the change is. There’s a few interesting parts to this. First of all, this is, of course, very subjective. I also decided to try and evaluate these as of today, that is, there are some changes we maybe thought were major that aren’t used all that often in practice today, so I categorized those as &lt;em&gt;medium&lt;/em&gt; rather than &lt;em&gt;major&lt;/em&gt;. This felt more consistent to me than trying to remember how I felt at the time.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;adds syntax&lt;/em&gt; changes &lt;em&gt;sound&lt;/em&gt; easy, but are actually &lt;em&gt;really&lt;/em&gt; tricky. For example, consider a feature like “&lt;a href=&quot;https://github.com/rust-lang/rfcs/blob/master/text/1492-dotdot-in-patterns.md&quot;&gt;dotdot in patterns&lt;/a&gt;”. This does change the grammar, for example, so you could argue that it adds syntax. But as a programmer, I don’t &lt;em&gt;really&lt;/em&gt; care about the grammar. The summary of this feature is “Permit the .. pattern fragment in more contexts.” It goes on to say:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;This RFC is intended to “complete” the feature and make it work in all possible list contexts, making the language a bit more convenient and consistent.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I think these kinds of changes are actually very core to this idea, and so I decided to categorize them according to my opinion: this is &lt;em&gt;not&lt;/em&gt; a new syntax change. You already had to know about &lt;code&gt;..&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;I believe this may be the most controversial part of my analysis. More on this later, of course.&lt;/p&gt;
&lt;p&gt;Okay, so that’s the stuff I covered. But there’s also stuff I didn’t cover. I was doing enough work and had to draw the line somewhere. I left this stuff out:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;compiler speedups. This is interesting with numbers, but that means actually compiling stuff, and I don’t have time for that. This is a whole study on its own.&lt;/li&gt;
&lt;li&gt;Documentation work. This tends to be not tracked as new features, but sometimes it appears in release notes, for bigger things. Better to just leave it out. I also don’t think that it affects my hypothesis at all.&lt;/li&gt;
&lt;li&gt;Library types implementing new traits. These can be hard to number, especially with generics involved. I decided that it would be better to leave them off.&lt;/li&gt;
&lt;li&gt;compiler internal news. We sometimes talk about things like “MIR exists now!” or “we ported the build system from make to cargo!” but similar to documentation, we talk about it very little. It’s also not a change that affects end users, or rather, it affects them more directly by stuff that is counted. MIR enabled NLL, and NLL was tracked as a language feature.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;the-results--analysis&quot;&gt;The results &amp;#x26; analysis&lt;/h2&gt;
&lt;p&gt;I am not as good with Google Sheets as I thought, so I asked for help. Big thanks to &lt;a href=&quot;https://twitter.com/ManishEarth&quot;&gt;Manish&lt;/a&gt; for helping me get this together. I should note that he set me up, but then I tweaked a ton of stuff, so any mistakes are mine, not his. For example, I got a little lazy and didn’t realize that the colors aren’t the same across the various charts. That’s my bad.&lt;/p&gt;
&lt;p&gt;Here’s some quick totals of how many changes and of each kind I found, with some sparklines. You can click on any of the images in this post to enlarge them:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://svbtleusercontent.com/i84Jyi8Ku2vJ2VRGfYmyBV0xspap_small.png&quot; alt=&quot;https://svbtleusercontent.com/i84Jyi8Ku2vJ2VRGfYmyBV0xspap_small.png&quot;&gt;&lt;/p&gt;
&lt;p&gt;And here’s some charts, per release:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://svbtleusercontent.com/oZTrBYjy26f5AKURN7z3db0xspap_small.png&quot; alt=&quot;https://svbtleusercontent.com/oZTrBYjy26f5AKURN7z3db0xspap_small.png&quot;&gt;&lt;/p&gt;
&lt;p&gt;First of all, it is fairly clear that, at least numerically speaking, the standard library is the part of Rust that changes most often. It’s a clear outlier by volume. I find this result kind of hilarious, because Rust is well-known for having a small standard library. We’ll talk more about why I think this is in the “Issues and further research” section below.&lt;/p&gt;
&lt;p&gt;Let’s look at the chart without the standard library:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://svbtleusercontent.com/qXu9v6Li5qzg8Ag6HV1j8p0xspap_small.png&quot; alt=&quot;https://svbtleusercontent.com/qXu9v6Li5qzg8Ag6HV1j8p0xspap_small.png&quot;&gt;&lt;/p&gt;
&lt;p&gt;You can see there’s a &lt;em&gt;ton&lt;/em&gt; of toolchain changes early on. We had a lot of work to do early on, and so made a ton of changes! It’s calmed down in recent times, but toolchain changes happen almost twice as often as language changes. I should also note that this reduction in toolchain changes may be due to methodology; this is talked about later in the post.&lt;/p&gt;
&lt;p&gt;So, the core question here: it looks like the language is changing &lt;em&gt;more&lt;/em&gt;, recently, rather than less. I think it’s pretty clear that this graph is &lt;em&gt;not&lt;/em&gt; exactly what I would imagine, that is, I expected a nice gentle curve down, but that’s not what has happened. I want to dig into this a bit more, but first, let’s look at some other graphs:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://svbtleusercontent.com/3Xa9rr1SM3atm69gAohMkM0xspap_small.png&quot; alt=&quot;https://svbtleusercontent.com/3Xa9rr1SM3atm69gAohMkM0xspap_small.png&quot;&gt;&lt;/p&gt;
&lt;p&gt;Changes that add syntax are a subset of language changes. There hasn’t been a whole ton of this, overall. Rust 2018 was the large bump. Half of our releases do not add syntax, though 10 out of 43 did introduce language changes. Our first 29 releases, skipping 1.26, had around one or two changes on average, but every since, it’s been between three and four. I believe this has to do with my methodology, but at the same time, this pretty resoundingly refutes my hypothesis. Very interesting!&lt;/p&gt;
&lt;p&gt;Here’s major/medium/minor:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://svbtleusercontent.com/cm4iWVjB9XZw4qp3c5b94o0xspap_small.png&quot; alt=&quot;https://svbtleusercontent.com/cm4iWVjB9XZw4qp3c5b94o0xspap_small.png&quot;&gt;&lt;/p&gt;
&lt;p&gt;There’s a peak around Rust 2018, and one from 1.12 to 1.19, but otherwise, it’s been pretty steady lately, in terms of overall changes. If we look at just major changes:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://svbtleusercontent.com/N3Dud8Du3fUEC8LL8a9Fn0xspap_small.png&quot; alt=&quot;https://svbtleusercontent.com/N3Dud8Du3fUEC8LL8a9Fn0xspap_small.png&quot;&gt;&lt;/p&gt;
&lt;p&gt;Rust 2018 had a huge bump. After 1.0, and after Rust 2018, it calmed. I think this chart is &lt;em&gt;very&lt;/em&gt; interesting, and demonstrates the 3 year edition cycle well. We ship an edition, stuff calms down, things slowly build back up, we ship an edition, they calm down again.&lt;/p&gt;
&lt;p&gt;So, why was my hypothesis wrong? I think this conclusion is &lt;em&gt;fascinating&lt;/em&gt;. I think part of it has to do with my methodology, and that maybe, that difference explains some of the ways people feel about Rust. You see, even if we release extremely often, and a lot of releases don’t have a &lt;em&gt;ton&lt;/em&gt; of changes in them (as you can see, it’s vaguely around 8 or 10, when you exclude the standard library, on average), the very fact that we do release often and have a decent, but fairly small amount of change means that things get into the release notes that may not if we had the exact same amount of change, but did yearly releases.&lt;/p&gt;
&lt;p&gt;So for example, in 2019, we released Rust 1.32 to 1.40. That involved 35 language changes. Would I have included, say, “you can now use &lt;code&gt;#[repr(align(N))]&lt;/code&gt; on enums” if I had been writing a post about all of these changes for the whole year? Probably not. But because there were only eight total changes in that release, with half of those being language changes, it made sense to include in the 1.37 release post.&lt;/p&gt;
&lt;p&gt;Does this mean that folks who read the release posts and think Rust changes a lot are wrong? No, it does not. For those of us in the thick of it, a lot of the smaller changes kind of blur into the background. I actually initially typed “&lt;code&gt;#[repr(N)]&lt;/code&gt; on enums” when writing the above sentence, because this change isn’t relevant to me or my work, and is pretty small, and makes things more orthogonal, and so it is just kind of vague background noise to me. But to someone who isn’t as in-tune with the language, it’s harder to know what’s big and what’s small. The endless release posts with tons of stuff in them makes it &lt;em&gt;feel&lt;/em&gt; like a lot is happening. But the same amount of stuff may be happening in other languages too, you just don’t see them in release posts, because they only put out one once a year. You both see them less often, as well as see less in them.&lt;/p&gt;
&lt;p&gt;I don’t think this means that the Rust project should change its release schedule, and I’m not entirely sure if this means we should change how we write release posts. However, maybe there’s a better way to surface “these are big changes” vs “this is a small thing,” or something like that. I’m not sure. But I do think this helps me understand the disconnect a lot better.&lt;/p&gt;
&lt;h2 id=&quot;issues-and-further-research&quot;&gt;Issues and further research&lt;/h2&gt;
&lt;p&gt;There are some big issues with this methodology. No analysis is perfect, but I want to be fair, so I’m calling out all of the stuff I can think of, at least.&lt;/p&gt;
&lt;p&gt;The first of which is, this is inherently subjective. There’s different degrees of subjectivity; for example, “total changes in the notes” is fairly objective. But not completely; folks have to decide what goes into the release notes themselves. So there’s already a layer of filtering going on, before I even started looking at the data. Doing this analysis took me two days of real time, but only a few hours of actual work. Something that analyses the git repo in an automated fashion may see other results. I argue that this level of subjectivity is okay, because we’re also testing something subjective. And I think I designed my methodology in a way that captures this appropriately. On some level, it doesn’t matter if the “real” answer is that Rust rarely changes: folks still get this info by reading the posts, and so I don’t think saying that “oh, yeah you feel that way, but this graph says your feelings are wrong” is really going to help this debate.&lt;/p&gt;
&lt;p&gt;The second problem expands on this. We sort of had three eras of release note writing: the first few posts were written by Aaron and Niko. As of Rust 1.4, I took over, and wrote &lt;em&gt;almost&lt;/em&gt; every post until 1.33. I then stepped back for a while, though I did help write the 1.42 post. The release team wrote 1.34 onward, and it was more of a collaborative effort than previous posts. This means that the person doing the filter from release notes -&gt; blog post changed over time. This can mess with the numbers. For example, there are some blog posts where I would have maybe omitted a small family of features, but the folks writing that post included them all, individually. This may explain the uptick in language changes lately, and why many of them were not rated as “major.” Additionally, the people who did the filter from “list of PRs” to “release notes” &lt;em&gt;also&lt;/em&gt; changed over time, so there’s some degree of filtering change there, as well.&lt;/p&gt;
&lt;p&gt;To complicate things further, starting with Rust 1.34, Cargo lost its section in the release blog posts. Big changes in Cargo still made it into the text, but the previous posts had more robust Cargo sections, and so I feel like post-1.34, Cargo was under-counted a bit. Cargo changes are toolchain changes, and so the recent calm-ness of the toolchain numbers may be due to this. This still is okay, because again, this analysis is about folks reading the release notes, but it’s worth calling out. Likewise, I think the standards for writing the library stabilizations changed a bit over time too; it’s gone from more to less comprehensive and back again a few times.&lt;/p&gt;
&lt;p&gt;This was mentioned above a bit, but for completeness, the structure of Rust releases means there’s a variable criteria for what makes it into a release post. If it’s a smaller release, smaller changes may get featured, whereas if those same feature were in a bigger release, they may not have been. I think this aspect is a significant factor in the rejection of my hypothesis, as I mentioned above.&lt;/p&gt;
&lt;p&gt;I think there’s interesting future research to be done here. I initially tried to track deprecations and soundness fixes, but soundness fixes happened so little it wasn’t worth talking about. There were 7 in those 42 releases. This is another weakness / area for future research, because I did not include point releases, only 1.x.0 releases. This would have added a few more soundness fixes, but it also would have added a lot of random noise where not much happened in the graphs, so that’s why I left those out. They also don’t happen on the same regular schedule, so time would get a bit funny… anyway. Deprecations was also just hard to track because there weren’t a lot of them, and sometimes it was hard to say if something was deprecated because of a soundness issue vs other reasons.&lt;/p&gt;
&lt;p&gt;Is my critera for adding syntax correct? I think a reasonable person could say “no.” If you have something that’s special cased, and you’re making it more general, there’s a good argument that this is &lt;em&gt;removing&lt;/em&gt; a restriction, rather than adding a feature. But reasonable folks could also say you’ve added something. I don’t think that this part is core to my analysis, and so I think it’s fine that I’ve made this decision, but you may not care for this section of results if you disagree.&lt;/p&gt;
&lt;p&gt;This analysis doesn’t get into something that I think is a huge deal: the ecosystem vs the language itself. I only track the Rust distribution itself here, but most Rust programmers use many, many ecosystem libraries. When people talk about churn in Rust, do they really mean the ecosystem, not the language? In some sense, doing so is correct: Rust having a small standard library means that you have to use external packages a lot. If those churn a lot, is it any better than churn in the language itself?&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Does&lt;/em&gt; Rust have a small standard library? There were 962 changes in 42 releases, that’s almost 23 changes per release. A lot of them are small, but still. Maybe Rust has a small, but deep standard library? Due to coherence, I would maybe think this is true. Just how big are standard libraries anyway? I’ve only seen discussion of this concept in terms of design philosophy. I’ve never seen a numerical analysis of such. Is it out there? Do you know of one? I’d love to hear about it!&lt;/p&gt;
&lt;p&gt;I think there’s a number of reasons that the standard library changes dominate the total change rate. Primarily, this section of the blog post &lt;em&gt;tends&lt;/em&gt; to be the most complete, that is, out of the total amount of changes, more standard library changes make it into blog posts than other kinds of changes. Why? Well, it’s really easy to measure: count up stuff stabilized and put it in a big list in the post. It’s also about how these changes are measured; when a method is added to every number type, that’s &lt;code&gt;u8&lt;/code&gt; + &lt;code&gt;u16&lt;/code&gt; + &lt;code&gt;u32&lt;/code&gt; + &lt;code&gt;u64&lt;/code&gt; + &lt;code&gt;u128&lt;/code&gt; = &lt;code&gt;5&lt;/code&gt; changes, even if conceptually it’s one change, in a different sense.&lt;/p&gt;
&lt;p&gt;This leads to another question about those standard library changes: what is up with that weird peak around Rust 1.33? Well, we added the &lt;code&gt;const fn&lt;/code&gt; feature in Rust 1.31. After that landed, we could &lt;code&gt;const&lt;/code&gt;-ify a number of functions in the standard library. The initial huge bulk of changes here landed in 1.33. It had 138 changes, but only 13 were not “this function is now &lt;code&gt;const&lt;/code&gt;.” And the feature continues to drive change outside of 1.33; the initial landing of &lt;code&gt;const fn&lt;/code&gt; in 1.31 was very limited, and as it expands, more functions that already existed can be made &lt;code&gt;const&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;In conclusion, even though I still believe that Rust has slowed down its rate of change a lot, I think that it makes total sense that not everyone agrees with me. By some metrics, I am just flat-out wrong.&lt;/p&gt;</content:encoded></item><item><title>A sad day for Rust</title><link>https://steveklabnik.com/writing/a-sad-day-for-rust/</link><guid isPermaLink="true">https://steveklabnik.com/writing/a-sad-day-for-rust/</guid><description>actix-web is dead. This situation is bad, from all sides. When Rust was a tiny, tiny community, I thought to myself, “wow, I wonder how long this will last? Probably 1.0 will kill it.” Sort of playing off of Eternal September , I assumed that over time, the community would grow,…</description><pubDate>Fri, 17 Jan 2020 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;code&gt;actix-web&lt;/code&gt; is dead.&lt;/p&gt;
&lt;p&gt;This situation is bad, from all sides. When Rust was a tiny, tiny community, I thought to myself, “wow, I wonder how long this will last? Probably 1.0 will kill it.” Sort of playing off of &lt;a href=&quot;https://en.wikipedia.org/wiki/Eternal_September&quot;&gt;Eternal September&lt;/a&gt;, I assumed that over time, the community would grow, and we’d encounter problems.&lt;/p&gt;
&lt;p&gt;Today is the first day where I say to myself, okay, has that happened?&lt;/p&gt;
&lt;p&gt;This story is not super clear-cut. I’m not going to link to a dozen citations, or try to prove that I’m some sort of neutral party here. I’m going to give you account of this story as I remember it and as I felt it. Because this isn’t really about playing judge. This is about thinking about the future.&lt;/p&gt;
&lt;p&gt;It’s been very clear from the beginning that the Rust project saw Rust as more than just the language. The community and the people mattered. From the earliest days, leadership explicitly took the position that it wasn’t just the code, but the people around the project were important. Of course, people are also people, and so this wasn’t perfect; we’ve made several fairly large mis-steps here over the years. But Rust has been an experiment in community building as much as an experiment in language building. Can we reject the idea of a BDFL? Can we include as many people as possible? Can we be welcoming to folks who historically have not had great representation in open source? Can we reject &lt;a href=&quot;https://blog.aurynn.com/2015/12/16-contempt-culture&quot;&gt;contempt culture&lt;/a&gt;? Can we be inclusive of beginners?&lt;/p&gt;
&lt;p&gt;Rust has a necessary feature, &lt;code&gt;unsafe&lt;/code&gt;, that allows you to escape Rust’s guarantees. This is a really important part of Rust, but also a very dangerous one, hence the name. But one of the things that’s important about it is that, since &lt;code&gt;unsafe&lt;/code&gt; means “I have checked this code, and it upholds all of the guarantees the compiler cannot check,” you can build a safe interface with unsafe guts.&lt;/p&gt;
&lt;p&gt;Interacting with anything outside of the language, for example, using the operating system to print to the screen, or write a file, has to be &lt;code&gt;unsafe&lt;/code&gt;, and so without this property, all programs would be &lt;code&gt;unsafe&lt;/code&gt;. This premise is treated skeptically by many, but has generally been demonstrated to have worked out. Several folks are in the process of providing tooling to prove that your &lt;code&gt;unsafe&lt;/code&gt; code is correct, and provided proofs for a bunch of the standard library’s &lt;code&gt;unsafe&lt;/code&gt; code. It not only found a few places where there were bugs, but also a few places where the restrictions were too tight!&lt;/p&gt;
&lt;p&gt;But “generally” is doing a lot of work in that previous sentence. This setup creates a gnawing fear in the back of people’s minds: what if some foundational package uses &lt;code&gt;unsafe&lt;/code&gt;, but uses it incorrectly? What happens when this causes problems for every package that uses that package? This relationship between safe and unsafe is also a bit hard to understand, and so, when bugs are found around unsafe, people &lt;em&gt;outside&lt;/em&gt; of Rust often use it to suggest that all of Rust is a house of cards. While Rust has “made it” in many senses, it has not quite yet in many others, and so I think this produces a fundamental anxiety in the community.&lt;/p&gt;
&lt;p&gt;Speaking of making it, actix-web is a good web framework. It came onto the scene, and people generally liked it. It also performed extremely well. Its score on &lt;a href=&quot;https://www.techempower.com/benchmarks/&quot;&gt;Techempower&lt;/a&gt; in particular was impressive, and got more impressive over time. Its author also works at Microsoft, and suggested that Microsoft is using actix-web in production. This was really exciting to people. This was the second project using Rust at Microsoft, and so this seemed really fantastic.&lt;/p&gt;
&lt;p&gt;But then, the anxiety.&lt;/p&gt;
&lt;p&gt;Before we get into that, though, there’s also the matter of Reddit. The team has basically rejected Reddit for said social reasons. We provide alternate forums for folks, but Reddit is a huge place. The Rust subreddit has ~87,000 subscribers, partially thanks to this. And, for a while, the Rust reddit was a decent place. I still think it’s better than most reddits, but it’s degraded much more quickly than the community at large. “Why Reddit is like this” is a whole other essay; I think it’s built into reddit’s structure itself. But the point is, while Reddit is not official, and so not linked to by any official resources, it’s still a very large group of people, and so to suggest it’s “not the Rust community” in some way is both true and very not true. For the purposes of this story, I think it has to be included in the broader community, and I think that this situation has brought new questions about the relationship of the project and Reddit, though this is already far too long.&lt;/p&gt;
&lt;p&gt;So, someone takes a peek under the covers, and it turns out actix-web is using a &lt;em&gt;lot&lt;/em&gt; of unsafe code. That’s not inherently a problem. The problem is, a lot of that unsafe code is not actually needed. This is where things start to go wrong.&lt;/p&gt;
&lt;p&gt;The author of actix-web basically says “nah it’s fine.” This is basically the perfect storm of unsafe anxiety: a big, important, visible library, a bunch of &lt;code&gt;unsafe&lt;/code&gt;, and an unresponsive author.&lt;/p&gt;
&lt;p&gt;Now, it’s important to mention that people were not just complaining: they were writing code. It is easy to frame this as a case of open source entitlement, and it still very well may be, but this isn’t just empty complaints. Patches were included, they just weren’t welcome. And that’s also not inherently wrong either; a project maintainer shouldn’t be required to accept a patch just because it exists…&lt;/p&gt;
&lt;p&gt;Reddit whips itself into a frenzy. Lots of ugly things are said. More issues are opened, and closed, and locked. Eventually, the author accepts some code that drops the total unsafe count significantly and has more sound usage of what’s left.&lt;/p&gt;
&lt;p&gt;People were not happy about how all this played out, for a variety of reasons and in a variety of ways. I haven’t spoken to actix-web’s author, but I can’t imagine that he was very happy about it either.&lt;/p&gt;
&lt;p&gt;And then it happens all over again. More unsafe, more patches rejected, more Reddit, more bad blood. I thought that at this point, the author said he was quitting, but that may be faulty memory, or maybe he changed his mind. Regardless, how responsive would you be, if you were the maintainer, after the shit-show of last time?&lt;/p&gt;
&lt;p&gt;People were not happy about how all this played out, for a variety of reasons and in a variety of ways.&lt;/p&gt;
&lt;p&gt;All was quiet for a while, and actix-web kept climbing the Techempower benchmarks, reaching the top of most of them by a &lt;em&gt;lot&lt;/em&gt;. It is wicked fast.&lt;/p&gt;
&lt;p&gt;And then, yesterday, a post titled &lt;a href=&quot;https://medium.com/@shnatsel/smoke-testing-rust-http-clients-b8f2ee5db4e6&quot;&gt;Smoke-testing Rust HTTP clients&lt;/a&gt; gets published. It focuses on a, well, smoke test of Rust HTTP clients, but it also comments a lot on the complexity of each project, and the amount of &lt;code&gt;unsafe&lt;/code&gt;. The author found and filed a lot of bugs.&lt;/p&gt;
&lt;p&gt;But:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;A quick glance at the dependencies reveals that it relies on actix-service, which underpins all of Actix and has a bespoke and unsound Cell implementation. For example, this method violates memory safety by handing out multiple mutable references to the same data, which can lead to e.g. a use-after-free vulnerability. I have reported the issue to the maintainers, but they have refused to investigate it.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This causes the now-usual Reddit uproar. It’s extra nasty this time. Some people go far, far, far over the line.&lt;/p&gt;
&lt;p&gt;And now the maintainer has quit.&lt;/p&gt;
&lt;p&gt;This means, on some level, this situation is over: there will not be a fourth huge actix-web drama. But it’s really left a bad taste in my mouth. It’s unfortunate that a well-known project had soundness issues. It’s unfortunate that the maintainer wasn’t receptive to fixing them. At the same time, I’ve been there: being a maintainer is tough. It’s also unfortunate that there’s this &lt;em&gt;style&lt;/em&gt; of response, and kind, and volume. It &lt;em&gt;is&lt;/em&gt; true that the situation was dangerous. But did it have to be handled this way? You have to understand a lot of nuance here to even know the main points of the story. One version of this story that will certainly be told is “The Rust community says they’re nice but they will harass you if you use unsafe wrong.” Is that what we want? I, for one, do not. If you’re a part of Rust, you gotta ask yourself: are you happy with this outcome? How did your actions (or lack thereof) contribute to it? Could you have done something better?&lt;/p&gt;
&lt;p&gt;I’m not sure where we go from here, and I’m not sure what we could have done to prevent this from happening. But I feel like this is a failure, and it’s set Rust back a bit, and I’m just plain sad.&lt;/p&gt;
&lt;p&gt;EPILOGUE&lt;/p&gt;
&lt;p&gt;actix-web has new maintainers, and will now live on: &lt;a href=&quot;https://github.com/actix/actix-web/issues/1289&quot;&gt;https://github.com/actix/actix-web/issues/1289&lt;/a&gt;&lt;/p&gt;</content:encoded></item><item><title>Rust has finally outgrown me</title><link>https://steveklabnik.com/writing/rust-has-finally-outgrown-me/</link><guid isPermaLink="true">https://steveklabnik.com/writing/rust-has-finally-outgrown-me/</guid><description>Today is a very interesting day. It’s giving me a lot of feels. Today is Rust Latam , a Rust conference in Montevideo. And I’m not there. This is significant because, as far as we know, I’m the only person who has been to every Rust conference in existence so far. I went to…</description><pubDate>Fri, 29 Mar 2019 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Today is a very interesting day. It’s giving me a lot of feels. Today is &lt;a href=&quot;https://rustlatam.org/&quot;&gt;Rust Latam&lt;/a&gt;, a Rust conference in Montevideo.&lt;/p&gt;
&lt;p&gt;And I’m not there.&lt;/p&gt;
&lt;p&gt;This is significant because, as far as we know, I’m the only person who has been to every Rust conference in existence so far. I went to RustCamp, all three RustConfs, all five RustFests so far, all three Rust Belt Rusts. One RustRush. Am I forgetting any? Thirteen Rust conferences in the past four years.&lt;/p&gt;
&lt;p&gt;I really wanted to attend Rust Latam. The main organizer, Santiago, has been a friend for a very long time. It’s amazing that we’re getting a new conference in this part of the world. There’s been a lot of energy with Rust there for quite a while. It would have been nice to meet all those people whose tweets I’ve seen.&lt;/p&gt;
&lt;p&gt;But in the end, I’m still between jobs (news on that soon, hopefully!), and spending that money would be irresponsible. I’m just getting settled in Austin, and it’s nice to stay in one place for a little while. I didn’t only attend Rust conferences last year, I attended many more. I missed Thanksgiving with my friends, because I was at a conference. I made five trips in October last year; Eastern Europe, then San Francisco, then Michigan, then New York (for a conf, not to stay at home), then Berlin. I did three more in November. I did about twenty conferences, and a few personal trips, last year. I am very tired.&lt;/p&gt;
&lt;p&gt;Don’t get me wrong, I love travel, and plan to do more of it in the future. But I’ve been taking a bit of a breather; I’ve only done four trips so far this year, twice to Europe, twice in the US. But it’s been nice to take a break. For now.&lt;/p&gt;
&lt;p&gt;More importantly, it’s time to let go of the pressure I felt to keep that streak up. Some of those trips really took a toll on me, mentally and physically. Nobody should ever fly from New York to Belarus for 30 hours, then immediately fly to San Francisco for three days, then back to New York. I’m not old, but I’m not as young as I once was, either.&lt;/p&gt;
&lt;p&gt;It’s also time to acknowledge that I cannot do it all on my own. This conference streak is one thing, but Rust has outgrown me in other ways. I used to be on &lt;code&gt;#rust&lt;/code&gt; every day, answering almost every question. Then it was both &lt;code&gt;#rust-beginners&lt;/code&gt; and &lt;code&gt;#rust&lt;/code&gt;. Not to mention all the other channels. I’m not even on IRC anymore. I was on the core team when the core team approved every RFC; now my team very rarely has RFCs. I used to read every single GitHub email on &lt;code&gt;rust-lang/rust&lt;/code&gt;, and then &lt;code&gt;rust-lang/cargo&lt;/code&gt;, and then all their other libraries. Now I skim &lt;code&gt;rust-lang/rust&lt;/code&gt;, and have unsubscribed from a lot of the other repos. I used to know every single production user of Rust. Those times are long gone; I’m starting to get used to hearing “oh yeah our team has been using Rust in production for a while now, it’s great.” The first time that happened, it felt &lt;em&gt;very&lt;/em&gt; strange. Exciting, but strange.&lt;/p&gt;
&lt;p&gt;Back when I first decided I wanted to devote my time to Rust, I used to submit every single blog post about Rust to Hacker News and Reddit, and then answer any question anyone had about things. I diligently did this for &lt;em&gt;years&lt;/em&gt;. I’m slowly letting go of this one, too. We’ll see.&lt;/p&gt;
&lt;p&gt;All of these things are excellent. This is the future I wanted. This is why I spent so much time over the years doing all of this stuff. I did it, mission accomplished. It feels good. But it also feels a little weird. That Rust is bigger than &lt;em&gt;me&lt;/em&gt; is an amazing, wonderful thing.&lt;/p&gt;
&lt;p&gt;I wonder what the next stage of Rust’s growth will feel like.&lt;/p&gt;</content:encoded></item><item><title>Learning Ada</title><link>https://steveklabnik.com/writing/learning-ada/</link><guid isPermaLink="true">https://steveklabnik.com/writing/learning-ada/</guid><description>I decided to try and learn Ada. I love programming languages. This post documents my attempt, and explains what I learned. This is pretty stream of consciousness and basically is a bunch of random notes, so if you hate that, better close the tab. I typed my thoughts up pretty…</description><pubDate>Tue, 26 Mar 2019 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I decided to try and learn Ada. I love programming languages. This post documents my attempt, and explains what I learned. This is pretty stream of consciousness and basically is a bunch of random notes, so if you hate that, better close the tab. I typed my thoughts up pretty raw, so I may be incorrect in places too. Let me know if you know the answer to something I don’t!&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;The first step, of course, is to google:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://svbtleusercontent.com/72NhELV1orufu8jasf5iiT0xspap_small.png&quot; alt=&quot;https://svbtleusercontent.com/72NhELV1orufu8jasf5iiT0xspap_small.png&quot;&gt;&lt;/p&gt;
&lt;p&gt;Great! I know that Adacore are sort of the stewards of Ada? Vaguely, that might be wrong. Let’s look at all three of those.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Learn.adacore.com is an interactive learning platform designed to teach the Ada and SPARK programming languages.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Ah, that’s awesome! No installation needed.&lt;/p&gt;
&lt;p&gt;The second one looks &lt;strong&gt;extremely&lt;/strong&gt; like spam. It does have a page of learning materials that look legit enough. I wonder if this is a low-effort attempt to make money through ads. Or maybe it’s actually good and real and feels outdated, it does have a high google ranking. Upon doing some more research, it seems like the latter. Oops…&lt;/p&gt;
&lt;p&gt;The third one is a parked domain, it apparently expired. Oops.&lt;/p&gt;
&lt;p&gt;Anyway, I’m going to pursue learn.adacore.com&lt;/p&gt;
&lt;h2 id=&quot;learnadacorecom&quot;&gt;learn.adacore.com&lt;/h2&gt;
&lt;p&gt;Here’s the initial code presented:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;with Ada.Text_IO; use Ada.Text_IO;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;procedure Learn is&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;   subtype Alphabet is Character range &apos;A&apos; .. &apos;Z&apos;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;begin&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;   Put_Line (&quot;Learning Ada from &quot; &amp;#x26; Alphabet&apos;First &amp;#x26; &quot; to &quot; &amp;#x26; Alphabet&apos;Last);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;end Learn;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Okay! This clearly has some style to it. Seems like &lt;code&gt;Pascal_Snake_Case&lt;/code&gt;. I’m not super hyped about this, but it’s fine. Syntax discussions are like the tabloids of programming language discussion. They’re fun, but they don’t really have any educational comment. One thing I will point out: are apostrophes used for method calls? Otherwise, this seems to be fairly Pascal like, which I think makes sense given what I know about Ada.&lt;/p&gt;
&lt;p&gt;I can click run and see it execute right there! Awesome.&lt;/p&gt;
&lt;p&gt;There seems to be three sections here: About, Courses, and Books. About is a single page of information that reinforces what I already know:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The Ada programming language was designed from its inception to be used in applications where safety and security are of the utmost importance.The SPARK programming language is a formally verifiable subset of the Ada language which allows developers to mathematically prove program correctness through static means.Founded in 1994, AdaCore is the leading provider of commercial and open-source software solutions for Ada&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Cool.&lt;/p&gt;
&lt;p&gt;There are two courses, introduction to Ada, and introduction to SPARK. I think SPARK is cool but I’ll learn that after I learn Ada itself. I also do like books, but let’s do that first.&lt;/p&gt;
&lt;p&gt;I’m not going to write everything about the book as I read it, but I will say that I like the basic structure here: first some history, then imperative programming stuff, then talking about types. After that it gets into packages, more type stuff, privacy, generics, exceptions, tasks, interfacing with C, the standard library, and some appendices. This feels pretty logical. Time to do some reading, I’ll jump back here at random points with notes.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The first Ada standard was issued in 1983; it was subsequently revised and enhanced in 1995, 2005 and 2012, with each revision bringing useful new features.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I heard that Ada 2020 is a thing; seems like they’re on a roughly 7-8ish year timeframe generally. Cool.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;In terms of modern languages, the closest in terms of targets and level of abstraction are probably C++ and Rust.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;We got a shout-out! That’s nice.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Readability is more important than conciseness. Syntactically this shows through the fact that keywords are preferred to symbols, that no keyword is an abbreviation, etc.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This is interesting; it seems to suggest that readability and verbosity are synonymous. I often find concise things easier to read, personally. This is, of course, subjective, and I wonder how I’ll feel after I learn more of the language.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Ada is a multi-paradigm language with support for object orientation and some elements of functional programming, but its core is a simple, coherent procedural/imperative language akin to C or Pascal.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This makes a lot of sense, especially given the time it was created.&lt;/p&gt;
&lt;p&gt;I’m finding it a &lt;em&gt;little&lt;/em&gt; hard to understand what &lt;code&gt;main&lt;/code&gt; is. The docs say&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Greet is a procedure, and the main entry point for our first program. Unlike in C or C++, it can be named anything you prefer. The builder will determine the entry point. In our simple example, gprbuild, GNAT’s builder, will use the file you passed as parameter.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;It will use it as … parameter? Like, is the fact that we called the file &lt;code&gt;greet.adb&lt;/code&gt; the reason it calls &lt;code&gt;Greet&lt;/code&gt;? It’s not clear to me at the moment.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Integer’Image is a function that takes an Integer and converts it to a String. It is an example of a language construct known as an attribute, indicated by the “’” syntax, which will be covered in more detail later.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Ah, it’s not a method call, it’s an attribute.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;In Ada, an integer type is not specified in terms of its machine representation, but rather by its range. The compiler will then choose the most appropriate representation.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Very interesting. I wonder how well-defined these mappings are, for example, if you need to call a C function, you’re gonna need to give it the correct sized type… I’m sure I’ll get to that.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Mainly for efficiency reasons, while machine level overflow always results in an exception, type level overflows will only be checked at specific boundaries, like assignment:&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Okay, &lt;em&gt;this&lt;/em&gt; is the good stuff. Ranged integers are something people always say Ada is better at than Rust; I wondered if this was a static or dynamic check. It &lt;em&gt;is&lt;/em&gt; a dynamic check. Cool. I’ve always wanted to know!&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;As mentioned previously, every “built-in” type in Ada is defined with facilities generally available to the user.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Pretty cool!&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;While unconstrained arrays in Ada might seem similar to variable length arrays in C, they are in reality much more powerful, because they’re truly first-class values in the language. You can pass them as parameters to subprograms or return them from functions, and they implicitly contain their bounds as part of their value. This means that it is useless to pass the bounds or length of an array explictly along with the array, because they are accessible via the ’First, ’Last, ’Range and ’Length attributes explained earlier.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Awesome. This is the way to do it, for sure.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Here is how the string type is defined in Ada:type String is array (Positive range &amp;#x3C;&gt;) of Character;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Hmm, what’s a &lt;code&gt;Character&lt;/code&gt; though? Let’s try to mess with the example:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;with Ada.Text_IO; use Ada.Text_IO;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;procedure Greet is&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;   Message : String (1 .. 2) := &quot;😊&quot;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;   --        ^ Pre-defined array type.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;   --          Component type is Character&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;begin&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;   for I in reverse Message&apos;Range loop&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;      --    ^ Iterate in reverse order&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;      Put (Message (I));&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;   end loop;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;   New_Line;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;end Greet;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here’s the output:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Run...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;greet.adb:4:04: warning: &quot;Message&quot; is not modified, could be declared constant&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;greet.adb:4:33: warning: wrong length for array of subtype of &quot;Standard.String&quot; defined at line 4&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;greet.adb:4:33: warning: &quot;Constraint_Error&quot; will be raised at run time&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;raised CONSTRAINT_ERROR : greet.adb:4 length check failed&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Hm, wrong length. What is the right length? This particular emoji is four bytes, so let’s try to set it to 5, since we start at 1. Nope that doesn’t work either. What about 4?&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Run...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;the machine running the examples is not responding, please try again later&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Very suspicious. Anyway, I’m guessing it’s ASCII, maybe it’ll tell me later.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;One last feature of Ada arrays that we’re going to cover is array slices. It is possible to take and use a slice of an array (a contiguous sequence of elements) as a name or a value.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Hell yeah, I love slices.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Ada has multidimensional arrays, which are not covered in this course. Slices will only work on one dimensional arrays.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Ah, bummer. I guess I’ll have to read up on those separately.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Returning variable size objects in languages lacking a garbage collector is a bit complicated implementation-wise, which is why C and C++ don’t allow it, prefering to depend on explicit dynamic allocation / free from the user.The problem is that explicit storage management is unsafe as soon as you want to collect unused memory. Ada’s ability to return variable size objects will remove one use case for dynamic allocation, and hence, remove one potential source of bugs from your programs.Rust follows the C/C++ model, but with safe pointer semantics. However, dynamic allocation is still used. Ada can benefit from an eventual performance edge because it can use any model.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Hmmm, I wonder &lt;em&gt;how&lt;/em&gt; it is doing this. Doesn’t that still dynamically allocate in Ada?&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Ada doesn’t have a tuple construct and does not allow returning multiple values from a subprogram (except by declaring a full-fledged record type). Hence, a way to return multiple values from a subprogram is to use out parameters.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I love tuples, oh well.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;While reading an out variable before writing to it should, ideally, trigger an error, imposing that as a rule would cause either inefficient run-time checks or complex compile-time rules. So from the user’s perspective an out parameter acts like an uninitialized variable when the subprogram is invoked.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Hmmmmmmmmmmmmmmmmmm. This seems &lt;em&gt;extremely&lt;/em&gt; against Ada’s safety focus.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;with Ada.Text_IO; use Ada.Text_IO;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;procedure Outp is&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;   procedure Foo (A : out Integer) is&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;   begin&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;      Put_Line (Integer&apos;Image (A));&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;   end Foo;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;   A : Integer := 12;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;begin&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;   Foo(A);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;end Outp;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;gives&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Run...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;outp.adb:4:19: warning: formal parameter &quot;A&quot; is read but never assigned&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;outp.adb:10:08: warning: &quot;A&quot; modified by call, but value might not be referenced&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;32514&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;2 errors.&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Each time I run it, I get a different number. Seems bad?&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;There are two ways in which Ada helps shield programmers from the dangers of pointers:One approach, which we have already seen, is to provide alternative features so that the programmer does not need to use pointers. Parameter modes, arrays, and varying size types are all constructs that can replace typical pointer usages in C.Second, Ada has made pointers as safe and restricted as possible, but allows “escape hatches” when the programmer explicitly requests them and presumably will be exercising such features with appropriate care.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Seems great! I’m very here for this.&lt;/p&gt;
&lt;p&gt;… but they have &lt;code&gt;null&lt;/code&gt;. Of course they do, given the timeframe Ada was developed. Oh well.&lt;/p&gt;
&lt;p&gt;Okay, so &lt;code&gt;new&lt;/code&gt; is a keyword, and is in the language. But freeing is an unsafe standard library API? I guess this makes sense, similarly to how leaking memory isn’t unsafe in Rust. Feels weird, though.&lt;/p&gt;
&lt;p&gt;I guess, reading more, the idea is that you should basically never need to do this yourself. I think this is where I was getting caught up earlier with the “return an unknown type” bit too. It &lt;em&gt;is&lt;/em&gt; allocating, but since you’re not typing &lt;code&gt;new&lt;/code&gt;, you’re not responsible, and so that’s safer. That makes sense. I hope my understanding is correct here, but I’m not totally sure.&lt;/p&gt;
&lt;p&gt;This does mean that it feels like allocations exist, but are hidden from you, the user. That’s okay, but it’s very different than Rust.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Ada’s variant records are very similar to Sum types in functional languages such as OCaml or Haskell. A major difference is that the discriminant is a separate field in Ada, whereas the ‘tag’ of a Sum type is kind of built in, and only accessible with pattern matching.There are other differences (you can have several discriminants in a variant record in Ada). Nevertheless, they allow the same kind of type modeling as sum types in functional languages.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This is pretty cool.&lt;/p&gt;
&lt;p&gt;The “Character Types” section still does not explain to me what valid characters are. Oh well. Googling it gives me &lt;a href=&quot;https://www.adaic.org/resources/add_content/standards/05rm/html/RM-3-5-2.html&quot;&gt;this&lt;/a&gt; which says&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The predefined type Character is a character type whose values correspond to the 256 code positions of Row 00 (also known as Latin-1) of the ISO/IEC 10646:2003 Basic Multilingual Plane (BMP). Each of the graphic characters of Row 00 of the BMP has a corresponding character_literal in Character. Each of the nongraphic positions of Row 00 (0000-001F and 007F-009F) has a corresponding language-defined name, which is not usable as an enumeration literal, but which is usable with the attributes Image, Wide_Image, Wide_Wide_Image, Value, Wide_Value, and Wide_Wide_Value; these names are given in the definition of type Character in A.1, “The Package Standard”, but are set in italics.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Ah. Yeah so that’s why the emoji didn’t work. Did that crash the compiler earlier, is that what was happening?&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Generic subprograms or packages can’t be used directly. Instead, they need to be instantiated, which we do using the new keyword, as shown in the following example:&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Wait, is this the same &lt;code&gt;new&lt;/code&gt; keyword as before? Do generics require heap allocation? That is a reasonable design, I’m just a bit surprised.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Ada exceptions are not types, but instead objects, which may be peculiar to you if you’re used to the way Java or Python support exceptions.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I found this sentence confusing; aren’t the objects in Java or Python as well? When I was reading this sentence, halfway through, I thought to myself “oh, like the stuff I know, cool” and then the second half was “this is unlike the stuff you know”. Hrm.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;A task can be thought as an application that runs concurrently with the main application. In other programming languages, a task can be called a thread, and tasking can be called multithreading.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Cool, this is a big topic I’ve been wondering about.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;As we’ve just seen, as soon as the main task starts, its subtasks also start automatically. The main task continues its processing until it has nothing more to do. At that point, however, it will not terminate. Instead, the task waits until its subtasks have finished before it allows itself to terminate.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Ah interesting, this is different than Rust. Well, Rust’s standard library, anyway.&lt;/p&gt;
&lt;p&gt;I wish it explained if tasks &lt;em&gt;are&lt;/em&gt; system threads, or if they’re green threads.&lt;/p&gt;
&lt;p&gt;I did some googling, and apparently this is implementation-defined. GNAT uses system threads for some of the same reason that Rust decided to expose system threads. Seems good.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The pragma Assertion_Policy statement is used to force the compiler to generate code to check the precondition.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Design by contract works at runtime. This is something I always thought was true, but was never actually sure of. Cool.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;To interface with C’s built-in types, we use the Interfaces.C package, which contains most of the type definitions we need. For example:&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Ah ha, this answers my question from earlier. Cool.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Object-oriented programming (OOP) is a large and ill-defined concept in programming languages and one that tends to encompass many different meanings because different languages often implement their own vision of it, with similarities and differences from the implementations in other languages.However, one model mostly “won” the battle of what object-oriented means, if only by sheer popularity. It’s the model used in the Java programming language, which is very similar to the one used by C++. Here are some defining characteristics:&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Spicy! But not incorrect.&lt;/p&gt;
&lt;p&gt;Dot notation exists! But only if you’re actually using objects, er, “tagged types”.&lt;/p&gt;</content:encoded></item><item><title>Thoughts on Rust in 2019</title><link>https://steveklabnik.com/writing/thoughts-on-rust-in-2019/</link><guid isPermaLink="true">https://steveklabnik.com/writing/thoughts-on-rust-in-2019/</guid><description>Each year, we ask the community to write blog posts about what they want to see on Rust’s roadmap for the next year . This is my post for Rust in 2019. Rust 2021: Maturity This year is also a bit special; in 2018, we introduced “editions” to Rust, on a roughly three-year…</description><pubDate>Thu, 27 Dec 2018 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Each year, &lt;a href=&quot;https://blog.rust-lang.org/2018/12/06/call-for-rust-2019-roadmap-blogposts.html&quot;&gt;we ask the community to write blog posts about what they want to see on Rust’s roadmap for the next year&lt;/a&gt;. This is my post for Rust in 2019.&lt;/p&gt;
&lt;h2 id=&quot;rust-2021-maturity&quot;&gt;Rust 2021: Maturity&lt;/h2&gt;
&lt;p&gt;This year is also a bit special; in 2018, we introduced “editions” to Rust, on a roughly three-year schedule. So now is not just a good time to think about 2019, but about 2020 and 2021 as well. Rust 2015 was about “stability”. Rust 2018 was about “productivity.” I’d like Rust 2021 to be about “maturity.”&lt;/p&gt;
&lt;p&gt;In order to get there, here’s what we need in 2019.&lt;/p&gt;
&lt;h2 id=&quot;no-new-features&quot;&gt;No &lt;em&gt;new&lt;/em&gt; features&lt;/h2&gt;
&lt;p&gt;Emphasis on “new” here. What do I mean by this? Well, there are a few features that are in the pipeline that I &lt;em&gt;do&lt;/em&gt; think should land:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;async&lt;/code&gt;/&lt;code&gt;await&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;GATs&lt;/li&gt;
&lt;li&gt;&lt;code&gt;const&lt;/code&gt; generics&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;And &lt;em&gt;possibly&lt;/em&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Specialization&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;None of these features are new; we’ve got their basic designs in place. These features are also &lt;em&gt;significant&lt;/em&gt; and &lt;em&gt;foundational&lt;/em&gt;; we need &lt;code&gt;async&lt;/code&gt;/&lt;code&gt;await&lt;/code&gt; (and to some degree, GATs) for a great networking story, we need &lt;code&gt;const&lt;/code&gt; generics for an excellent numerics story.&lt;/p&gt;
&lt;p&gt;But after that? I’d like to see a moratorium on major features until 2020, and I’d prefer if we limited 2020 to two or three, if any.&lt;/p&gt;
&lt;p&gt;We’ve hit a sweet spot. We’ve always said that Rust 1.0 was about stability, not completeness. I think we’re fast approaching completeness.&lt;/p&gt;
&lt;p&gt;That said, I don’t think that the language team should be disbanded or anything; I think their work should transition to working on &lt;em&gt;specifying&lt;/em&gt; what we already have, in more detail. I’m not sure if we can have the reference be done in 2019 (more on that later), but I’d like it to be much further along. That can only happen with the help of the language team, and they can only do that work if they have the time.&lt;/p&gt;
&lt;h2 id=&quot;refine-the-rfc-process&quot;&gt;Refine the RFC process&lt;/h2&gt;
&lt;p&gt;The RFC process needs to be significantly re-vamped. Niko wrote a great post on this &lt;a href=&quot;http://smallcultfollowing.com/babysteps/blog/2018/06/20/proposal-for-a-staged-rfc-process/&quot;&gt;back in June&lt;/a&gt;, and I think it’s really, really, really important. I’d like to work on an RFC to propose this, so if you’re interested, we should talk.&lt;/p&gt;
&lt;p&gt;Niko already makes the case and lays out some foundations, so I won’t say more there.&lt;/p&gt;
&lt;h2 id=&quot;pay-down-organizational-debt&quot;&gt;Pay down organizational debt&lt;/h2&gt;
&lt;p&gt;Consider this section an endorsement of &lt;a href=&quot;https://boats.gitlab.io/blog/post/rust-2019/&quot;&gt;everything boats said&lt;/a&gt;. I cannot say it better, so I will just leave it at that.&lt;/p&gt;
&lt;h2 id=&quot;figure-out-documentation-sustainability&quot;&gt;Figure out documentation sustainability&lt;/h2&gt;
&lt;p&gt;This year was a bad year for the docs team. The book got shipped, and that was great. We had some people pitch in on the reference, and their work was amazing. Some of the other documentation writers moved on to work on &lt;code&gt;rustdoc&lt;/code&gt;, which was important.&lt;/p&gt;
&lt;p&gt;But a lot of the goals we wanted to do about writing more docs themselves never came to fruition. For example, contributing to major ecosystem crates? Never happened. The cookbook isn’t done. Rust by Example still languishes. The standard library could use a lot of love.&lt;/p&gt;
&lt;p&gt;We just don’t have the people to make this happen. We’ve tried, but nothing has worked. It’s possible that this is simply unfixable, after all, most programmers don’t like writing docs. But I also don’t want to give up on it either. I’m not sure what to do here, but I do know that it is a major problem.&lt;/p&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;There’s a lot of work to do, and I’m very excited to do it. I think Rust is in an &lt;em&gt;excellent&lt;/em&gt; place, and with some work, we can make Rust even more amazing in a year’s time.&lt;/p&gt;</content:encoded></item><item><title>Six years with Rust</title><link>https://steveklabnik.com/writing/six-years-with-rust/</link><guid isPermaLink="true">https://steveklabnik.com/writing/six-years-with-rust/</guid><description>Today is six years since I first heard of Rust. I wrote a post last year about it. This past year was… intense. Rust 1.31 was basically Rust 2.0, at least in the marketing sense. I burned myself out getting the first edition of the book together for Rust 1.0, and I burned myself…</description><pubDate>Fri, 21 Dec 2018 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Today is six years since I first heard of Rust. &lt;a href=&quot;/writing/five-years-with-rust/&quot;&gt;I wrote a post last year&lt;/a&gt; about it.&lt;/p&gt;
&lt;p&gt;This past year was… intense. Rust 1.31 was basically Rust 2.0, at least in the marketing sense. I burned myself out getting the first edition of the book together for Rust 1.0, and I burned myself out getting the edition shipped.&lt;/p&gt;
&lt;p&gt;Let’s talk about the bad and the good. Bad first so we end on the high notes.&lt;/p&gt;
&lt;h2 id=&quot;the-bad&quot;&gt;The Bad&lt;/h2&gt;
&lt;p&gt;This year, the docs team sort of… died. Not entirely, but it’s… different now. We used to have a single docs team that handled most everything docs related. The core of that for the past few years has been me and two others. But early this year, we split the sub-teams into fewer individual teams. The old docs team became the docs team, the &lt;code&gt;rustdoc&lt;/code&gt; team, the Rust By Example team, and the Reference team. But we didn’t really attract many more people. We did to some degree! The reference team did a &lt;em&gt;ton&lt;/em&gt; of amazing reference work. RBE has still struggled. I stayed on the docs team, and the other two went to the &lt;code&gt;rustdoc&lt;/code&gt; team. That’s fine, and they’re doing great work, but it’s a little lonely over here now. I can’t decide how much of this issue is “it’s really hard to get people to volunteer to write docs” and how much of this issue is “I mis-managed the team(s) somehow and so it’s my fault.”&lt;/p&gt;
&lt;p&gt;Shipping the edition was a monumental effort that caused a lot of debt. We did a good job at avoiding &lt;em&gt;technical&lt;/em&gt; debt, but we have a lot of social and organizational debt. &lt;a href=&quot;https://boats.gitlab.io/blog/post/rust-2019/&quot;&gt;See here for more&lt;/a&gt;. This has to be paid off now…&lt;/p&gt;
&lt;p&gt;There’s a few other things, but let’s stop there.&lt;/p&gt;
&lt;h2 id=&quot;the-good&quot;&gt;The Good&lt;/h2&gt;
&lt;p&gt;We shipped the edition! In fact, we invented the entire edition system and then shipped our first one. Whew! This is a &lt;em&gt;massive&lt;/em&gt;, &lt;em&gt;massive&lt;/em&gt; accomplishment. Figuring out how we are going to manage Rust’s evolution decades into the future is, frankly a pretty amazing thing to do in twelve months. Non-lexical lifetimes finally landed. Procedural macros finally landed. Rocket is almost on stable. &lt;code&gt;async&lt;/code&gt;/&lt;code&gt;await&lt;/code&gt; is almost here, and &lt;code&gt;Futures&lt;/code&gt; are finally where they should be after two years of work. We did &lt;em&gt;so much&lt;/em&gt; good work this year, technically speaking. I’m very proud.&lt;/p&gt;
&lt;p&gt;We shipped the new website! This was met with some controversy, but every single website redesign in the history of redesigns has been met with controversy. Doing so in less than a year is also an incredible accomplishment. It almost always takes way longer. We now have the foundations for Rust web properties going forward. This will also pay off a ton later.&lt;/p&gt;
&lt;p&gt;We made wasm a thing! I really really wanted wasm to be a thing. A lot of people put in a ton of work, and Rust’s wasm support is bar-none best-in-class. I think this is still a &lt;em&gt;massive&lt;/em&gt; growth area for Rust, and we’re almost a full year ahead of almost everyone else on this.&lt;/p&gt;
&lt;p&gt;Speaking of growth, Rust’s commercial uptake skyrocketed this year. I met someone for the first time who told me “I learned Rust because it’s what we use at work.” A ton of companies, big and small, have started deploying Rust in critical places, and report good things. Out of the FAANGs, we’ve got Facebook, Amazon, and Google. Three out of five ain’t bad. This tweet is wild:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Introducing #HyperledgerSawtooth version 1.1, an enterprise-grade #blockchain platform with support for #WebAssembly smart contracts and great performance with @rustlang. Empower your business. &lt;a href=&quot;https://t.co/wl9OYVnUsR&quot;&gt;https://t.co/wl9OYVnUsR&lt;/a&gt; #HyperledgerForum pic.twitter.com/5vurpbVMP1
— Intel Security (@IntelSecurity) December 12, 2018&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;So is this one:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Discover Rust, a C-like language that supports imperative, functional, and object-oriented programming. &lt;a href=&quot;https://t.co/fCgY4x6zqc&quot;&gt;https://t.co/fCgY4x6zqc&lt;/a&gt;
— IBM Developer (@IBMDeveloper) June 10, 2018&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;There’s still lots more to do, but things are headed in the right direction.&lt;/p&gt;
&lt;p&gt;Speaking of heading in the right direction, tomorrow will be the compliment to this post; my entry for &lt;code&gt;#rust2019&lt;/code&gt;. Catch you then!&lt;/p&gt;</content:encoded></item><item><title>You can&apos;t &quot;turn off the borrow checker&quot; in Rust</title><link>https://steveklabnik.com/writing/you-can-t-turn-off-the-borrow-checker-in-rust/</link><guid isPermaLink="true">https://steveklabnik.com/writing/you-can-t-turn-off-the-borrow-checker-in-rust/</guid><description>Every once in a while, someone will talk about unsafe in Rust, and how it “turns off the borrow checker.” I think this framing leads to misconceptions about unsafe and how it interacts with safe code. Here’s some code that causes a borrow checker error: fn main() { let mut x = 5;…</description><pubDate>Fri, 14 Sep 2018 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Every once in a while, someone will talk about &lt;code&gt;unsafe&lt;/code&gt; in Rust, and how it “turns off the borrow checker.” I think this framing leads to misconceptions about &lt;code&gt;unsafe&lt;/code&gt; and how it interacts with safe code.&lt;/p&gt;
&lt;p&gt;Here’s some code that causes a borrow checker error:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;fn main() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    let mut x = 5;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    let y = &amp;#x26;x;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    let z = &amp;#x26;mut x;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    println!(&quot;{}&quot;, y);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And the error:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;error[E0502]: cannot borrow `x` as mutable because it is also borrowed as immutable&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt; --&gt; src/main.rs:5:18&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  |&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;4 |     let y = &amp;#x26;x;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  |              - immutable borrow occurs here&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;5 |     let z = &amp;#x26;mut x;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  |                  ^ mutable borrow occurs here&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;6 | }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  | - immutable borrow ends here&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Rust won’t let us have a &lt;code&gt;&amp;#x26;T&lt;/code&gt; and a &lt;code&gt;&amp;#x26;mut T&lt;/code&gt; to the same &lt;code&gt;T&lt;/code&gt; at the same time.&lt;/p&gt;
&lt;p&gt;If &lt;code&gt;unsafe&lt;/code&gt; “turned off the borrow checker, we’d expect this code to work:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;fn main() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    let mut x = 5;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    unsafe {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        let y = &amp;#x26;x;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        let z = &amp;#x26;mut x;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        println!(&quot;{}&quot;, y);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;However, we get the same error, plus a new warning:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;error[E0502]: cannot borrow `x` as mutable because it is also borrowed as immutable&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt; --&gt; src/main.rs:6:22&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  |&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;5 |         let y = &amp;#x26;x;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  |                  - immutable borrow occurs here&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;6 |         let z = &amp;#x26;mut x;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  |                      ^ mutable borrow occurs here&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;7 |     }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  |     - immutable borrow ends here&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;warning: unnecessary `unsafe` block&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt; --&gt; src/main.rs:4:5&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  |&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;4 |     unsafe {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  |     ^^^^^^ unnecessary `unsafe` block&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  |&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  = note: #[warn(unused_unsafe)] on by default&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So what does &lt;code&gt;unsafe&lt;/code&gt; actually do? Unsafe Rust is a &lt;em&gt;superset&lt;/em&gt; of Safe Rust. &lt;code&gt;Unsafe&lt;/code&gt; never changes the semantics of Rust code. It instead adds new features that you can only use inside an &lt;code&gt;unsafe&lt;/code&gt; block.&lt;/p&gt;
&lt;p&gt;One of those features is the ability to de-reference a “raw pointer”. This code &lt;em&gt;does&lt;/em&gt; compile:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;fn main() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    let mut x = 5;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    let y = &amp;#x26;x as *const i32;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    let z = &amp;#x26;mut x as *mut i32;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    unsafe {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        println!(&quot;y: {} z: {}&quot;, *y, *z);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;y&lt;/code&gt; and &lt;code&gt;z&lt;/code&gt; here have the types &lt;code&gt;*const i32&lt;/code&gt; and &lt;code&gt;*mut i32&lt;/code&gt;, both kinds of raw pointers. In order to print &lt;code&gt;y&lt;/code&gt; and &lt;code&gt;z&lt;/code&gt;, we must de-reference them, which means that we need an unsafe block.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Incidentally, this code is safe. Raw pointers are allowed to alias. And we have no &amp;#x26;T or &amp;#x26;mut Ts here. So we’re good.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Why does this matter? Well, a lot of people think that as soon as you drop into &lt;code&gt;unsafe&lt;/code&gt;, you’re missing the point of Rust, and that you lose all of its guarantees. It’s true that you have to do a lot more work when writing unsafe, since you don’t have the compiler helping you in certain situations, but that’s only for the unsafe constructs.&lt;/p&gt;
&lt;p&gt;For example, let’s look at Rust’s standard library, and the &lt;a href=&quot;https://doc.rust-lang.org/stable/std/collections/linked_list/struct.LinkedList.html&quot;&gt;LinkedList&lt;t&gt;&lt;/t&gt;&lt;/a&gt; that it contains. It looks like this:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;pub struct LinkedList&amp;#x3C;T&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    head: Option&amp;#x3C;NonNull&amp;#x3C;Node&amp;#x3C;T&gt;&gt;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    tail: Option&amp;#x3C;NonNull&amp;#x3C;Node&amp;#x3C;T&gt;&gt;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    len: usize,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    marker: PhantomData&amp;#x3C;Box&amp;#x3C;Node&amp;#x3C;T&gt;&gt;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I’m not gonna go into &lt;em&gt;too&lt;/em&gt; much detail here, but it has a head pointer, a tail pointer, a length. &lt;a href=&quot;https://doc.rust-lang.org/stable/std/ptr/struct.NonNull.html&quot;&gt;NonNull&lt;t&gt;&lt;/t&gt;&lt;/a&gt; is like &lt;code&gt;*mut T&lt;/code&gt;, but asserts that it will never be null. This means that we can combine it with &lt;code&gt;Option&amp;#x3C;T&gt;&lt;/code&gt;, and the option will use the &lt;code&gt;null&lt;/code&gt; case for &lt;code&gt;None&lt;/code&gt;:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;fn main() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    println!(&quot;{}&quot;, std::mem::size_of::&amp;#x3C;*mut i32&gt;());&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    println!(&quot;{}&quot;, std::mem::size_of::&amp;#x3C;Option&amp;#x3C;std::ptr::NonNull&amp;#x3C;i32&gt;&gt;&gt;());&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;prints this on my system:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;8&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;8&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This optimization is guaranteed due to guarantees on both &lt;code&gt;Option&amp;#x3C;T&gt;&lt;/code&gt; and &lt;code&gt;NonNull&amp;#x3C;T&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;So now, we have a sort of hybrid construct: &lt;code&gt;Option&amp;#x3C;T&gt;&lt;/code&gt; is safe, and so we can do some operations entirely in safe code. Rust is now forcing us to handle the null checks, even though we have zero runtime overhead in representation.&lt;/p&gt;
&lt;p&gt;I think a good example of how this plays out in practice is in the implementation of &lt;a href=&quot;https://doc.rust-lang.org/stable/std/collections/linked_list/struct.LinkedList.html#method.append&quot;&gt;append&lt;/a&gt;, which takes two &lt;code&gt;LinkedList&amp;#x3C;T&gt;&lt;/code&gt;s and appends the contents of one to the end of the other:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    pub fn append(&amp;#x26;mut self, other: &amp;#x26;mut Self) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        match self.tail {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            None =&gt; mem::swap(self, other),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            Some(mut tail) =&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                if let Some(mut other_head) = other.head.take() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                    unsafe {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                        tail.as_mut().next = Some(other_head);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                        other_head.as_mut().prev = Some(tail);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                    self.tail = other.tail.take();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                    self.len += mem::replace(&amp;#x26;mut other.len, 0);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here’s some comments to help understand what’s going on:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    pub fn append(&amp;#x26;mut self, other: &amp;#x26;mut Self) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        // do we have a tail?&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        match self.tail {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            // If we don&apos;t, then we have no elements, and so appending a&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;           // list to this one means that that list is now this list.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            None =&gt; mem::swap(self, other),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            // If we do have a tail...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            Some(mut tail) =&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                // the first thing we do is, check if the other list has&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                //  a head. if it does...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                if let Some(mut other_head) = other.head.take() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                    // we set our tail to point at their head, and we &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                    // set their head to point at our tail.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                    unsafe {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                        tail.as_mut().next = Some(other_head);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                        other_head.as_mut().prev = Some(tail);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                    // We set our tail to their tail&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                    self.tail = other.tail.take();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                    // finally, we add their length to our length, and &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                    // replace theirs with zero, because we took all&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                    // their nodes!&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                    self.len += mem::replace(&amp;#x26;mut other.len, 0);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                } // there&apos;s no else case for that if let; if they don&apos;t&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                  //  have a head, that list is empty and so there&apos;s&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                  //  nothing to do.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We only need &lt;code&gt;unsafe&lt;/code&gt; when mutating the &lt;code&gt;next&lt;/code&gt; of the &lt;code&gt;tail&lt;/code&gt; of the first list, and the &lt;code&gt;prev&lt;/code&gt; of the &lt;code&gt;head&lt;/code&gt; of the second list. And that’s even only in the case where the &lt;code&gt;tail&lt;/code&gt; exists in the first place. We can do things like “set our tail to their tail” in safe code, because we’re never de-referencing pointers. Safe Rust is helping us manage many, but not all, of our guarantees. We &lt;em&gt;could&lt;/em&gt; move the &lt;code&gt;unsafe&lt;/code&gt; block to encompass the entire body of this function, and Rust would still make us check those &lt;code&gt;Option&amp;#x3C;T&gt;&lt;/code&gt;s. It would still check that &lt;code&gt;self&lt;/code&gt; and &lt;code&gt;other&lt;/code&gt; are not aliased by &lt;code&gt;&amp;#x26;T&lt;/code&gt; or &lt;code&gt;&amp;#x26;mut T&lt;/code&gt;s in the body of the function.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;unsafe&lt;/code&gt; is a powerful tool, and should be used with care. But that doesn’t mean that you throw out many of the things that make Rust what it is.&lt;/p&gt;</content:encoded></item><item><title>Is WebAssembly the return of Java Applets &amp; Flash?</title><link>https://steveklabnik.com/writing/is-webassembly-the-return-of-java-applets-flash/</link><guid isPermaLink="true">https://steveklabnik.com/writing/is-webassembly-the-return-of-java-applets-flash/</guid><description>In my last post on WebAssembly , I made the following claim: Some have compared WebAssembly to Java applets; in some ways, they’re very right, but in some ways, they’re very wrong. Eventually I’ll write a post about the wrong, but for now, the right: in some sense, WebAssembly is…</description><pubDate>Wed, 25 Jul 2018 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;In my &lt;a href=&quot;/writing/webassembly-is-more-than-just-the-web/&quot;&gt;last post on WebAssembly&lt;/a&gt;, I made the following claim:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Some have compared WebAssembly to Java applets; in some ways, they’re very right, but in some ways, they’re very wrong. Eventually I’ll write a post about the wrong, but for now, the right: in some sense, WebAssembly is a different way of accomplishing what the JVM set out to do: it’s a common virtual machine that can be used to build very cross-platform software.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;A lot of people expressed interest in me elaborating, so let’s get to it! For this post, I’m going to make three comparisons: to Flash, to Java Applets, and &lt;em&gt;occasionally&lt;/em&gt; to PNaCL. Secondly, this post is going to focus on the &lt;em&gt;web&lt;/em&gt; use-case for WebAssembly, even though the previous post was about non-web uses. We’ll make &lt;em&gt;that&lt;/em&gt; comparison in the next post. Finally, this post is kind of like eating tapas, there’s a bunch of little sections. I feel like it’s a bit short, but at the same time, I’m trying to get back into the habit of blogging, and if I try to keep expanding it, it’ll take forever, so it is what it is.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;For what it’s worth, I think this comparison is very &lt;em&gt;natural&lt;/em&gt;; that is, when you hear this pitch for WebAssembly:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;WebAssembly (abbreviated Wasm) is a binary instruction format for a stack-based virtual machine. Wasm is designed as a portable target for compilation of high-level languages like C/C++/Rust, enabling deployment on the web for client and server applications.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;It sounds quite a bit like previous technologies. Asking how they relate, or assuming that they’re a slightly different take on the problem makes a lot of sense. But WebAssembly is significantly different, for a few reasons.&lt;/p&gt;
&lt;h2 id=&quot;wasm-won&quot;&gt;Wasm won&lt;/h2&gt;
&lt;p&gt;The first reason that WebAssembly is different is that it’s succeeded, and those technologies did not. When I say this, I mean it in a very specific way; if you look at the number of Flash applications out there, and compare it to the number of WebAssembly apps out there, Wasm loses, for sure. Those of us that are excited about WebAssembly still have a lot of work to do before it’s widely used.&lt;/p&gt;
&lt;p&gt;When I say “WebAssembly won”, I mean that it’s become a part of the Web Platform. Flash, Java Applets, and PNaCL used the browser’s plugin functionality to work. They were, in a sense, &lt;em&gt;outside&lt;/em&gt; of the web ecosystem. They were never standardized, and that matters a lot.&lt;/p&gt;
&lt;p&gt;In some sense, this is the final point, really. But just saying that it’s true doesn’t explain &lt;em&gt;why&lt;/em&gt;. The rest of this post digs into &lt;em&gt;why&lt;/em&gt; this occurred, and those points sort of sum up to this one: other technologies didn’t make it, but WebAssembly did. There’s a &lt;em&gt;lot&lt;/em&gt; of overlap here, but I’m trying to reasonably separate it out into individual points.&lt;/p&gt;
&lt;h2 id=&quot;other-technologies-didnt-fit-nicely-into-the-platform&quot;&gt;Other technologies didn’t fit nicely into the platform&lt;/h2&gt;
&lt;p&gt;Remember this?&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://svbtleusercontent.com/gY9tj6D62jnC9Fc6RncFhD0xspap_small.gif&quot; alt=&quot;https://svbtleusercontent.com/gY9tj6D62jnC9Fc6RncFhD0xspap_small.gif&quot;&gt;&lt;/p&gt;
&lt;p&gt;Or this?&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://svbtleusercontent.com/qaipxL2e5a4gLH5cAhRHDn0xspap_small.jpg&quot; alt=&quot;https://svbtleusercontent.com/qaipxL2e5a4gLH5cAhRHDn0xspap_small.jpg&quot;&gt;&lt;/p&gt;
&lt;p&gt;What about this?&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://svbtleusercontent.com/9mGgBDzvwYYLGHFg4Pafzt0xspap_small.png&quot; alt=&quot;https://svbtleusercontent.com/9mGgBDzvwYYLGHFg4Pafzt0xspap_small.png&quot;&gt;&lt;/p&gt;
&lt;p&gt;If you built an applet in one of these technologies, you didn’t really build a &lt;em&gt;web application&lt;/em&gt;. You had a web page with a chunk cut out of it, and your applet worked within that frame. You lost all of the benefits of other web technologies; you lost HTML, you lost CSS, you lost the accessibility built into the web. These platforms never gained the ability to interact with the rest of the platform provided by your browser. Well, &lt;a href=&quot;https://docs.oracle.com/javase/tutorial/deployment/applet/manipulatingDOMFromApplet.html&quot;&gt;technically they might have&lt;/a&gt;, but that’s not how these technologies were used in practice.&lt;/p&gt;
&lt;p&gt;How could the web sustain an ecosystem that doesn’t integrate with it? It was never going to happen. And users ended up solidly rejecting it. Outside of games, users &lt;em&gt;hated&lt;/em&gt; Flash. Java Applets were heavy and slow. Enshrining these technologies into the web platform wasn’t going to work.&lt;/p&gt;
&lt;p&gt;WebAssembly, on the other hand, is much closer to JavaScript. It doesn’t inherently require taking over a part of your screen. It doesn’t expect to be its own little closed off world. Via JavaScript today, and &lt;a href=&quot;https://github.com/WebAssembly/host-bindings/blob/master/proposals/host-bindings/Overview.md&quot;&gt;on its own in the future&lt;/a&gt;, it’s able to interact with the surrounding environment. It just… fits.&lt;/p&gt;
&lt;h2 id=&quot;other-technologies-were-owned-by-companies&quot;&gt;Other technologies were owned by companies&lt;/h2&gt;
&lt;p&gt;Java was owned by Sun Microsystems, Flash was owned by Adobe. But why does this matter?&lt;/p&gt;
&lt;p&gt;Corporate influence on the web is a complicated topic. But &lt;em&gt;in general&lt;/em&gt;, the web runs on a psuedo-consensus model. Java and Flash, on the other hand, were controlled by their respective companies. These companies have significant motive to make profit, not to make the web better. And that’s partially what led to the above situation; these companies didn’t care that they didn’t integrate properly with the rest of the platform. Why would they? It’d be much better for business if you got locked into their platform, and abandoned the rest of the web entirely. The incentives are fundamentally misaligned.&lt;/p&gt;
&lt;p&gt;WebAssembly is a joint venture between Mozilla, Google, Apple, Microsoft, and others. It’s not trying to push anyone’s particular platform, but instead represents the shared interests of a wide number of stakeholders, both corporate and individual.&lt;/p&gt;
&lt;h2 id=&quot;webassembly-followed-the-web-process&quot;&gt;WebAssembly followed the web process&lt;/h2&gt;
&lt;p&gt;This &lt;em&gt;also&lt;/em&gt; meant that these technologies never really followed the process that we use to standardize the web. That being said, the web standards process is healthier than its ever been, and at the time these technologies were big, things worked a bit differently. Regardless, WebAssembly followed the way that we do things on the web.&lt;/p&gt;
&lt;p&gt;First, &lt;code&gt;asm.js&lt;/code&gt; was created, proving that we could do more impressive things with the web. Its performance was good enough to demonstrate what could be done, though it wasn’t fantastic. The secret sauce of &lt;code&gt;asm.js&lt;/code&gt; was that it was just JavaScript; it was fully backwards compatible with the existing ecosystem. “Don’t break the web” is a very, very important rule for browser vendors.&lt;/p&gt;
&lt;p&gt;WebAssembly was sort of &lt;code&gt;asm.js&lt;/code&gt; done better. After building some degree of consensus around &lt;code&gt;asm.js&lt;/code&gt;, a variety of people came together to make WebAssembly a reality. Given that it wasn’t just JavaScript, it had to go through the usual process for browsers to implement it, and it did so. Now a W3C spec, it went &lt;em&gt;with&lt;/em&gt; the grain of web standards, not against them.&lt;/p&gt;
&lt;h3 id=&quot;corollary-other-technologies-were-too-big-and-unstable&quot;&gt;Corollary: other technologies were too big and unstable&lt;/h3&gt;
&lt;p&gt;There’s another reason Wasm succeeded: it’s tiny. Wasm takes the approach of other web technologies: start small, and build on those foundations. Stay backwards compatible. These technologies also didn’t follow that particular social convention. For Flash and Java Applets, you’d be downloading the particular runtime you needed, and so there was no need for compatibility. PNaCl built on top of LLVM IR, which is completely unstable. They were going to make it a stable subset, but then when LLVM introduces changes, it would have ended up diverging, which isn’t a great situation to be in.&lt;/p&gt;
&lt;p&gt;These technologies were also far too large to ever make it through the stabilization process. Can you imagine the big four browser vendors specifying the JVM in full and then agreeing to those semantics for all time? For all of ActionScript, itself a similar-to-but-not-quite version of ECMAScript? For all of LLVM-IR?&lt;/p&gt;
&lt;p&gt;Large technologies introduce an unacceptable amount of risk in this situation. It’s an all-or-nothing kind of deal, and the safe bet is to go with “nothing.” WebAssembly, on the other hand, does almost nothing. It’s pretty much math and calling into JavaScript. This means it’s &lt;em&gt;much&lt;/em&gt; easier to develop consensus around.&lt;/p&gt;
&lt;h3 id=&quot;collary-other-technologies-required-an-entire-separate-virtual-machine&quot;&gt;Collary: other technologies required an entire separate virtual machine&lt;/h3&gt;
&lt;p&gt;I haven’t mentioned Dart in this post, but it sort of fits here too. One big issue with “let’s just put the JVM in every browser” is that browsers &lt;em&gt;already&lt;/em&gt; contain a language runtime: JavaScript’s. It’s hard enough to maintain one runtime, let alone two. And then how do you integrate them?&lt;/p&gt;
&lt;p&gt;WebAssembly, on the other hand, was designed to be a small extension to existing JavaScript virtual machines. While you &lt;em&gt;can&lt;/em&gt; implement your own WebAssembly VM, and non-web use cases often do, for browsers, the maintenance cost is much, much lower.&lt;/p&gt;
&lt;h2 id=&quot;other-technologies-were-too-specific&quot;&gt;Other technologies were too specific&lt;/h2&gt;
&lt;p&gt;WebAssembly is fundamentally language-agnostic. Flash and Java Applets were built first and foremost to run ActionScript and Java. They’re deeply tied to their relative semantics. Even PNaCl suffers from this to some degree; LLVM is really designed for C-like languages, though not quite the same amount.&lt;/p&gt;
&lt;p&gt;Do we really want to christen one language as the next language of the web? We already have JavaScript. Are we someday going to introduce a third language? A fourth? An agnostic approach is significantly better for longevity’s sake.&lt;/p&gt;
&lt;h2 id=&quot;wasm-has-a-strong-approach-for-safety&quot;&gt;Wasm has a strong approach for safety&lt;/h2&gt;
&lt;p&gt;Java Applets and Flash were security &lt;em&gt;nightmares&lt;/em&gt;. Even if there were attempts to secure them, in reality, they constantly had problems.&lt;/p&gt;
&lt;p&gt;WebAssembly, on the other hand, piggybacks on that JavaScript VM again; all of the effort going into creating its sandbox also applies to Wasm. Wasm is missing some features of regular assembly language that can cause security vulnerabilities, like stack smashing. Wasm is memory-safe, which is huge!&lt;/p&gt;
&lt;p&gt;Additionally, WebAssembly was designed for &lt;em&gt;validation&lt;/em&gt; in mind; its fully typed, and can be checked without running any of its code. It spec includes instructions on how to do validation. This stuff is quite useful!&lt;/p&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;One thing I’ll say about this post is that it’s quite &lt;em&gt;implementer&lt;/em&gt; focused. But implementers are important; they control the web. Providing a solution that works with their goals is just as important as something that works for users. In a future post, I’d like to try to go over user concerns some as well. I have lots of posts to write!&lt;/p&gt;
&lt;p&gt;At the end of the day:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Other technologies were not integrated into the platform, and commercial interests didn’t point towards that happening&lt;/li&gt;
&lt;li&gt;Other technologies required too much; too much to agree on, too much to implement&lt;/li&gt;
&lt;li&gt;Wasm has a really strong sandboxing and verification story that others simply did not.&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title>WebAssembly is more than just the web</title><link>https://steveklabnik.com/writing/webassembly-is-more-than-just-the-web/</link><guid isPermaLink="true">https://steveklabnik.com/writing/webassembly-is-more-than-just-the-web/</guid><description>While WebAssembly was given its name for good reason, I also think it’s quite the misnomer. When you hear about WebAssembly, don’t just think of the web: think bigger. Many programmers know that WebAssembly is a technology that lets you run non-JavaScript code in the browser.…</description><pubDate>Fri, 13 Jul 2018 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;While WebAssembly was given its name for good reason, I also think it’s quite the misnomer. When you hear about WebAssembly, don’t just think of the web: think bigger.&lt;/p&gt;
&lt;p&gt;Many programmers know that WebAssembly is a technology that lets you run non-JavaScript code in the browser. That is true, but there’s a lot more to it. You see, the spec is written in a very interesting way: there’s the core, what WebAssembly actually is. Here’s &lt;a href=&quot;https://webassembly.github.io/spec/&quot;&gt;the opening section&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;To support the embedding of WebAssembly into different environments, its specification is split into layers that are specified in separate documents.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Core specification - Defines the semantics of WebAssembly modules and its instruction set, independent from a concrete embedding.API specifications - Define application programming interfaces enabling the use of WebAssembly modules in concrete embedding environments.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;It goes on to say:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Currently, two APIs are specified: JavaScript API … Web API.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;So, WebAssembly itself, the core, is completely independent of the web. The web is a particular environment that Wasm is embedded &lt;em&gt;in&lt;/em&gt;, but not actually required to use wasm. Other embedding APIs can be created, with their own interfaces, to do various things.&lt;/p&gt;
&lt;p&gt;Let’s make this concrete: on the web, we can write a program that draws graphics using WebGL. But we could also write a desktop program that embeds a WebAssembly interpreter, and provides an OpenGL (or whatever else) API to render to the screen. And now our WebAssembly program is running on the desktop.&lt;/p&gt;
&lt;p&gt;Why would you want to do this? Well:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I wonder if wasm, in being sufficiently minimal, well defined, practical and widely supported, will wind up as an archival format of choice for emulation-based software preservation. &lt;a href=&quot;https://t.co/33OUOrqiWg&quot;&gt;https://t.co/33OUOrqiWg&lt;/a&gt;
— Graydon Hoare (@graydon_pub) July 11, 2018&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;These emulators, with a teeny bit of work, could be made to run on the desktop as well. “Cross-platform” doesn’t just mean “Windows, Linux, and MacOS”, but can also mean running to the web as well.&lt;/p&gt;
&lt;p&gt;There’s so many more things that can be done, too. All it requires is a bit of re-framing of WebAssembly in your mind:&lt;/p&gt;
&lt;p&gt;WebAssembly is &lt;em&gt;not&lt;/em&gt; a way to run code other than JavaScript on the web; WebAssembly is a tiny, embeddable language that you can use almost anywhere.&lt;/p&gt;
&lt;p&gt;Some have compared WebAssembly to Java applets; in some ways, they’re very right, but in some ways, they’re very wrong. Eventually I’ll write a post about the wrong, but for now, the right: in some sense, WebAssembly is a different way of accomplishing what the JVM set out to do: it’s a common virtual machine that can be used to build very cross-platform software.&lt;/p&gt;
&lt;p&gt;There’s a couple of other interesting applications of WebAssembly outside of the browser; one of my personal favorites is &lt;a href=&quot;https://github.com/nebulet/nebulet&quot;&gt;Nebulet&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;A microkernel that implements a WebAssembly “usermode” that runs in Ring 0.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I’d describe it like this:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Nebulet is an operating system that runs WebAssembly programs.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;None of this has anything to do with a web browser; just like ELF is the standard binary format on many Linuxes, WebAssembly is the standard binary format on Nebulet. It’s a new implementation of a quite old idea, but I’m really excited to see where it goes.&lt;/p&gt;
&lt;p&gt;A second interesting example is Parity. I’m a cryptocurrency skeptic, but from a tech perspective, this is quite cool. Parity is a company who is building a VM for the Ethereum cryptocurrency. Etherium’s VM has a programming language, Solidity, that lets you script their blockchain. Writing a programming language is a tough task on its own, and Solidity has had some issues, leading to pretty serious bugs. And those bugs are affecting people’s money.&lt;/p&gt;
&lt;p&gt;So, rather than keep their custom language, Parity is experimenting with &lt;a href=&quot;https://wiki.parity.io/WebAssembly-Design&quot;&gt;embedding WebAssembly into the Ethereum VM instead&lt;/a&gt;. This gets them a well-tested language that has pretty decent toolchain support, and lets them use a variety of other languages to do said scripting. This is very cool!&lt;/p&gt;
&lt;p&gt;These are a few of the possibilities for WebAssembly, and I’m really excited about where it could go in the future.&lt;/p&gt;</content:encoded></item><item><title>&quot;The Expressive C++17 Coding Challenge (in Rust)&quot; revisited</title><link>https://steveklabnik.com/writing/the-expressive-c-17-coding-challenge-in-rust-revisited/</link><guid isPermaLink="true">https://steveklabnik.com/writing/the-expressive-c-17-coding-challenge-in-rust-revisited/</guid><description>In October of last year, I wrote a post, “The Expressive C++17 Coding Challenge (in Rust)” . For various reasons, it got brought up again in the D world, and seb has written a new post . It’s good, you should check it out! However, it links to my gist, not my blog post. As I said…</description><pubDate>Wed, 14 Feb 2018 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;In October of last year, I wrote a post, &lt;a href=&quot;/writing/the-expressive-c-17-coding-challenge-in-rust/&quot;&gt;“The Expressive C++17 Coding Challenge (in Rust)”&lt;/a&gt;. For various reasons, it got brought up again in the D world, and &lt;a href=&quot;https://seb.wilzba.ch/b/2018/02/the-expressive-c17-coding-challenge-in-d/&quot;&gt;seb has written a new post&lt;/a&gt;. It’s good, you should check it out!&lt;/p&gt;
&lt;p&gt;However, it links to my gist, not my blog post. As I said back then:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I held myself to the same constraints as the original contest; no external packages is a bit painful in Rust, but it’s not too bad. Mostly it would let me eliminate boilerplate while also improving correctness, and making the code a bit shorter.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;So, that got me thinking: What &lt;em&gt;would&lt;/em&gt; this look like if I could use external packages? I took about an hour, and knocked it out. I have two versions to show you today, one where I pay no attention to allocations, and one where it’s zero-allocation.&lt;/p&gt;
&lt;p&gt;First, the “whatever just allocate” version:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;extern crate csv;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;#[macro_use]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;extern crate serde_derive;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;extern crate serde;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;#[macro_use]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;extern crate structopt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;use std::error::Error;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;use std::fs::File;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;use structopt::StructOpt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;#[derive(Debug,Serialize,Deserialize)]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;struct Record {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    name: String,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    surname: String,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    city: String,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    country: String,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;#[derive(StructOpt, Debug)]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;#[structopt(name = &quot;basic&quot;)]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;struct Opt {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    filename: String,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    column_name: String,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    replacement: String,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    output_filename: String,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;fn run(args: &amp;#x26;Opt) -&gt; Result&amp;#x3C;(), Box&amp;#x3C;Error&gt;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    let input = File::open(&amp;#x26;args.filename)?;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    let output = File::create(&amp;#x26;args.output_filename)?;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    let mut rdr = csv::Reader::from_reader(input);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    let mut wtr = csv::Writer::from_writer(output);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    for result in rdr.deserialize() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        let mut record: Record = result?;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        let replacement = args.replacement.clone();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        match &amp;#x26;*args.column_name {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            &quot;name&quot; =&gt; record.name = replacement,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            &quot;surname&quot; =&gt; record.surname = replacement,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            &quot;city&quot; =&gt; record.city = replacement,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            &quot;country&quot; =&gt; record.country = replacement,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            _ =&gt; panic!(&quot;incorrect column name&quot;),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        wtr.serialize(record)?;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    wtr.flush()?;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    Ok(())&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;fn main() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    let opt = Opt::from_args();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    if let Err(err) = run(&amp;#x26;opt) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        eprintln!(&quot;error: {}&quot;, err);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        std::process::exit(1);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This uses the &lt;code&gt;[csv&lt;/code&gt; crate](&lt;a href=&quot;https://crates.io/crates/csv/1.0.0-beta.5&quot;&gt;https://crates.io/crates/csv/1.0.0-beta.5&lt;/a&gt;) to do the heavy lifting with regards to the CSV stuff, and the &lt;code&gt;[strucopt&lt;/code&gt; crate](&lt;a href=&quot;https://crates.io/crates/structopt&quot;&gt;https://crates.io/crates/structopt&lt;/a&gt;) for argument parsing. Not only is this code much shorter than my “no crates” version, but it’s also got more features!&lt;/p&gt;
&lt;p&gt;There’s a few things that aren’t the best here: first, the &lt;code&gt;match&lt;/code&gt;. Rust doesn’t have reflection, exactly, so saying “hey I have this string and I want to index it in this struct” is not as nice. I’m just panic-ing here, but it’d be nicer to validate it up front, and possibly even do some custom derive shenanigans so that I don’t have to write it myself, but I wanted to present a fairly &lt;em&gt;realistic&lt;/em&gt; version of what I’d write today. This is good enough.&lt;/p&gt;
&lt;p&gt;Second, there’s that one &lt;code&gt;clone&lt;/code&gt;. We need it because we’ve said that our &lt;code&gt;Record&lt;/code&gt; type holds &lt;code&gt;String&lt;/code&gt;s, and so has ownership over the string. We end up copying &lt;code&gt;London&lt;/code&gt; each iteration of the loop. Is copying a city name a problem? Not &lt;em&gt;really&lt;/em&gt;, in the context of this example. But what if it &lt;em&gt;was&lt;/em&gt;? Fundamentally, there’s no reason to do any allocation here: We’re reading from a file, and we’re writing the same string over and over again.&lt;/p&gt;
&lt;p&gt;Enter version 2:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;extern crate csv;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;#[macro_use]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;extern crate serde_derive;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;extern crate serde;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;#[macro_use]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;extern crate structopt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;use std::error::Error;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;use std::fs::File;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;use structopt::StructOpt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;#[derive(Debug,Serialize,Deserialize)]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;struct Record&amp;#x3C;&apos;a&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    name: &amp;#x26;&apos;a str,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    surname: &amp;#x26;&apos;a str,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    city: &amp;#x26;&apos;a str,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    country: &amp;#x26;&apos;a str,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;#[derive(StructOpt, Debug)]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;#[structopt(name = &quot;basic&quot;)]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;struct Opt {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    filename: String,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    column_name: String,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    replacement: String,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    output_filename: String,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;fn run(args: &amp;#x26;Opt) -&gt; Result&amp;#x3C;(), Box&amp;#x3C;Error&gt;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    let input = File::open(&amp;#x26;args.filename)?;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    let output = File::create(&amp;#x26;args.output_filename)?;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    let mut rdr = csv::Reader::from_reader(input);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    let mut wtr = csv::Writer::from_writer(output);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    let mut raw_record = csv::StringRecord::new();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    let headers = rdr.headers()?.clone();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    while rdr.read_record(&amp;#x26;mut raw_record)? {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        let mut record: Record = raw_record.deserialize(Some(&amp;#x26;headers))?;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        match &amp;#x26;*args.column_name {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            &quot;name&quot; =&gt; record.name = &amp;#x26;args.replacement,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            &quot;surname&quot; =&gt; record.surname = &amp;#x26;args.replacement,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            &quot;city&quot; =&gt; record.city = &amp;#x26;args.replacement,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            &quot;country&quot; =&gt; record.country = &amp;#x26;args.replacement,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            _ =&gt; panic!(&quot;incorrect column name&quot;),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        wtr.serialize(record)?;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    wtr.flush()?;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    Ok(())&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;fn main() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    let opt = Opt::from_args();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    if let Err(err) = run(&amp;#x26;opt) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        eprintln!(&quot;error: {}&quot;, err);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        std::process::exit(1);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is &lt;em&gt;slightly&lt;/em&gt; more involved, as you no longer get access to the nice iterator, and have to do things a little more manually. But it took me about five minutes to port this bit over, so it’s not &lt;em&gt;too&lt;/em&gt; onerous.&lt;/p&gt;
&lt;p&gt;So, as you can see, once you let people use external packages, the Rust gets &lt;em&gt;significantly&lt;/em&gt; nicer. The code pretty much mirrors the task: open the two files, iterate over them, replace the column, write it out. Nice.&lt;/p&gt;
&lt;p&gt;I’m not going to do any performance comparisons here because that’s not really what the contest was about. I am mildly curious… if I really wanted to optimize performance, I’d also skip the string stuff and go for bytes directly. This isn’t a super tough transformation, but moves things to be slightly lower level.&lt;/p&gt;
&lt;p&gt;If you manipulate CSVs often, you should check out &lt;a href=&quot;https://crates.io/crates/xsv&quot;&gt;xsv&lt;/a&gt;, a command-line tool in Rust that lets you slice and dice these files with speed and ease.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;I should also mention that several people have been working on &lt;code&gt;quicli&lt;/code&gt;, a package to make making CLIs super easy. One of its authors &lt;a href=&quot;https://gist.github.com/killercup/049d759118e3b5029737eb77e157ea42&quot;&gt;posted a gist of what this looks like with quicli&lt;/a&gt;, you should check that out too!&lt;/p&gt;</content:encoded></item><item><title>Looking back at Rust in 2018</title><link>https://steveklabnik.com/writing/looking-back-at-rust-in-2018/</link><guid isPermaLink="true">https://steveklabnik.com/writing/looking-back-at-rust-in-2018/</guid><description>A careful reader will note the date of this post; it’s fundamentally in response to this call for blog posts, with a rhetorical device of looking backwards as if my personal plans for Rust came true. If you’re reading this in 2019 or beyond, this may be a work of fiction. It’s…</description><pubDate>Tue, 09 Jan 2018 00:00:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;A careful reader will note the date of this post; it’s fundamentally in response to this call for blog posts, with a rhetorical device of looking backwards as if my personal plans for Rust came true. If you’re reading this in 2019 or beyond, this may be a work of fiction.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;It’s been an exciting year for Rust. Well, it depends on what you mean by “exciting”, exactly. In a word, this year has been about &lt;em&gt;polish&lt;/em&gt;. I find this kind of thing exciting! It’s a very different kind of exciting than the “new and shiny” exciting. It’s “take what we have and make it shiny.”&lt;/p&gt;
&lt;p&gt;Let’s recap the major achievements of the year.&lt;/p&gt;
&lt;h2 id=&quot;rust-2018&quot;&gt;Rust 2018&lt;/h2&gt;
&lt;p&gt;First of all, we shipped our first epoch! If you type &lt;code&gt;cargo new&lt;/code&gt; today, you’ll see a new shiny entry in your &lt;code&gt;Cargo.toml&lt;/code&gt;:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;[package]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;name = &quot;new-program&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;version = &quot;0.1.0&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;authors = [&quot;steveklabnik &amp;#x3C;steve@steveklabnik.com&gt;&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;epoch = &quot;2018&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;[dependencies]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;What does this mean in practical terms? Well, a few things. First, let’s get the big one out of the way: Try to compile this code with no epoch, or with &lt;code&gt;epoch = &quot;2015&quot;&lt;/code&gt;:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;fn main() {    let catch = 5;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You’ll see this:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&gt; cargo build&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;   Compiling new-program v0.1.0 (file:///C:/Users/steve/tmp/new-program)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;warning: `catch` will become a keyword in the 2018 epoch&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt; --&gt; src\main.rs:2:9&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  |&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;2 |     let catch = 5;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  |         ^^^^^&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  |&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  = note: #[warn(new_keyword)] on by default&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  = note: to avoid this warning, consider using `_catch` instead&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And if you change it to &lt;code&gt;epoch = &quot;2018&quot;&lt;/code&gt;, you’ll see this:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&gt; cargo build&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;   Compiling new-program v0.1.0 (file:///C:/Users/steve/tmp/new-program)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;error: expected pattern, found keyword `catch`&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt; --&gt; src\main.rs:2:9&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  |&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;2 |     let catch = 5;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  |         ^^^^^&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;error: aborting due to previous error&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Success! However, the specifics here aren’t as interesting as what this change means:&lt;/p&gt;
&lt;p&gt;First, &lt;em&gt;this is one of only two changes that relies on the epoch&lt;/em&gt;. When we announced our plans for epochs, many people were skeptical that we would do as we said, and only included small, parser-level changes here. But we did, and will continue to do so. &lt;code&gt;catch&lt;/code&gt; and &lt;code&gt;dyn Trait&lt;/code&gt; are the only two changes here.&lt;/p&gt;
&lt;p&gt;Second, &lt;em&gt;we’ve demonstrated that this doesn’t split the ecosystem&lt;/em&gt;. All of the crates that had no epoch are treated as 2015, and everything still works. Mixing 2015 and 2018 code works just fine.&lt;/p&gt;
&lt;p&gt;Finally, &lt;em&gt;mrustc has not had trouble implementing this split&lt;/em&gt;. &lt;code&gt;[mrustc&lt;/code&gt; is an alternative implementation of Rust](&lt;a href=&quot;https://github.com/thepowersgang/mrustc&quot;&gt;https://github.com/thepowersgang/mrustc&lt;/a&gt;), and some of the worries about epochs would be that they would unnecessarily burden alternative implementations. This fear has not borne fruit yet though.&lt;/p&gt;
&lt;h2 id=&quot;we-did-ship-some-new-stuff&quot;&gt;We did ship &lt;em&gt;some&lt;/em&gt; new stuff&lt;/h2&gt;
&lt;p&gt;Even though this year was about polish, that doesn’t mean that we had no new features. The key is, these features were all &lt;em&gt;designed&lt;/em&gt; in 2017 or before. That is, features like non-lexical lifetimes, &lt;code&gt;impl Trait&lt;/code&gt;, and Macros 2.0 didn’t land in stable until 2018, but they’ve been worked on for years. At the end of 2017, we had preliminary implementations already landed, it was just about polishing them up so we could ship.&lt;/p&gt;
&lt;p&gt;Cargo, however, did gain some new abilities. Cargo was sort of neglected in 2017, or at least, wasn’t worked on as much as the rest of the project was. Cargo grew the ability to use alternative registries, and at least one company is offering “crates.io as a service” and “crates.io behind your firewall”. Cargo also became easier to use offline, and the “integrate Cargo into other build systems” work bore some more fruit.&lt;/p&gt;
&lt;h2 id=&quot;webassembly-and-embedded-platforms&quot;&gt;WebAssembly and Embedded platforms&lt;/h2&gt;
&lt;p&gt;At the end of 2017, Rust was poised to take advantage of WebAssembly. And take advantage, we did. WebAssembly has not taken over the world yet, but that was also never its intention. It is a common aspect of the Web Platform these days, and Rust’s support for it is so excellent that it’s the primary language with which you write new code for WebAssembly today. Tons of JavaScript programmers use Rust for their various systems-level tasks on the web, and we’re just starting to see completely new kinds of applications form. Adding Rust to your Node or front-end project is trivial, thanks to excellent integration from JavaScript’s build tools, or as we now call them, “compilers”.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;An aside: in the 2014-2017 era, even though JavaScript was JIT compiled, many programmers used various “build tools” or “transpilers” to do things like minify and bundle their JavaScript together. This was useful for things like “let me use new ES2017 features today but transpile to ES5.” In 2017, lots of JavaScript programmers, through tools like Rollup, started to appreciate that what they’re doing, on a fundamental level, is compiling. Once these tools realized this, they started taking advantage of decades of existing compiler research, and these tools started doing amazing things. Oddly enough, this makes JavaScript feel more like Java: you compile to a thing that ends up being JIT-ed. And that’s not even half of it; stuff like Ember’s GlimmerVM took this approach to new heights.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Furthermore, it’s considered standard practice to test your crate against the WebAssembly target, just like you would Windows, Linux, and macOS, so the vast majority of the crates.io ecosystem Just Works.&lt;/p&gt;
&lt;p&gt;But this work on wasm has a good side effect: wasm is basically a very minimal embedded platform. By doing the legwork to make wasm awesome, we also made embedded platforms of various kinds awesome. There’s also specific work that had to be done, for example, remember &lt;code&gt;xargo&lt;/code&gt;? Cargo just does that now. We’ve elevated ARM to a Tier 1 platform these days, and provide easy instructions for getting a new architecture going.&lt;/p&gt;
&lt;p&gt;This also implies stabilizing some of the lower-level things that are needed to do OSdev work. You can’t write a “real” OS in stable Rust yet, but you can write toy ones, and real OSes should be usable by next year.&lt;/p&gt;
&lt;h2 id=&quot;stabilization&quot;&gt;Stabilization&lt;/h2&gt;
&lt;p&gt;One way in which we did polish was to ship a ton of stuff that was previously in flight. I mentioned non-lexical lifetimes earlier, as well as some other features, but there’s also a sort of “long tail” of stabilizations that we addressed.&lt;/p&gt;
&lt;p&gt;At the start of the year, the teams went through each of their feature gates, and voted: stabilize, put on hold, or remove. Things put on hold this year will get decided next year, but cannot be put on hold for another year. Of course, there were some small course-corrections over the year, but in general, it let us go “oh hey, slice patterns has been unstable since before Rust 1.0, let’s finally ship it.”&lt;/p&gt;
&lt;h2 id=&quot;bugs--new-contributors&quot;&gt;Bugs &amp;#x26; new contributors&lt;/h2&gt;
&lt;p&gt;Rust’s bugtracker was in a much better state in 2017 than in 2016, but got even better in 2018. 2017 saw the infrastructure team actually ensure that all bugs get triaged, that is, they all have tags within two days of being opened. In 2018, however, there was a focus to knock out a lot of the long-standing, papercut style bugs. At the start of 2018, there were ~3100 bugs on the tracker, but today, there are only ~1500. That’s four bugs per day! We couldn’t have gotten there without all of the new contributors and team members we’ve added this year; in 2017, we had about 75 people on our various teams, and now we have 100. Your average Rust release in 2017 had about 120 contributors, it’s 180 for 2018.&lt;/p&gt;
&lt;h2 id=&quot;community-and-job-growth&quot;&gt;Community and Job growth&lt;/h2&gt;
&lt;p&gt;It’s not just the teams that have grown, but also the community. For example, in 2016, crates.io had ~7500 crates. In 2017, ~13,000. In 2018, we’re up to 35,000. That’s a lot of packages! One major driver of this growth is jobs; once &lt;strong&gt;REDACTED&lt;/strong&gt; announced that they’d been using Rust in a production setting, and that compared to the old system written in &lt;strong&gt;REDACTED&lt;/strong&gt;, it saved them millions of dollars in server costs per year, a ton of companies started using Rust. It’s not &lt;em&gt;super&lt;/em&gt; easy to get a Rust job, but they’re out there. We’ve also seen our meetups continue to grow, RustConf had two tracks this year, and there’s a new RustFest in South America, with rumors of a conference in China next year.&lt;/p&gt;
&lt;h2 id=&quot;ides&quot;&gt;IDEs&lt;/h2&gt;
&lt;p&gt;While I don’t really use IDEs, we put a lot of work into making them awesome, and 2018 was the first time that people who &lt;em&gt;do&lt;/em&gt; use IDEs love using one. Specifically, they love using the new IDE that JetBrains has released for Rust. In 2017, JetBrains was sponsoring the plugin for IntelliJ, but in 2018, they’ve released a whole product. Other IDEs are coming along swimmingly; Visual Studio now has really excellent support, for example.&lt;/p&gt;
&lt;h2 id=&quot;documentation&quot;&gt;Documentation&lt;/h2&gt;
&lt;p&gt;I work on docs, so I’m going to give this a section, even though maybe other things are more “exciting”.&lt;/p&gt;
&lt;p&gt;2018 saw the release of $REDACTED, a sort of “next-generation &lt;code&gt;rustdoc&lt;/code&gt;.” It focused on not just API docs, but all of your docs holistically; you can publish guides as well, structure things how you’d like, etc. In some ways, it’s “&lt;code&gt;rustdoc&lt;/code&gt; + &lt;code&gt;mdbook&lt;/code&gt;” in a nice integrated package. This has led to even more people writing even better docs, since it’s so nice to use.&lt;/p&gt;
&lt;p&gt;There were two other major initiatives this year: focusing on intermediate documentation, and helping major ecosystem crates get excellent docs. In 2017, there was sort of a “what do I do after TRPL” situation, but now we’ve got some great resources to help you grow as a Rust programmer. Additionally, many of the more popular crates have docs that rival the standard library’s, and smaller crates have decent docs.&lt;/p&gt;
&lt;p&gt;Oh, and TRPL saw its initial paper release early in the year. Yay!&lt;/p&gt;
&lt;h2 id=&quot;epilogue&quot;&gt;Epilogue&lt;/h2&gt;
&lt;p&gt;Whew, that’s a lot of stuff! What does 2019 hold for Rust? That post is for another time.&lt;/p&gt;</content:encoded></item><item><title>Five years with Rust</title><link>https://steveklabnik.com/writing/five-years-with-rust/</link><guid isPermaLink="true">https://steveklabnik.com/writing/five-years-with-rust/</guid><description>Today is five years since I first heard of Rust. I wrote a post last year about it. This year, I have something slightly different in mind. Five years is a long time in tech. It’s also a long time for me to be focused on one specific thing; other than the pizza job I held in high…</description><pubDate>Thu, 21 Dec 2017 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Today is five years since I first heard of Rust. &lt;a href=&quot;/writing/four-years-with-rust/&quot;&gt;I wrote a post last year&lt;/a&gt; about it. This year, I have something slightly different in mind.&lt;/p&gt;
&lt;p&gt;Five years is a long time in tech. It’s also a long time for me to be focused on one specific thing; other than the pizza job I held in high school and college, I’ve never stayed in a single job for five years. (This is true today as well; it’s not like I got a job with Rust the first day I learned of its existence.) I started with Ruby and Rails in 2008/2009, and my final commits to Rails were in August/September of 2013. So at this point, my career has basically been split in half, rather than dominated by Ruby.&lt;/p&gt;
&lt;p&gt;Five years ago tomorrow, I registered &lt;a href=&quot;http://www.rustforrubyists.com/&quot;&gt;http://www.rustforrubyists.com/&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Yesterday, I had lunch with someone I’m very honored to call a friend. We talked about a lot of things, but also about Rust’s past, present, and future. One thing I’ve always felt a little awkward about is that there was a crucial point back in 2011/2012 where I wasn’t sure what to do with myself. I was very frustrated by the industry, and considered doing other things instead. But, as they and I talked about, sometimes, it’s not about your interests. If what you want to do is change the world, caring a lot isn’t enough; you have to analyze what you can actually &lt;em&gt;do&lt;/em&gt;. While I think our industry is pretty broken, I at least have the ability to try and improve it, thanks to my stature. (God, even just typing that makes me feel gross.)&lt;/p&gt;
&lt;p&gt;I decided to put my time into Rust because I believed, and still believe, that it’s an important thing. And I saw the work that needed to be done, and saw that it’s the kind of work that I could do. And so, it’s maybe not something bigger, but I resolved myself to doing the work.&lt;/p&gt;
&lt;p&gt;Five years in, I think my journey has been successful so far. I’m proud of how far Rust has come. That said, there’s a lot more work to do. I’m still committed as ever to getting that work done, and feel proud to be able to work alongside people as amazing as the Rust community.&lt;/p&gt;
&lt;p&gt;Here’s to five more years. ?&lt;/p&gt;</content:encoded></item><item><title>&quot;The Expressive C++17 Coding Challenge&quot; in Rust</title><link>https://steveklabnik.com/writing/the-expressive-c-17-coding-challenge-in-rust/</link><guid isPermaLink="true">https://steveklabnik.com/writing/the-expressive-c-17-coding-challenge-in-rust/</guid><description>A few weeks ago, two C++ bloggers initiated a challenge ( here and here ): use the shiny new features of C++17 to write a small program that manipulates CSV files. The link is to the results; you can see the examples people came up with. I’ve written a follow-up post too! I…</description><pubDate>Wed, 25 Oct 2017 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;A few weeks ago, two C++ bloggers initiated a challenge (&lt;a href=&quot;https://www.fluentcpp.com/2017/10/23/results-expressive-cpp17-coding-challenge/&quot;&gt;here&lt;/a&gt; and &lt;a href=&quot;http://www.bfilipek.com/2017/09/the-expressive-cpp17-challenge.html&quot;&gt;here&lt;/a&gt;): use the shiny new features of C++17 to write a small program that manipulates CSV files. The link is to the results; you can see the examples people came up with.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;I’ve written &lt;a href=&quot;/writing/the-expressive-c-17-coding-challenge-in-rust-revisited/&quot;&gt;a follow-up post&lt;/a&gt; too!&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;I decided to implement it in Rust for fun. You should give it a try, in whatever language you use, it’s a nice sample problem. I held myself to the same constraints as the original contest; no external packages is a bit painful in Rust, but it’s not too bad. Mostly it would let me eliminate boilerplate while also improving correctness, and making the code a bit shorter.&lt;/p&gt;
&lt;p&gt;Anyway, here it is:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://gist.github.com/steveklabnik/ad0a33acc82e21ca3f763e4278ad31a5&quot;&gt;https://gist.github.com/steveklabnik/ad0a33acc82e21ca3f763e4278ad31a5&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I implemented &lt;code&gt;From&lt;/code&gt; for everything so I could use &lt;code&gt;?&lt;/code&gt;, but then &lt;code&gt;main&lt;/code&gt; just has a ton of &lt;code&gt;unwrap&lt;/code&gt;s. I normally would remove those too, but the challenge does not include good error handling, so I decided to just stick to the text of the challenge.&lt;/p&gt;
&lt;p&gt;I’m not going to say that this is the &lt;em&gt;best&lt;/em&gt; Rust code in the world, nor compare it directly to the C++ examples. But it was a fun hour or two to knock it out, and figured I’d at least share my results.&lt;/p&gt;</content:encoded></item><item><title>Want to join the Rust docs team?</title><link>https://steveklabnik.com/writing/want-to-join-the-rust-docs-team/</link><guid isPermaLink="true">https://steveklabnik.com/writing/want-to-join-the-rust-docs-team/</guid><description>One of Rust’s major goals this year is to provide mentoring at all levels of the project . This is a goal I’m very on-board with. There’s lots of ways to get involved with Rust, but I’d like to talk about the bit I’m most involved in: documentation. There’s many ways to…</description><pubDate>Fri, 24 Mar 2017 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;One of Rust’s major goals this year is to &lt;a href=&quot;https://github.com/rust-lang/rust-roadmap/issues/13&quot;&gt;provide mentoring at all levels of the project&lt;/a&gt;. This is a goal I’m very on-board with. There’s lots of ways to get involved with Rust, but I’d like to talk about the bit I’m most involved in: documentation.&lt;/p&gt;
&lt;p&gt;There’s many ways to contribute to Rust’s docs. Some people contribute occasional PRs, some people end up contributing a lot. No matter what your interest, I’d like to help. But before I get into those details, &lt;em&gt;why&lt;/em&gt; should someone get involved with documentation? I have my own reasons, but I also have a pitch for you:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Working on documentation is a fantastic way to learn something in a deeper way.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;In order to document something, you have to understand it, even if only a little bit! It’s a good excuse to dig into the details. And I’ve found that many people are eager to help explain something to you in return for you writing that down and synthesizing it into documentation.&lt;/p&gt;
&lt;p&gt;If that sounds intriguing to you, let’s talk! There’s a number of different ways to do this, and I’m interested generally in helping anyone work on Rust’s documentation, in any form. However, if you don’t have something in mind, I do have a suggestion.&lt;/p&gt;
&lt;p&gt;Back in October of 2015, I made a &lt;a href=&quot;https://github.com/rust-lang/rust/issues/29329&quot;&gt;big GitHub issue&lt;/a&gt; to track giving the whole standard library documentation a once-over. I then made sub-issues for each main module. Slowly, myself and others have been knocking them out, but there’s still a number of issues open.&lt;/p&gt;
&lt;p&gt;Today, I went through all of the remaining ones, and made fine-grained bullet points of what needs to be done. I’ll admit that some of them may not be as explicit as they could be, but it at least gives a starting point to talk about. Here’s all the sections that are currently open:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/rust-lang/rust/issues/29349&quot;&gt;convert&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/rust-lang/rust/issues/29354&quot;&gt;ffi&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/rust-lang/rust/issues/29381&quot;&gt;macros&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/rust-lang/rust/issues/29378&quot;&gt;thread&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/rust-lang/rust/issues/29377&quot;&gt;sync&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/rust-lang/rust/issues/29375&quot;&gt;str&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/rust-lang/rust/issues/29371&quot;&gt;ptr&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/rust-lang/rust/issues/29370&quot;&gt;process&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/rust-lang/rust/issues/29367&quot;&gt;os&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/rust-lang/rust/issues/29365&quot;&gt;ops&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/rust-lang/rust/issues/29363&quot;&gt;net&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/rust-lang/rust/issues/29357&quot;&gt;hash&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/rust-lang/rust/issues/29355&quot;&gt;fmt&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Some of the work that needs to be done is very small: add a link here, re-word a sentence there. Other bits are large; “this whole thing needs re-written.”&lt;/p&gt;
&lt;p&gt;So here’s my pitch to you: have you ever wanted to learn a bit more about Rust? Do any of those names sound interesting to you? Maybe you’ve wanted to learn a bit more about threads in Rust. Check out that ‘thread’ issue above, poke around, learn some Rust, and then let’s make the docs better! We can work together on the issues, through email, or on IRC. Whatever works. Maybe you’ll find it as addicting as I do. And I find that people who are non-experts write way better docs than experts. So don’t worry about that!&lt;/p&gt;
&lt;p&gt;Worst case, you’ll have learned a bit of the standard library a bit better, and that’s always a good thing, too.&lt;/p&gt;</content:encoded></item><item><title>An overview of macros in Rust</title><link>https://steveklabnik.com/writing/an-overview-of-macros-in-rust/</link><guid isPermaLink="true">https://steveklabnik.com/writing/an-overview-of-macros-in-rust/</guid><description>Rust has had a lot of stuff going on with “macros”. There are a few, interconnected aspects of these features, many different names for the same thing, and a lot of development work going on. This post will give an overview of the past, present, and future of macros in Rust.…</description><pubDate>Tue, 24 Jan 2017 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Rust has had a lot of stuff going on with “macros”. There are a few, interconnected aspects of these features, many different names for the same thing, and a lot of development work going on. This post will give an overview of the past, present, and future of macros in Rust.&lt;/p&gt;
&lt;p&gt;Ultimately, macros allow you to write things like this:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;let map = hashmap!{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    &quot;a&quot; =&gt; 1,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    &quot;b&quot; =&gt; 2,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;};&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;or&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;#[derive(Serialize, Deserialize)]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;struct S {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    #[serde(rename = &quot;a&quot;)]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    f: i32,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That is, some macros look like functions: &lt;code&gt;foo!&lt;/code&gt;, but allow you to write nearly arbitrary syntax inside of the &lt;code&gt;()&lt;/code&gt;s. Some let you control the ability to write custom attributes. Both generate some other kind of valid Rust code for the compiler to interpret. In the first case, the &lt;code&gt;hashmap!&lt;/code&gt; macro will expand to a call to &lt;code&gt;HashMap::new&lt;/code&gt; and a bunch of &lt;code&gt;insert&lt;/code&gt; calls, and the second case, the &lt;code&gt;Serialize&lt;/code&gt; and &lt;code&gt;Deserialize&lt;/code&gt; traits will be automatically implemented for this struct, along with a bit of custom logic where the field &lt;code&gt;f&lt;/code&gt; maps to the name &lt;code&gt;a&lt;/code&gt; in the data that’s being {de,}serialized.&lt;/p&gt;
&lt;p&gt;These features are extremely powerful, but also must be done right: metaprogramming is very useful, but can also make code inscrutable, or give poor error messages.&lt;/p&gt;
&lt;p&gt;Oh, and I’d like to give a shout-out to &lt;a href=&quot;https://danielkeep.github.io/tlborm/book/index.html&quot;&gt;The Little Book of Rust Macros&lt;/a&gt;, which is basically &lt;em&gt;the&lt;/em&gt; resource for doing this kind of work. If you are interested in writing macros, you should check it out.&lt;/p&gt;
&lt;h2 id=&quot;pre-10&quot;&gt;Pre-1.0&lt;/h2&gt;
&lt;p&gt;As Rust developed, two major forms of macros evolved. One was called “macros” and the other was called “compiler plugins”. Both of these systems were pretty good, but both of them also had a lot of problems. We’ll get into the details of each of these kinds of macros below, but there’s one thing we should talk about first. On the way to 1.0, it was decided to stabilize one kind of macros, but not the other. From &lt;a href=&quot;https://blog.rust-lang.org/2014/10/30/Stability.html&quot;&gt;Stability as a Deliverable&lt;/a&gt;: (also, this uses some terms that we will cover shortly)&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;After extensive discussion, we plan to release globs and macros as stable at 1.0. For globs, we believe we can address problems in a backwards-compatible way. For macros, we will likely provide an alternative way to define macros (with better hygiene) at some later date, and will incrementally improve the “macro rules” feature until then. The 1.0 release will stabilize all current macro support, including import/export.On the other hand, we cannot stabilize syntax extensions, which are plugins with complete access to compiler internals. Stabilizing it would effectively forever freeze the internals of the compiler; we need to design a more deliberate interface between extensions and the compiler. So syntax extensions will remain behind a feature gate for 1.0.Many major uses of syntax extensions could be replaced with traditional code generation, and the Cargo tool will soon be growing specific support for this use case. We plan to work with library authors to help them migrate away from syntax extensions prior to 1.0. Because many syntax extensions don’t fit this model, we also see stabilizing syntax extensions as an immediate priority after the 1.0 release.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;We’ll discuss in each section how this ended up working out, but it’s important to remember that only &lt;em&gt;one&lt;/em&gt; form of these macros was available on stable Rust for 1.0, and in fact, as of the time of this writing. That’s going to change soon…&lt;/p&gt;
&lt;p&gt;It’s also important to note that we weren’t entirely happy with macros. They were fine, but they have some flaws. We wanted to fix them, but we also didn’t want to ship 1.0 without macros. Language design is hard. I’ll talk about this more in the appropriate section.&lt;/p&gt;
&lt;h2 id=&quot;declarative-macros&quot;&gt;Declarative Macros&lt;/h2&gt;
&lt;p&gt;The first form of Macros in Rust, and the one that’s most widely used, are called “declarative macros”, sometimes “macros by example”, sometimes “macro_rules macros”, or sometimes just “macros”. At their core, declarative macros allow you to write something similar to a Rust &lt;code&gt;match&lt;/code&gt; statement:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;match x {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    4 =&gt; println!(&quot;four!&quot;),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    5 =&gt; println!(&quot;five!&quot;),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    _ =&gt; println!(&quot;something else&quot;),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;With &lt;code&gt;match&lt;/code&gt;, &lt;code&gt;x&lt;/code&gt;’s structure and value will be evaluated, and the right arm will execute based on what matches. So if &lt;code&gt;x&lt;/code&gt; is five, the second arm happens. Etc.&lt;/p&gt;
&lt;p&gt;These kinds of macros work in the same way: you set up some sort of pattern, and then, if that pattern matches, some code is generated. One important difference here is that in &lt;code&gt;match&lt;/code&gt;, &lt;code&gt;x&lt;/code&gt; gets evaluated. With macros, &lt;code&gt;x&lt;/code&gt; does not get evaluated.&lt;/p&gt;
&lt;p&gt;There are two kinds of declarative macros: ones defined with the &lt;code&gt;macro_rules!&lt;/code&gt; keyword, and ones defined with the &lt;code&gt;macro&lt;/code&gt; keyword.&lt;/p&gt;
&lt;h3 id=&quot;macro_rules&quot;&gt;&lt;code&gt;macro_rules!&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;These are most commonly known as “macros” in Rust world, and are the only thing that’s stable in Rust at the time of this writing. Here’s a macro you’ll see when using Rust:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;let x: Vec&amp;#x3C;u32&gt; = vec![1, 2, 3];&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This macro creates a new vector, with three elements inside. Here’s what the macro could look like, written with &lt;code&gt;macro_rules!&lt;/code&gt;:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;macro_rules! vec {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    ( $( $x:expr ),* ) =&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            let mut temp_vec = Vec::new();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            $(&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                temp_vec.push($x);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            )*&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            temp_vec&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    };&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Whew! That’s a bunch of stuff. The most important line is here:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    ( $( $x:expr ),* ) =&gt; {&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This &lt;code&gt;pattern =&gt; block&lt;/code&gt; looks similar to the &lt;code&gt;match&lt;/code&gt; statement above. If this pattern matches, then the block of code will be emitted. Given that this is the only pattern in this macro, there’s only one valid way to match; any other will be an error. More complex macros will have more than one rule.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;$x:expr&lt;/code&gt; part matches an expression, and gives it the name &lt;code&gt;$x&lt;/code&gt;. The &lt;code&gt;$(),*&lt;/code&gt; part matches zero or more of these expressions. Then, in the body of the macro, the &lt;code&gt;$()*&lt;/code&gt; part is generated for each part that matches, and the &lt;code&gt;$x&lt;/code&gt; within is replaced with each expression that was matched.&lt;/p&gt;
&lt;p&gt;These macros are fine, but there’s a number of bugs and rough edges. For example, there’s no namespacing: if a macro exists, it’s everywhere. In order to prevent name clashes, this means that you have to explicitly import the macros when using a crate:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;#[macro_use]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;extern crate serde;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Otherwise, you couldn’t import two crates that had the same macro name. In practice this conflict doesn’t come up much, but as we grow, it becomes more likely. The hygiene of &lt;code&gt;macro_rules&lt;/code&gt; is there, but not perfect. (Only local variables and labels are hygienic…) Et cetera. The plan is that with the new macro systems, you’ll be able to use the regular module system, and use macros just like you use functions today.&lt;/p&gt;
&lt;p&gt;Even with these problems, macros were useful enough to include in Rust 1.0. But plans for a better macro system were already being worked on, and so, they were given the name &lt;code&gt;macro_rules!&lt;/code&gt; so that we could eventually deprecate all of this. This is one of the few features that we decided to do this with Rust 1.0; a vestigial thing that was always planned for obsolescence. Doing it hurts, but not having any metaprogramming at all would hurt much more.&lt;/p&gt;
&lt;h3 id=&quot;macro&quot;&gt;&lt;code&gt;macro&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;As such, the &lt;code&gt;macro&lt;/code&gt; keyword was reserved for a new macro system. We’re still not 100% sure if we’re calling these “macros by example” (which you’ll sometimes see with a “2.0” at the end) or “declarative macros”. I prefer the latter, because it pairs nicely with “procedural macros.” It seems like most agree with me. We’ll see.&lt;/p&gt;
&lt;p&gt;These macros are an incremental improvement over the existing &lt;code&gt;macro_rules!&lt;/code&gt; macros: they’re fundamentally the same thing, but with some nicer features.&lt;/p&gt;
&lt;p&gt;At the time of this writing, &lt;a href=&quot;https://github.com/rust-lang/rfcs/pull/1584&quot;&gt;an initial RFC is in FCP&lt;/a&gt;, laying out some high-level aspects of this feature. An initial implementation is underway, but it hasn’t landed yet, so you can’t use &lt;code&gt;macro&lt;/code&gt; in real code yet.&lt;/p&gt;
&lt;h2 id=&quot;procedural-macros&quot;&gt;Procedural Macros&lt;/h2&gt;
&lt;p&gt;In opposition to the pattern-based declarative macros, the second form are called “procedural macros” because they’re functions: they accept some Rust code as an input, and produce some Rust code as an output. I say “code” but I don’t mean that literally; we’ll get into the exact details in each section.&lt;/p&gt;
&lt;h3 id=&quot;syntax-extensions&quot;&gt;Syntax Extensions&lt;/h3&gt;
&lt;p&gt;Syntax extensions, also sometimes just called “procedural macros” or “compiler plugins”, were not stabilized for Rust 1.0. Here’s (part of) a syntax extension that implements roman numeral literals:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;#![feature(plugin_registrar, rustc_private)]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;extern crate syntax;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;extern crate rustc;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;extern crate rustc_plugin;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;use syntax::parse::token;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;use syntax::tokenstream::TokenTree;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;use syntax::ext::base::ExtCtxt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;use rustc_plugin::Registry;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;fn expand_rn(cx: &amp;#x26;mut ExtCtxt, sp: Span, args: &amp;#x26;[TokenTree])&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        -&gt; Box&amp;#x3C;MacResult + &apos;static&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    // implementation goes here&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;#[plugin_registrar]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;pub fn plugin_registrar(reg: &amp;#x26;mut Registry) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    reg.register_macro(&quot;rn&quot;, expand_rn);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You’d use it like this:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;#![feature(plugin)]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;#![plugin(roman_numerals)]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;fn main() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    assert_eq!(rn!(MMXV), 2015);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That is… a lot of code. And frankly, probably doesn’t even work on today’s Rust right now. Why not? Well, that’s the big problem with syntax extensions:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;extern crate syntax;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;extern crate rustc;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;extern crate rustc_plugin;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This literally loads up bits of the Rust compiler and uses it as a library. Then, it uses Rust’s internal AST to do the processing. This is extremely powerful, but also extremely unstable. We don’t and can’t freeze Rust’s internal AST, or any of its other internal APIs, at least not at this time. Not to mention that this means any alternative Rust compiler would need to either use our AST or map ours to theirs, which puts a damper on alternative Rust implementations. This means that syntax extensions haven’t had a good path towards stability. It’s also why they couldn’t be made stable as-of Rust 1.0. But “run arbitrary Rust code to produce more Rust code” is a useful feature, and so, some projects needed them. In addition, while declarative macros can produce function-style &lt;code&gt;foo!&lt;/code&gt; calls, they cannot do the custom attribute stuff. And those are very useful. We &lt;em&gt;could&lt;/em&gt; make this work, but there hasn’t been a real reason to, nor much demand.&lt;/p&gt;
&lt;p&gt;A side note: there’s also the term “compiler plugin.” Syntax extensions are a particular kind of compiler plugin; there are others, like lint passes, LLVM pass plugins, MIR plugins… we’re only talking about syntax extensions in this post, however.&lt;/p&gt;
&lt;p&gt;The current plan is to never stabilize syntax extensions, and instead, stabilize “procedural macros.” Again, this isn’t for all compiler plugins, only syntax extensions.&lt;/p&gt;
&lt;h3 id=&quot;procedural-macros-1&quot;&gt;Procedural Macros&lt;/h3&gt;
&lt;p&gt;Accepted in &lt;a href=&quot;https://github.com/rust-lang/rfcs/blob/master/text/1566-proc-macros.md&quot;&gt;RFC 1566&lt;/a&gt;, procedural macros will give you the same power as compiler plugins, without needing to reach into the guts of &lt;code&gt;rustc&lt;/code&gt;. How? Well, they look like this:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;#[proc_macro]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;pub fn foo(TokenStream) -&gt; TokenStream {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    // do stuff to implement the foo macro&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This creates a &lt;code&gt;foo!&lt;/code&gt; procedural macro. You’ll note that it accepts a &lt;code&gt;TokenStream&lt;/code&gt; and produces a &lt;code&gt;TokenStream&lt;/code&gt;. To quote the RFC:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The first argument is the tokens between the delimiters in the macro use. For example in foo!(a, b, c), the first argument would be [Ident(a), Comma, Ident(b), Comma, Ident(c)].The value returned replaces the macro use.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Why tokens? Well, while an AST can change, the actual tokens will not. This approach will allow us the flexibility to change &lt;code&gt;rustc&lt;/code&gt;’s internal AST, while giving us the full power of compiler plugins.&lt;/p&gt;
&lt;p&gt;So, how do you work with one of these kinds of macros? You can of course work with the token stream directly, but we also expect to see libraries that will provide easier-to-use interfaces on top of this. You could imagine a package that converts a &lt;code&gt;TokenStream&lt;/code&gt; to its own AST, and then provides an interface to that AST. This is nicer to use than working with tokens directly. There are already some libraries that do similar kinds of things, like &lt;a href=&quot;https://github.com/dtolnay/syn&quot;&gt;syn&lt;/a&gt;. More on that in a moment.&lt;/p&gt;
&lt;h3 id=&quot;function-like-vs-attribute-like&quot;&gt;Function-like vs attribute like&lt;/h3&gt;
&lt;p&gt;The above is for a macro that gives you a &lt;code&gt;foo!&lt;/code&gt; macro, that is, one that looks like a function. What about one that gives you an attribute? That’d look like this:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;#[proc_macro_attribute]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;pub fn foo(Option&amp;#x3C;TokenStream&gt;, TokenStream) -&gt; TokenStream {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    // implementation goes here&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To quote the RFC:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The first argument is a list of the tokens between the delimiters in the macro use. Examples:#[foo] =&gt; None#[foo()] =&gt; Some([])#[foo(a, b, c)] =&gt; Some([Ident(a), Comma, Ident(b), Comma, Ident(c)])The second argument is the tokens for the AST node the attribute is placed on.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Internally, it’s the same thing: use a &lt;code&gt;TokenStream&lt;/code&gt;, produce a &lt;code&gt;TokenStream&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id=&quot;macros-11&quot;&gt;“Macros 1.1”&lt;/h3&gt;
&lt;p&gt;You may have also heard a lot of commotion about “Macros 1.1.” In fact, they will be stable as of the next release of Rust, 1.15. Macros 1.1 are the &lt;a href=&quot;https://en.wikipedia.org/wiki/Pareto_principle&quot;&gt;Pareto principle&lt;/a&gt; applied to procedural macros: as it turns out, the vast majority of people who use procedural macros today use it for “custom derive”, that is, the ability to say &lt;code&gt;#[derive(MyTrait)]&lt;/code&gt; and implement a trait automatically. As such, a plan was hatched: we could stabilize &lt;em&gt;just the very very very basics&lt;/em&gt; of procedural macros, enough to get the ability to write custom derives, and stabilize that, without needing to implement everything. What does that look like? Here’s one that implements &lt;code&gt;#[derive(Double)]&lt;/code&gt;&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;extern crate proc_macro;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;use proc_macro::TokenStream;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;#[proc_macro_derive(Double)]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;pub fn double(input: TokenStream) -&gt; TokenStream {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    let source = input.to_string();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    // Parse `source` for struct/enum declaration, and then build up some new&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    // source code representing a number of items in the implementation of&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    // the `Double` trait for the struct/enum in question.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    let source = derive_double(&amp;#x26;source);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    // Parse this back to a token stream and return it&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    source.parse().unwrap()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You’ll notice that this still looks like &lt;code&gt;TokenStream&lt;/code&gt; -&gt; &lt;code&gt;TokenStream&lt;/code&gt;, but there’s something more subtle here: &lt;code&gt;input.to_string()&lt;/code&gt;. That is, for Macros 1.1, &lt;code&gt;TokenStream&lt;/code&gt; has two methods; all it has is the ability to be converted to a string, with the original Rust code inside of it, and a &lt;code&gt;parse&lt;/code&gt; method, which can take a string of Rust code and produce another &lt;code&gt;TokenStream&lt;/code&gt;. What you do with that &lt;code&gt;String&lt;/code&gt; is your own business.&lt;/p&gt;
&lt;p&gt;What most people will do is use &lt;a href=&quot;https://github.com/dtolnay/syn&quot;&gt;syn&lt;/a&gt; to parse the Rust code, and &lt;a href=&quot;https://github.com/dtolnay/quote&quot;&gt;quote&lt;/a&gt; to generate Rust code from that. These libraries will make it feasible to build real-world custom derive code, without us needing to stabilize anything we don’t want to. Of course, once full procedural macros are implemented, it’s not likely that people will want to turn &lt;code&gt;TokenStream&lt;/code&gt;s into and parse &lt;code&gt;TokenStream&lt;/code&gt;s from strings, but it’s not &lt;em&gt;totally&lt;/em&gt; unheard of, and will be the tiniest wart. It’s worth it to move a significant chunk of the ecosystem onto the stable compiler.&lt;/p&gt;
&lt;p&gt;For more details, see &lt;a href=&quot;https://github.com/rust-lang/rfcs/blob/master/text/1681-macros-1.1.md&quot;&gt;RFC 1681&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&quot;macros-12-&quot;&gt;“Macros 1.2” ?&lt;/h3&gt;
&lt;p&gt;There’s also been some small talk about possibly doing a “macros 1.2”, that is, another step towards full procedural macros without needing the whole thing. This would be “procedural macros without hygiene”, though it’s still early days for this idea; there isn’t even an RFC yet. We’ll see if this happens. There’s still some controversy around this idea.&lt;/p&gt;</content:encoded></item><item><title>Announcing Rust Contributors</title><link>https://steveklabnik.com/writing/announcing-rust-contributors/</link><guid isPermaLink="true">https://steveklabnik.com/writing/announcing-rust-contributors/</guid><description>When I was working with Ruby on Rails, someone once sent me this link: http://contributors.rubyonrails.org/ In some ways, this link changed my life. You see, I respond really strongly to integers going upwards. I am a sucker for points, hits, whatever. That web page, however,…</description><pubDate>Thu, 12 Jan 2017 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;When I was working with Ruby on Rails, someone once sent me this link:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://contributors.rubyonrails.org/&quot;&gt;http://contributors.rubyonrails.org/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;In some ways, this link changed my life. You see, I respond &lt;em&gt;really&lt;/em&gt; strongly to integers going upwards. I am a sucker for points, hits, whatever. That web page, however, puts that integer towards something useful: open source contributions. It’s fairly well known that open source contribution is a long tail, but that’s also &lt;em&gt;perfect&lt;/em&gt; for this kind of gamification. One contribution, as of today, will put you in 2461th place. Your second? 1473! That’s almost a thousand places! Just &lt;em&gt;one&lt;/em&gt; more contribution puts you at number 1114. Still three hundred spots. Your forth commit will let you get in the top 900, #893. You get the idea. (I ended up at #47.)&lt;/p&gt;
&lt;p&gt;Today, I’m working on Rust. And one of the things that I do is write the release announcements, or at least, their first draft. And one of my favorite things to do is the last bit: thanking all of the people who have put in work toward this release. It’s one of my favorite things because I really do appreciate all of the patches, but also because I remember how hooked I was when people gave me a little bit of credit for my contribution. Thanking people is powerful.&lt;/p&gt;
&lt;p&gt;So to write those blog posts, I have to run some &lt;code&gt;git&lt;/code&gt; commands. And I always forget &lt;em&gt;exactly&lt;/em&gt; what I have to write, given our branching strategy. So I wrote a little &lt;code&gt;Rakefile&lt;/code&gt; almost a year ago that will generate a new post with the appropriate thank yous and statistics. But I never made it general enough; I have to tweak the numbers every release. It’s annoying. I’ve always wanted to fix it up. There’s one more way in which I don’t like this setup: we only thank people who contribute to &lt;code&gt;rust-lang/rust&lt;/code&gt;. Even those with a commit to Cargo don’t make it in there. It’s a historical artifact of the release process, but I don’t like it. We should be thanking those people too.&lt;/p&gt;
&lt;p&gt;While all of this has been rolling around in the back of my brain, I’ve been thinking about contributors.rubyonrails.org. I’ve said for a while I wanted it in Rust. So, over the last few days, I hacked one together.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://rust-contributors.herokuapp.com/&quot;&gt;https://rust-contributors.herokuapp.com/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Right now, it only replicates what we say in the blog posts. It doesn’t show commit counts, or order by it, or anything. But the foundation is there. Also, since this is a fun hack, I didn’t take too much care when writing it: there’s a number of low-hanging fruit kinds of things to do. I didn’t use a fancy web framework. I didn’t focus on refactoring relentlessly. I didn’t write any tests. The error handling is basically non-existent. I just knocked it out as fast as I can. But it’s a web app, written in Rust, and that’s fun.&lt;/p&gt;
&lt;p&gt;If you’d like to help me hack on this, head over to &lt;a href=&quot;https://github.com/steveklabnik/contributors&quot;&gt;https://github.com/steveklabnik/contributors&lt;/a&gt; and take a look at the issues. I’ve already identified a number of things, and if you do web work but have been meaning to mess with Rust, this might be a good chance to give it a shot.&lt;/p&gt;
&lt;p&gt;Thank you to everyone who submits patches to Rust; you’re all great, and I’m lucky to be able to work with you all.&lt;/p&gt;</content:encoded></item><item><title>Fire Mario not fire flowers</title><link>https://steveklabnik.com/writing/fire-mario-not-fire-flowers/</link><guid isPermaLink="true">https://steveklabnik.com/writing/fire-mario-not-fire-flowers/</guid><description>My post yesterday got a lot of great responses. Two of them are from people I greatly respect, Dave Herman and Graydon Hoare . You should go read those two posts; this one is in response to them. I’m going to respond to both at the same time by mixing them together. Graydon says:…</description><pubDate>Thu, 29 Dec 2016 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;/writing/rust-is-more-than-safety/&quot;&gt;My post yesterday&lt;/a&gt; got a lot of great responses. Two of them are from people I greatly respect, &lt;a href=&quot;https://thefeedbackloop.xyz/safety-is-rusts-fireflower/&quot;&gt;Dave Herman&lt;/a&gt; and &lt;a href=&quot;http://graydon2.dreamwidth.org/247406.html&quot;&gt;Graydon Hoare&lt;/a&gt;. You should go read those two posts; this one is in response to them. I’m going to respond to both at the same time by mixing them together.&lt;/p&gt;
&lt;p&gt;Graydon says:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Safety in the systems space is Rust’s raison d’être. Especially safe concurrency (or as Aaron put it, fearless concurrency). I do not know how else to put it.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;“Fearless concurrency” is a different way to put it! That is, to use Dave’s metaphor, “safety” is the fire flower. But “fearless concurrency” is Fire Mario. This is where I think Dave misses the mark slightly as well. I agree with his metaphor, but disagree with his conclusion.&lt;/p&gt;
&lt;p&gt;I’m not saying that we get rid of fire flowers. I’m saying that we focus on “Rust makes you Fire Mario,” not “Rust is made of fire flowers”, when talking to people about Rust.&lt;/p&gt;
&lt;p&gt;Dave also misses my mark slightly, but in a different way:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I don’t think the Rust community should worry about shying away from talking about safety, but I hope we all remember that it’s in service of something much more exciting: making more badass systems programmers!&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;We are so close here that it feels like nitpicking, but I think the difference is important. I think one of Rust’s greatest potentials, like Dave does, is bringing a ton of new people into systems programming. But my point is this: “memory safety without garbage collection” doesn’t speak to that &lt;em&gt;at all&lt;/em&gt;. That is, memory safety without garbage collection is the mechanism of how that’s accomplished, but it’s not the accomplishment itself. It’s the Fire Flower, not Fire Mario.&lt;/p&gt;
&lt;p&gt;I’d like to make sure we’re talking about being Fire Mario, rather than being Fire Flower enthusiasts.&lt;/p&gt;</content:encoded></item><item><title>Rust is more than safety</title><link>https://steveklabnik.com/writing/rust-is-more-than-safety/</link><guid isPermaLink="true">https://steveklabnik.com/writing/rust-is-more-than-safety/</guid><description>Rust is most well-known for its features around writing low-level code in a safer way than its predecessors. But it’s also a lot more than that. The Rust community is slowly evolving the way that we talk about Rust to people who haven’t yet given Rust a try, but it can take time.…</description><pubDate>Wed, 28 Dec 2016 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Rust is most well-known for its features around writing low-level code in a safer way than its predecessors. But it’s also a lot more than that. The Rust community is slowly evolving the way that we talk about Rust to people who haven’t yet given Rust a try, but it can take time. But how did we get here?&lt;/p&gt;
&lt;p&gt;In Rust’s initial release announcement, Graydon used a phrase that is amazing:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;[Rust is] Technology from the past come to save the future from itself&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;He goes on to elaborate a bit:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Many older languages [are] better than new ones. We keep forgetting already-learned lessons.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This is one of the many things that the “Rust” name evokes. Rust was not intended to be a cutting-edge PLT (programming language theory) research language. It was challenging an assumption that I think many of us hold dear: that “progress” means that things always get better. Reality is a bit more complex than that. Yes, we’ve improved on some things, but there are some older things that were actually “better” in some sense, but never quite made it for other reasons. I’ve always phrased this sentiment like this:&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;Let’s look at the initial release dates of some of the top programming languages:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;C: 1972&lt;/li&gt;
&lt;li&gt;C++: 1983&lt;/li&gt;
&lt;li&gt;C#: 2000&lt;/li&gt;
&lt;li&gt;Java: 1995&lt;/li&gt;
&lt;li&gt;JavaScript: 1995&lt;/li&gt;
&lt;li&gt;Python: 1991&lt;/li&gt;
&lt;li&gt;PHP: 1995&lt;/li&gt;
&lt;li&gt;Ruby: 1995&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The first thing you’ll notice is: what the hell were they putting in the water in 1995?&lt;/p&gt;
&lt;p&gt;The second is that, other than C# in 2000, 1995 or earlier is where most of our programming languages come from. Have we really not made any advancements significant enough in the last 20 years to have gotten people’s attention?&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;Now, there are a multitude of newer languages, and people do use them. And these languages have had more releases since then. But none of these languages has fundamentally changed. They’re all pretty much the same, but better. And specifically, you’ll notice that many of these languages are scripting or higher-level languages: if we restrict ourselves to “what most operating systems are programmed in”, we haven’t had a new generation of programming languages in thirty or forty years!&lt;/p&gt;
&lt;p&gt;PLT research and industry live in two different worlds. Industry is effectively using ancient PLT tech. There’s lots of &lt;em&gt;good&lt;/em&gt; reasons for this too, mind you. But if you’re looking to make a new hit programming language, you don’t actually have to be innovative in the PLT sense. You can take PLT tech from the 2005-2010 era and you’ll still be ten years ahead!&lt;/p&gt;
&lt;p&gt;So in some senses, this is what Rust is trying to do: not be a cutting-edge programming language in a PLT sense, but advance the industry by mining “older” research.&lt;/p&gt;
&lt;p&gt;However, plans don’t always work out the way you want to. &lt;a href=&quot;https://www.youtube.com/watch?v=79PSagCD_AY&quot;&gt;As Rust evolved&lt;/a&gt;, many of its original bits were thrown out, and replaced with new ones. Rust &lt;em&gt;has&lt;/em&gt; advanced a small bit of the universe in PLT with the ownership/borrowing system. Like most research, it’s built on top of older work. But that’s exciting!&lt;/p&gt;
&lt;p&gt;Another thing about the borrow checker is that it’s “unique” about Rust as well. So if someone asks you, “hey, what’s cool about Rust?”, it’s extremely tempting to answer with the thing that makes it most clearly different than other programming languages. And for some people, this pitch is compelling! But not for everyone…&lt;/p&gt;
&lt;h2 id=&quot;shifting-priorities&quot;&gt;Shifting priorities&lt;/h2&gt;
&lt;p&gt;Marketing is hard. But there’s one thing that I’ve learned about it that I think applies to Rust:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Your marketing should be focused on what problems your product solves for the consumer.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Rust’s marketing, historically, hasn’t been as good at this as it could have been. That is, we’ve been too focused on the details, and not enough on the big picture. We’ve been worried about what’s interesting in a PLT aspect, and not what problems Rust solves for users. I can think of two big examples where this has happened:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Rust is safer than C or C++. (“I never have problems with safety in the C++ code I write” is a common reply.)&lt;/li&gt;
&lt;li&gt;Rust is as low-level of a programming language as C! (“I never write C. Rust is not for me.”)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Both of these pitches for Rust focus on the &lt;em&gt;how&lt;/em&gt;, and not on the problem itself. And that means that sometimes people draw the opposite inference as to what you were intending with the pitch in the first place.&lt;/p&gt;
&lt;p&gt;I have some ideas on a better pitch for Rust, and I even had a draft of it here, but I’ve decided to delete it for now. Instead, I’d like to ask all of you who love Rust to give this some thought, and write your own blog posts about what problems Rust solves for you. I’ll edit this post and link to yours if you ask me to. I’ve seen several people do a good job at articulating this kind of thing before. And I’ll work on my own post as well, as a follow-up.&lt;/p&gt;
&lt;p&gt;Let’s figure out the best way to share our love of Rust with the rest of the programming world.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;Here’s some of the responses generated from this:&lt;/p&gt;
&lt;p&gt;I’ve written &lt;a href=&quot;/writing/fire-mario-not-fire-flowers/&quot;&gt;Fire Mario, not Fire Flowers&lt;/a&gt;, as a response to two responses to this post.&lt;/p&gt;
&lt;p&gt;The &lt;a href=&quot;https://www.reddit.com/r/rust/comments/5krhr0/rust_is_more_than_safety/&quot;&gt;/r/rust&lt;/a&gt;, &lt;a href=&quot;https://www.reddit.com/r/programming/comments/5krw7r/rust_is_more_than_safety/&quot;&gt;proggit&lt;/a&gt;, and &lt;a href=&quot;https://news.ycombinator.com/item?id=13272474&quot;&gt;orange website&lt;/a&gt; threads are full of good replies.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://medium.com/@Hisako1337/rust-in-2017-8f2b57a67d9b&quot;&gt;Rust in 2017&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://insanitybit.github.io/2016/12/28/why-rust-introduction&quot;&gt;Why Rust?&lt;/a&gt; and &lt;a href=&quot;https://insanitybit.github.io/2016/12/28/why-rust-sum-types&quot;&gt;Why Rust? Sum Types&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title>Four years with Rust</title><link>https://steveklabnik.com/writing/four-years-with-rust/</link><guid isPermaLink="true">https://steveklabnik.com/writing/four-years-with-rust/</guid><description>Today is four years since I first learned about the existence of Rust. I know this because Rust 0.5 was the first release I used. Rust has changed a lot in that time. For a brief overview of its history, watch this talk of mine . But for today, I thought it would be fun to check…</description><pubDate>Wed, 21 Dec 2016 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Today is four years since I first learned about the existence of Rust. I know this because Rust 0.5 was the first release I used. Rust has changed a lot in that time. For a brief overview of its history, &lt;a href=&quot;https://www.youtube.com/watch?v=79PSagCD_AY&quot;&gt;watch this talk of mine&lt;/a&gt;. But for today, I thought it would be fun to check out &lt;a href=&quot;https://mail.mozilla.org/pipermail/rust-dev/2012-December/002787.html&quot;&gt;the release announcement&lt;/a&gt; and see what’s the same, and what’s changed.&lt;/p&gt;
&lt;h2 id=&quot;rust-dev&quot;&gt;rust-dev&lt;/h2&gt;
&lt;p&gt;First up, the announcement itself. The &lt;a href=&quot;https://mail.mozilla.org/listinfo/rust-dev&quot;&gt;rust-dev mailing list&lt;/a&gt; used to be your one-stop shop for talking about Rust in a persistent form. But in &lt;a href=&quot;https://mail.mozilla.org/pipermail/rust-dev/2015-January/011558.html&quot;&gt;January of 2015&lt;/a&gt;, we decided to close it down. Why? Let’s see what Brian said at the time:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;You likely have already noticed, but traffic to rust-dev has decreased dramatically in recent months. This was a result of natural changes in project coordination at first, and then an intentional effort to phase out the list.In the beginning of the project there were only two places to talk about rust: #rust and rust-dev, and they served us well for all purposes for several years. As Rust grew though the coordination of the project moved to different venues, conversations were happening in a number of other places, and the purpose of rust-dev became less clear. At the same time there were also a number of heated and essentially unmoderatable discussions that caused many to lose faith in the effectiveness of the mailing list.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I love mailing lists, but I know I’m fairly unique in that. But they do have one big problem, which is that the tools for moderating them are extremely thin. You can pretty much ban someone, and that’s about it. No removing only certain posts, no cooldown periods, no shadow banning. While Rust has a generally positive reputation for community and moderation, that doesn’t mean things were always perfect. We learned some lessons the hard way.&lt;/p&gt;
&lt;p&gt;More than that, mailman represents something of the “old guard” of open source. People see it as a sign of something backwards. Very few people want even more email. The culture is changing. We recognized this, and decided to move to &lt;a href=&quot;http://www.discourse.org/&quot;&gt;Discourse&lt;/a&gt; instead. rust-dev was survived by two children, &lt;a href=&quot;http://users.rust-lang.org/&quot;&gt;users&lt;/a&gt; and &lt;a href=&quot;https://internals.rust-lang.org/&quot;&gt;internals&lt;/a&gt;. This created a clear split between “discussion about Rust” and “discussions about building Rust.” It’s still free/open source software, it has good moderation tools, and you can even have it send you email!&lt;/p&gt;
&lt;p&gt;We also don’t make release announcements on these forums; we do it on &lt;a href=&quot;https://blog.rust-lang.org/&quot;&gt;our blog&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Let’s dig into those notes!&lt;/p&gt;
&lt;h2 id=&quot;900-changes-numerous-bugfixes&quot;&gt;900 changes, numerous bugfixes&lt;/h2&gt;
&lt;p&gt;900 changes is a lot! At the time, Rust was on a roughly six-month release schedule, so that’s about five patches merged per day. Rust 1.14 &lt;a href=&quot;https://github.com/rust-lang/blog.rust-lang.org/pull/141&quot;&gt;will have&lt;/a&gt; 1230 patches over its six-week release cycle: that’s just over 29 per day. That’s a much, much higher velocity. And that only counts the main repository; we’ve since added many more, like &lt;a href=&quot;https://github.com/rust-lang/cargo/&quot;&gt;Cargo&lt;/a&gt; and &lt;a href=&quot;https://github.com/rust-lang/crates.io&quot;&gt;crates.io&lt;/a&gt;. This is actually something I’ve been worried about for a while now; we only credit people for commits to &lt;code&gt;rust-lang/rust&lt;/code&gt; in release announcements, basically due to this history, but there’s a lot more work that goes on here these days. I want &lt;a href=&quot;http://contributors.rubyonrails.org/&quot;&gt;Rails Contributors&lt;/a&gt;, but for the Rust project. Anyone want to work on it with me sometime?&lt;/p&gt;
&lt;h2 id=&quot;syntax-changes&quot;&gt;Syntax changes&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Removed &lt;code&gt;&amp;#x3C;-&lt;/code&gt; move operator&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Rust went through several iterations of “when do you move, when do you copy” over its lifetime. Today, that distinction is made between types that implement &lt;code&gt;Copy&lt;/code&gt; and ones that don’t. But older Rusts had various schemes. Given that this one was removed in the first version of Rust I used, I don’t &lt;em&gt;exactly&lt;/em&gt; remember this, but I think it was&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;x &amp;#x3C;- y; // move&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;x = y; // copy&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Rust also had this at one point in time, I believe:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;x = move y; // move&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;x = y; // copy&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We decided to unify the two syntactically for two reasons: one, the annotations felt like busywork, the compiler would tell you what to put if you got it wrong. Secondly, at least in today’s Rust, move and copy are identical operations, with the exception of what you can do with the older variable after the move. Sharing the syntax reinforces that.&lt;/p&gt;
&lt;p&gt;Niko’s blog has a lot of great history in it, and &lt;a href=&quot;http://smallcultfollowing.com/babysteps/blog/2012/10/01/moves-based-on-type/&quot;&gt;this topic is no exception&lt;/a&gt;.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Completed transition from &lt;code&gt;#fmt&lt;/code&gt; extension syntax to &lt;code&gt;fmt!&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Long ago, Rust had a “no keywords can have more than five letters” rule, and so many things were abbreviated. This particular extension lives on today, but with the longer name &lt;a href=&quot;https://doc.rust-lang.org/stable/std/macro.format.html&quot;&gt;format!&lt;/a&gt;.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Removed old fixed length vector syntax - &lt;code&gt;[T]/N&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Rust’s vector and array types, as we know them today, went through a &lt;em&gt;lot&lt;/em&gt; of internal iteration, across many axes. The moral equivalent of &lt;code&gt;[T]/N&lt;/code&gt; today is &lt;code&gt;[T; N]&lt;/code&gt;, but I’m sure there are/were lots of subtle differences between the two. I can’t quite remember.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;New token quasi-quoters, &lt;code&gt;quote_tokens!&lt;/code&gt;, &lt;code&gt;quote_expr!&lt;/code&gt;, etc.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These live on in some sense; they’re still not stable, so much so that they’re note even shown in the official docs. &lt;a href=&quot;https://manishearth.github.io/rust-internals-docs/syntax/ext/quote/index.html&quot;&gt;Manish hosts a copy though&lt;/a&gt;. These are tools for “syntax extensions”, Rust’s most powerful form of metaprogramming. A final design for them was &lt;a href=&quot;https://github.com/rust-lang/rfcs/pull/1566&quot;&gt;just accepted eight days ago&lt;/a&gt;, so it’ll be a while still before you see this on stable Rust.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Macros may now expand to items and statements&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I don’t know why macros couldn’t do this before, but they still can today, and it’s very useful.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;a.b()&lt;/code&gt; is always parsed as a method call, never as a field&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This is a fun edge case. Here’s the problem:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;struct Env&amp;#x3C;F: Fn(i32)&gt; {    f: F,}let e = Env { f: |i| println!(&quot;Hello, {}&quot;, i) };e.f(); // what does this do?&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;According to this entry, this would be a method call. In today’s Rust, this would be an error, you need to write &lt;code&gt;(e.f)();&lt;/code&gt; At least the error tells you exactly what to do!&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;error: no method named `f` found for type `Env&amp;#x3C;[closure@&amp;#x3C;anon&gt;:6:22: 6:50]&gt;` in the current scope&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt; --&gt; &amp;#x3C;anon&gt;:8:7&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  |&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;8 |     e.f(); // what does this do?&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  |       ^&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  |&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;note: use `(e.f)(...)` if you meant to call the function stored in the `f` field&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt; --&gt; &amp;#x3C;anon&gt;:8:7&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  |&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;8 |     e.f(); // what does this do?&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  |       ^&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Eq&lt;/code&gt; and &lt;code&gt;IterBytes&lt;/code&gt; implementations automatically generated with &lt;code&gt;#[deriving_eq]&lt;/code&gt; and &lt;code&gt;#[deriving_iter_bytes]&lt;/code&gt; respectively&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;We now have a more generic way to derive traits: &lt;code&gt;#[derive(Eq)]&lt;/code&gt;, for example. &lt;code&gt;Eq&lt;/code&gt; is still here today, but &lt;code&gt;IterBytes&lt;/code&gt; is not. I can’t recall exactly what it did.&lt;/p&gt;
&lt;p&gt;Today, the list of traits you can derive is still only blessed ones by the compiler, and it’s a huge cause of people using nightly today, for better ergonomics with libraries like &lt;a href=&quot;http://serde.rs/&quot;&gt;Serde&lt;/a&gt; and &lt;a href=&quot;http://diesel.rs/&quot;&gt;Diesel&lt;/a&gt;. But as of Rust 1.15, this restriction will be lifted, and one of the largest blockers of people using stable Rust will be eliminated! ???&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Removed the special crate language for &lt;code&gt;.rc&lt;/code&gt; files&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The moral equivalent of &lt;code&gt;.rc&lt;/code&gt; files today are &lt;code&gt;.crate&lt;/code&gt; files, which Cargo will upload to crates.io. But unlike in the 0.5 days, you almost never need to worry or think about them, since Cargo makes it Just Work (tm).&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Function arguments may consist of any irrefutable pattern&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This is true today, and is a little known fact! It works like this:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;struct Point {    x: i32,    y: i32,}fn takes_point(Point {x, y}: Point) {    println!(&quot;({}, {})&quot;, x, y);}fn main() {    let origin = Point { x: 0, y: 0 };    takes_point(origin);}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That is, arguments to functions are &lt;code&gt;PATTERN: TYPE&lt;/code&gt;, not &lt;code&gt;NAME: TYPE&lt;/code&gt;. Inside of &lt;code&gt;takes_point&lt;/code&gt;, &lt;code&gt;x&lt;/code&gt; and &lt;code&gt;y&lt;/code&gt; are in scope, rather than a whole point.&lt;/p&gt;
&lt;h2 id=&quot;semantic-changes&quot;&gt;Semantic changes&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;&amp;#x26;&lt;/code&gt; and &lt;code&gt;~&lt;/code&gt; pointers may point to objects&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Rust did have objects, long ago, but I thought they were removed at this point. This one is unclear to me.&lt;/p&gt;
&lt;p&gt;Worth mentioning that &lt;code&gt;~&lt;/code&gt; is &lt;code&gt;Box&amp;#x3C;T&gt;&lt;/code&gt; now, though. That’s a long story…&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Tuple structs - &lt;code&gt;struct Foo(Bar, Baz)&lt;/code&gt;. Replace newtype enums.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These are &lt;a href=&quot;https://doc.rust-lang.org/stable/book/structs.html#tuple-structs&quot;&gt;still in Rust today&lt;/a&gt;.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Enum variants may be structs&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This is true today:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;enum Foo {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    Variant { x: i32, y: i32 },&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;Destructors can be added to all nominal types via Drop trait&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This is &lt;a href=&quot;https://doc.rust-lang.org/stable/std/ops/trait.Drop.html&quot;&gt;still true&lt;/a&gt;!&lt;/p&gt;
&lt;p&gt;I think the “nominal” here is alluding to something older in Rust’s type system; we don’t make these kinds of distinctions today, as IIRC, all types are nominal. Not 100% sure.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Structs and nullary enum variants may be constants&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This is true today.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Values that cannot be implicitly copied are automatically moved without writing &lt;code&gt;move&lt;/code&gt; explicitly&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I alluded to this above with &lt;code&gt;&amp;#x3C;-&lt;/code&gt;.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;&amp;#x26;T&lt;/code&gt; may now be coerced to &lt;code&gt;*T&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;code&gt;*T&lt;/code&gt; is &lt;code&gt;*const T&lt;/code&gt; or &lt;code&gt;*mut T&lt;/code&gt; today, but this is still true:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;let x = &amp;#x26;5;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;let y: *const i32 = x;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;Coercions happen in &lt;code&gt;let&lt;/code&gt; statements as well as function calls&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;We’ve gone through many different iterations of “what coerces and what doesn’t” over the years; I actually expected the example with &lt;code&gt;*const i32&lt;/code&gt; above to require an &lt;code&gt;as&lt;/code&gt;.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;use&lt;/code&gt; statements now take crate-relative paths&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This is true today. I really like it, but a lot of people find it confusing. Basically, “use” always starts from the root of the crate. So&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;mod bar {    struct Foo;    mod baz {        use bar::Foo; // from the root        use super::Foo; // if you want to start from the parent        use self::super::Foo; // self makes it be relative. Not even sure if self + super works, but you get the idea.    }}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;The module and type namespaces have been merged so that static method names can be resolved under the trait in which they are declared&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Not sure on this one, it’s too in the weeds.&lt;/p&gt;
&lt;h2 id=&quot;improved-support-for-language-features&quot;&gt;Improved support for language features&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Trait inheritance works in many scenarios&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This has always been a bit of a misnomer, inheritance means:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;trait Foo: Bar {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If you implement &lt;code&gt;Foo&lt;/code&gt;, you must also implement &lt;code&gt;Bar&lt;/code&gt;. That’s it. This line makes me smile: “it works more often.”&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Support for explicit self arguments in methods - &lt;code&gt;self&lt;/code&gt;, &lt;code&gt;&amp;#x26;self&lt;/code&gt; &lt;code&gt;@self&lt;/code&gt;, and &lt;code&gt;~self&lt;/code&gt; all generally work as expected&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Today’s Rust doesn’t just support this; it’s required! However:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;self&lt;/code&gt; is still &lt;code&gt;self&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;#x26;self&lt;/code&gt; is still &lt;code&gt;&amp;#x26;self&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;@self&lt;/code&gt; is &lt;code&gt;Rc&amp;#x3C;self&gt;&lt;/code&gt;, sorta kinda.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;~self&lt;/code&gt; is &lt;code&gt;Box&amp;#x3C;self&gt;&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;code&gt;@self&lt;/code&gt; was supposed to be a garbage-collected type, but was never really more than refcounting.&lt;/p&gt;
&lt;p&gt;In addition, the last two don’t actually work like that: they would be &lt;code&gt;self: Rc&amp;#x3C;Self&gt;&lt;/code&gt; and &lt;code&gt;self: Box&amp;#x3C;self&gt;&lt;/code&gt;. The &lt;code&gt;Box&lt;/code&gt; version will compile today, but the &lt;code&gt;Rc&lt;/code&gt; version does not, because &lt;code&gt;Box&lt;/code&gt; is magical. Eventually this will be rectified.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Static methods work in more situations&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Another “yay more features work” line. :)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Experimental: Traits may declare default methods for impls to use&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This works today, and is very useful. Consider &lt;a href=&quot;https://doc.rust-lang.org/stable/std/iter/trait.Iterator.html&quot;&gt;Iterator&lt;/a&gt;: all of those methods have default implementations, so you only need to define &lt;code&gt;next()&lt;/code&gt;, and you get the rest automatically.&lt;/p&gt;
&lt;h2 id=&quot;libraries&quot;&gt;Libraries&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;New condition handling system in &lt;code&gt;core::condition&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Conditions were a Lisp way of handling errors that Rust supported for a while. They were really cool, but nobody really knew how to effectively use them, so they never got used, so they’re gone now.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Timsort added to &lt;code&gt;std::sort&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;code&gt;std::sort&lt;/code&gt; doesn’t exist anymore, though we do have &lt;a href=&quot;https://doc.rust-lang.org/stable/std/primitive.slice.html#method.sort&quot;&gt;a sort function on slices&lt;/a&gt;. We don’t declare it to have a particular algorithm, though we do say “This sort is stable and O(n log n) worst-case but allocates approximately 2 * n where n is the length of self.”&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/rust-lang/rust/pull/38192&quot;&gt;Recently it was improved a ton&lt;/a&gt;, by a first-time contributor, no less! Extremely well-done. In the PR, he explains the algorithm:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;However, if we take the main ideas from TimSort (intelligent merging strategy of sorted runs) and drop galloping, then we’ll have great performance on random inputs and it won’t be bad on partially sorted inputs either.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;code&gt;TimSort&lt;/code&gt; is still around, kicking.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;New priority queue, &lt;code&gt;std::priority_queue&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Today this is &lt;a href=&quot;https://doc.rust-lang.org/std/collections/binary_heap/&quot;&gt;std::collections::binary_heap&lt;/a&gt;.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Pipes for serializable types, `std::flatpipes’&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;No idea where this went.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Serialization overhauled to be trait-based&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This is true today. See the above comments about Serde, though. &lt;a href=&quot;https://crates.io/crates/rustc-serialize&quot;&gt;rustc-serialize&lt;/a&gt; got to cheat though, and the compiler understands &lt;code&gt;RustcEncodable&lt;/code&gt; and &lt;code&gt;RustcDecodable&lt;/code&gt;. Can’t wait for Rust 1.15.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Expanded &lt;code&gt;getopts&lt;/code&gt; definitions&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;We’ve &lt;a href=&quot;https://github.com/rust-lang-nursery/getopts&quot;&gt;moved &lt;code&gt;getopts&lt;/code&gt; out of tree&lt;/a&gt;, but it’s still there.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Moved futures to &lt;code&gt;std&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Hoo boy! I forgot that we used to have futures in the standard library. Futures are one of the hottest topics in Rust today. &lt;a href=&quot;https://github.com/tokio-rs&quot;&gt;Tokio&lt;/a&gt; is one of the most anticipated releases of all time in Rust world. For a taste, &lt;a href=&quot;https://www.youtube.com/watch?v=bcrzfivXpc4&quot;&gt;watch this talk&lt;/a&gt;. A little birdie told me that Tokio should have a &lt;code&gt;0.1&lt;/code&gt; release soon…&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;More functions are pure now&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Rust no longer has a notion of purity, though &lt;a href=&quot;https://github.com/rust-lang/rfcs/blob/master/text/0911-const-fn.md&quot;&gt;const fn&lt;/a&gt; (still unstable) sorta feels like it in some senses. For some history on purity in Rust, see &lt;a href=&quot;http://smallcultfollowing.com/babysteps/blog/2012/10/12/extending-the-definition-of-purity-in-rust/&quot;&gt;Niko’s blog&lt;/a&gt;, or &lt;a href=&quot;https://mail.mozilla.org/pipermail/rust-dev/2013-April/003926.html&quot;&gt;this explanation by Graydon on why it was removed&lt;/a&gt;.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;core::comm&lt;/code&gt; renamed to &lt;code&gt;oldcomm&lt;/code&gt;. Still deprecated&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Very, very long gone.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;rustdoc&lt;/code&gt; and &lt;code&gt;cargo&lt;/code&gt; are libraries now&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Rustdoc still exists, though not &lt;em&gt;really&lt;/em&gt; as a library. Cargo however, is not the cargo you’re thinking of. &lt;a href=&quot;https://github.com/rust-lang/rust-wiki-backup/blob/73816d6f888c24fb8115d78078a1601805cbecb5/Doc-using-cargo-to-manage-packages.md&quot;&gt;It’s a totally different one&lt;/a&gt;. Rust went through many iterations of package managers before coming up with today’s Cargo; there was also &lt;a href=&quot;https://github.com/rust-lang/rust/blob/3e39e3e80dcf726a96ec0fe778f96e2a9dde620b/doc/guide-rustpkg.md&quot;&gt;rustpkg&lt;/a&gt;, for example, which was &lt;em&gt;after&lt;/em&gt; the Cargo referenced here, but before the Cargo we’re using today.&lt;/p&gt;
&lt;h2 id=&quot;misc&quot;&gt;Misc&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Added a preliminary REPL, &lt;code&gt;rusti&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;We removed the repl from the tree, as it never &lt;em&gt;really&lt;/em&gt; worked, and was a maintenance nightmare. &lt;a href=&quot;https://github.com/murarth/rusti&quot;&gt;This one&lt;/a&gt; is the only one I know of today. Some people ask about one, but nobody has done the work to get a good one together yet. It’s tough!&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;License changed from MIT to dual MIT/APL2&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This is still true today, with no plans on changing.&lt;/p&gt;
&lt;h2 id=&quot;contributors-to-rust-05&quot;&gt;Contributors to Rust 0.5:&lt;/h2&gt;
&lt;p&gt;We had 41 people contribute to 0.5. 1.14 will have 144 contributors, and that’s around average for a release these days. Out of those 41 people, at a glance, I recognize the names of about 17 individuals, and roughly six of them are still involved with Rust and Servo today. What about the other eleven? Some were interns that got jobs at other places and can’t work on Rust anymore, some are contributors that left for various reasons, and then of course, there’s Graydon.&lt;/p&gt;
&lt;p&gt;I personally opened &lt;a href=&quot;https://github.com/rust-lang/rust/pull/4305&quot;&gt;my first pull request&lt;/a&gt; six days after discovering it. You’ll note this PR wasn’t merged due to a procedural issue: I sent it into the wrong branch! Today, GitHub lets you change this, but I had to &lt;a href=&quot;https://github.com/rust-lang/rust/pull/4308&quot;&gt;open a new PR instead&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;As I said in that PR:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I’ve just started using Rust, and I really like it. One of the things that makes Rust hard to use is its lack of documentation, which is obviously fine, given that Rust isn’t production-ready yet.I’d like to help change that.To get started, I’ve just modified this one little description in the rustdoc. If this works out, and you all like my changes, I’ll start working on more docs like this for the rest of core, and maybe the stdlib after that.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;You might say it did work out. I’m now &lt;a href=&quot;https://blog.rust-lang.org/2014/12/12/Core-Team.html&quot;&gt;on the core team&lt;/a&gt;, I’ve sent in 866 PRs since then, and that first patch landed in &lt;a href=&quot;https://mail.mozilla.org/pipermail/rust-dev/2013-April/003427.html&quot;&gt;Rust 0.6&lt;/a&gt;. Rust 0.10 is the only release since then that I’ve not gotten at least one patch into, and today, I write the release announcements.&lt;/p&gt;
&lt;p&gt;I hope you’ve enjoyed this little trip down memory lane! I’m still really loving Rust and its community. Here’s to many more years ?♥&lt;/p&gt;</content:encoded></item><item><title>What&apos;s new with &quot;The Rust Programming Language&quot;</title><link>https://steveklabnik.com/writing/whats-new-with-the-rust-programming-language/</link><guid isPermaLink="true">https://steveklabnik.com/writing/whats-new-with-the-rust-programming-language/</guid><description>It’s been a while since I’ve mentioned my work on “The Rust Programming Language”, and I wanted to give you all an update. Before we get into the news, though, I’d like to take a moment to reflect on where the book has been, and then we’ll talk about it’s future. I previously…</description><pubDate>Mon, 15 Aug 2016 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;It’s been a while since I’ve mentioned my work on “The Rust Programming Language”, and I wanted to give you all an update. Before we get into the news, though, I’d like to take a moment to reflect on where the book has been, and then we’ll talk about it’s future.&lt;/p&gt;
&lt;p&gt;I &lt;a href=&quot;/writing/rusts-documentation-is-about-to-drastically-improve/&quot;&gt;previously wrote about my history with Rust and docs&lt;/a&gt;. As I said back then:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;But my first area of focus will be on the area of Rust’s documentation that’s the most weak, and simultaneously the most important: the tutorial.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;“The tutorial” eventually turned into “The Rust Programming Language.” But there’s a funny thing about writing a book for a language that isn’t done yet: you don’t really know &lt;em&gt;how&lt;/em&gt; to write a good book on something that doesn’t exist, because, well, you haven’t played with it yourself. I could make decent guesses, given that Rust was evolving incrementally, but that’s still very different. I think “technical debt” is a great metaphor here: the evolution of the language meant that I had to keep up with the work of many, many people to try and update the documentation. Furthermore, since nobody had tried to learn Rust 1.0 yet, since it didn’t exist, I couldn’t write a book that would do an amazing job of teaching them, since I hadn’t used it either!&lt;/p&gt;
&lt;p&gt;In some ways, this mirrors the compiler itself, which accrued a &lt;em&gt;massive&lt;/em&gt; amount of technical debt until 1.0. And so, the story since 1.0 has largely about been paying off this debt; culminating in &lt;a href=&quot;https://blog.rust-lang.org/2016/04/19/MIR.html&quot;&gt;MIR&lt;/a&gt;. By the same token, since 1.0, a lot of people have read the book, and a lot of people have tried to learn Rust. I now know so much more about how people go about doing so, and so am much, much better situated to write something that’ll be great for them.&lt;/p&gt;
&lt;p&gt;And so, now that time has passed, re-writing the book is what I’ve been spending a lot of my time on. I’ve been mostly quiet about this work, since I’ve wanted to get a chunk finished before starting to talk about it, and so today is finally that day.&lt;/p&gt;
&lt;p&gt;Let’s talk about what’s going on with the book today.&lt;/p&gt;
&lt;h2 id=&quot;a-new-coauthor&quot;&gt;A new coauthor.&lt;/h2&gt;
&lt;p&gt;The first bit of news is something that I’ve been wanting to tell you all for a few weeks now, and is the bit that I’m most excited about: I’m bringing &lt;a href=&quot;https://twitter.com/carols10cents&quot;&gt;Carol (Nichols || Goulding)&lt;/a&gt; on as a coauthor. TRPL is an incredibly personal work for me, one that I’ve poured my life into over the last few years. Carol and I have been friends for a long time, and there’s nobody else I’d rather share an authorship with. Not only is Carol a friend, but she’s been doing Rust longer than most. You might know her from &lt;a href=&quot;https://github.com/carols10cents/rustlings&quot;&gt;Rustlings&lt;/a&gt;, or the &lt;a href=&quot;http://rust-belt-rust.com/&quot;&gt;Rust Belt Rust conference&lt;/a&gt;, or as a cofounder of &lt;a href=&quot;http://integer32.com/&quot;&gt;Integer32&lt;/a&gt;, the first Rust-focused consulting company. Carol knows her stuff, and I’m proud to have her name next time mine on the cover. The book will be far better through her influence.&lt;/p&gt;
&lt;h2 id=&quot;a-new-beginning&quot;&gt;A new beginning&lt;/h2&gt;
&lt;p&gt;One of Carols’ first tasks was taking a bunch of the stuff I’d already written and checking it out herself, making improvements. She’s taken the first six chapters of the book and whipped them into shape. Some of the content you might recognize from the first edition of TRPL, but much of it is brand-new.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://rust-lang.github.io/book/&quot;&gt;Read the first six chapters online&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/rust-lang/book&quot;&gt;Source and issue tracker&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;As an example of how much better this book is, can, and will be than the first edition, compare the &lt;a href=&quot;http://rust-lang.github.io/book/ch04-00-understanding-ownership.html&quot;&gt;Ownership chapter&lt;/a&gt; to &lt;a href=&quot;https://doc.rust-lang.org/stable/book/ownership.html&quot;&gt;the current one&lt;/a&gt; ( plus &lt;a href=&quot;https://doc.rust-lang.org/stable/book/references-and-borrowing.html&quot;&gt;borrowing&lt;/a&gt; ). Instead of an abstract set of rules, we took one of the biggest things facing a new Rustacean, strings, and used them as a way to make these concepts concrete.&lt;/p&gt;
&lt;p&gt;If you have the time, please check it out, and file issues with any suggestions!&lt;/p&gt;
&lt;h2 id=&quot;more-to-come&quot;&gt;More to come&lt;/h2&gt;
&lt;p&gt;If you’d like to see chapters as we work on them, just follow the repo: everything is open source. Initial PRs are already up for the start of the next three chapters, and hopefully we’ll get them merged and move forward soon. I’m really proud of how the book is shaping up, and hope you enjoy it too.&lt;/p&gt;</content:encoded></item><item><title>Structure literals vs. constructors in Rust</title><link>https://steveklabnik.com/writing/structure-literals-vs-constructors-in-rust/</link><guid isPermaLink="true">https://steveklabnik.com/writing/structure-literals-vs-constructors-in-rust/</guid><description>Learning the basics of a language and its syntax is easy. Learning how all those bits fit together is a bit harder. There’s a neat intersection between three of Rust’s features that I’ve seen people use, but never seen written down. I was explaining this technique to someone in…</description><pubDate>Tue, 26 Jul 2016 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Learning the basics of a language and its syntax is easy. Learning how all those bits fit together is a bit harder. There’s a neat intersection between three of Rust’s features that I’ve seen people use, but never seen written down. I was explaining this technique to someone in &lt;code&gt;#rust-beginners&lt;/code&gt; the other day, and thought I’d write it down in case it helps you, too.&lt;/p&gt;
&lt;p&gt;A small review: If you have a &lt;code&gt;struct&lt;/code&gt; in Rust, like this:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;struct Point {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    x: i32,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    y: i32,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You can use ‘&lt;code&gt;struct&lt;/code&gt; literal syntax’ to create a new instance of the &lt;code&gt;struct&lt;/code&gt;:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;let origin = Point { x: 0, y: 0 };&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;However, this syntax only works if you have the proper access to the &lt;code&gt;struct&lt;/code&gt; and its members via Rust’s privacy rules.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;mod foo {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    pub struct Point {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        x: i32,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        y: i32,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    pub fn foo(x: i32, y: i32) -&gt; Point {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        Point { x: x, y: y } // this is fine, as we&apos;re in the same module&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;fn main() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    let origin = foo::Point { x: 0, y: 0 }; // this is not fine&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We can’t use &lt;code&gt;struct&lt;/code&gt; literal synatx in &lt;code&gt;main&lt;/code&gt; because &lt;code&gt;x&lt;/code&gt; and &lt;code&gt;y&lt;/code&gt; are also not public. But within the same module, we have access, so it works. So how would we let &lt;code&gt;main&lt;/code&gt; instantiate a &lt;code&gt;Point&lt;/code&gt; if we can’t use the literal syntax? Well, our &lt;code&gt;foo&lt;/code&gt; function does this, so we could expose it. More conventionally, we’d make it an associated function and call it &lt;code&gt;new&lt;/code&gt;:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;mod foo {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    pub struct Point {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        x: i32,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        y: i32,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    impl Point {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        pub fn new(x: i32, y: i32) -&gt; Point {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            Point { x: x, y: y } // this is fine, as we&apos;re in the same module&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;fn main() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    let origin = foo::Point::new(0, 0);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Great. But what if we wanted &lt;code&gt;x&lt;/code&gt; and &lt;code&gt;y&lt;/code&gt; to be public for some reason, yet we still wanted to force people to use the &lt;code&gt;new&lt;/code&gt; function to create &lt;code&gt;Point&lt;/code&gt;s? Maybe the initial creation does some sort of side effect that’s important. If we changed our code to this:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;mod foo {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    pub struct Point {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        pub x: i32,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        pub y: i32,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    impl Point {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        pub fn new(x: i32, y: i32) -&gt; Point {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            Point { x: x, y: y } // this is fine, as we&apos;re in the same module&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;fn main() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    let origin = foo::Point::new(0, 0);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    // but so does this:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    let origin = foo::Point { x: 0, y: 0 };&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;By making all of the elements of &lt;code&gt;Point&lt;/code&gt; public, we’ve re-enabled the literal syntax, which isn’t what we wanted. So what do we do?&lt;/p&gt;
&lt;p&gt;Fixing this requires two insights. The first is “zero-sized types”. In Rust, certain types only have values that don’t require any storage. Take, for example, &lt;code&gt;()&lt;/code&gt;, the “unit” type. It only has one possible value, also &lt;code&gt;()&lt;/code&gt;. Since it only has one value, there’s no need to actually store anything in memory to represent &lt;code&gt;()&lt;/code&gt;; if we have a valid value, we already know what it is. That means that once we compile down to actual assembly, &lt;code&gt;()&lt;/code&gt; just goes away entirely. So we can do this:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;mod foo {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    pub struct Point {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        pub x: i32,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        pub y: i32,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        _secret: (),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    impl Point {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        pub fn new(x: i32, y: i32) -&gt; Point {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            Point { x: x, y: y, _secret: () }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;fn main() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    let origin = foo::Point::new(0, 0);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, we have a new, non-public field, &lt;code&gt;_secret&lt;/code&gt;. I’ve given it a name that starts with an underscore because we don’t intend to use it for anything, and so Rust won’t warn us about it. &lt;code&gt;_secret&lt;/code&gt; has the type of &lt;code&gt;()&lt;/code&gt;, and so it’s entirely a compile-time construct; it doesn’t materially affect &lt;code&gt;Point&lt;/code&gt;’s representation. But it being private &lt;em&gt;does&lt;/em&gt; affect how we’re allowed to construct our &lt;code&gt;Point&lt;/code&gt;s. &lt;code&gt;main&lt;/code&gt; can no longer use the &lt;code&gt;struct&lt;/code&gt; literal syntax, since not all of the fields are public.&lt;/p&gt;
&lt;p&gt;However, remember that privacy is a module-level thing in Rust. Therefore, we can still use the &lt;code&gt;struct&lt;/code&gt; literal syntax inside of the &lt;code&gt;foo&lt;/code&gt; module:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;mod foo {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    pub struct Point {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        pub x: i32,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        pub y: i32,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        _secret: (),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    impl Point {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        pub fn new(x: i32, y: i32) -&gt; Point {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            Point { x: x, y: y, _secret: () }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    fn foo() -&gt; Point {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        Point: { x: 0, y: 0, _secret: () } // this is still allowed!&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;fn main() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    let origin = foo::Point::new(0, 0);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To prevent &lt;code&gt;foo&lt;/code&gt; from being able to use the literal syntax, we need one more concept: &lt;code&gt;pub use&lt;/code&gt;. Check this out:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;mod foo {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    mod point {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        pub struct Point {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            pub x: i32,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            pub y: i32,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            _secret: (),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        impl Point {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            pub fn new(x: i32, y: i32) -&gt; Point {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                Point { x: x, y: y, _secret: () }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    pub use foo::point::Point;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    fn foo() -&gt; Point {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        Point::new(0, 0) // must use `new` here, as we&apos;re no longer in the same module!&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;fn main() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    let origin = foo::Point::new(0, 0);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;By giving &lt;code&gt;Point&lt;/code&gt; its own module, everything that’s private to it is private. But typing &lt;code&gt;foo::point::Point&lt;/code&gt; would be redundant and an ergonomic regression; &lt;code&gt;pub use&lt;/code&gt; saves the day! We re-export the &lt;code&gt;Point&lt;/code&gt; structure into &lt;code&gt;foo&lt;/code&gt;, so we can still use &lt;code&gt;foo::Point&lt;/code&gt;, but since one of its members is private, literal syntax isn’t allowed.&lt;/p&gt;
&lt;p&gt;To me, understanding things like this is when I really start to feel like I’m getting to know a language: putting three or four disparate concepts together to achieve some goal. It’s when a language stops being a bunch of disjoint parts and starts becoming a cohesive whole.&lt;/p&gt;</content:encoded></item><item><title>&quot;The Rust Programming Language&quot; will be published by No Starch Press</title><link>https://steveklabnik.com/writing/the-rust-programming-language-will-be-published-by-no-starch-press/</link><guid isPermaLink="true">https://steveklabnik.com/writing/the-rust-programming-language-will-be-published-by-no-starch-press/</guid><description>I’m happy to bring you some news: “The Rust Programming Language” is going to be published, in physical form, by No Starch Press . I am really excited to work with No Starch on this: they’ve published some of my favorite programming books, like “If Hemingway Wrote JavaScript” ,…</description><pubDate>Tue, 08 Sep 2015 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I’m happy to bring you some news: &lt;a href=&quot;http://doc.rust-lang.org/stable/book/&quot;&gt;“The Rust Programming Language”&lt;/a&gt; is going to be published, in physical form, by &lt;a href=&quot;https://www.nostarch.com/&quot;&gt;No Starch Press&lt;/a&gt;. I am really excited to work with No Starch on this: they’ve published some of my favorite programming books, like &lt;a href=&quot;https://www.nostarch.com/hemingway&quot;&gt;“If Hemingway Wrote JavaScript”&lt;/a&gt;, &lt;a href=&quot;https://www.nostarch.com/rum&quot;&gt;“Ruby Under a Microscope”&lt;/a&gt;, and &lt;a href=&quot;https://www.nostarch.com/rubywizardry&quot;&gt;“Ruby Wizardry”&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Another reason I’m keen to work with No Starch on this is that they believe in publishing freely available material: we’re going to take the existing manuscript, whip it into shape, make a nice paper book out of it, and merge the changes back into the official documentation. So the improvements will get back to everyone, even those who can’t afford a physical copy.&lt;/p&gt;
&lt;p&gt;The authorship credit is to “The Rust Project Developers,” as other people have contributed significantly: we even have an &lt;a href=&quot;https://github.com/rust-lang/rust/pull/28301&quot;&gt;active PR to re-write an entire chapter&lt;/a&gt;. Rust is a team effort.&lt;/p&gt;
&lt;p&gt;Oh, and one last thing: the profit from the book won’t go to me, it will go to &lt;a href=&quot;http://openhatch.org/&quot;&gt;OpenHatch&lt;/a&gt;, “a non-profit dedicated to matching prospective free software contributors with communities, tools, and education,” to use their words about it.&lt;/p&gt;
&lt;p&gt;I’ll let you know when we’re closer to actually shipping!&lt;/p&gt;</content:encoded></item><item><title>Community Versions for Rust</title><link>https://steveklabnik.com/writing/community-versions-for-rust/</link><guid isPermaLink="true">https://steveklabnik.com/writing/community-versions-for-rust/</guid><description>Rust has been through a lot of changes in recent years. As such, tutorials get out of date. We’ve occasionally said that including rustc -v in your blog posts would be helpful, but today, I saw this tweet go by: Tired of guessing what versions of Ember work with a given blog…</description><pubDate>Sun, 23 Aug 2015 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;http://www.rust-lang.org/&quot;&gt;Rust&lt;/a&gt; has been through a &lt;em&gt;lot&lt;/em&gt; of changes in recent years. As such, tutorials get out of date. We’ve occasionally said that including &lt;code&gt;rustc -v&lt;/code&gt; in your blog posts would be helpful, but today, I saw this tweet go by:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Tired of guessing what versions of Ember work with a given blog post? Check out &lt;a href=&quot;http://t.co/6joJiNdJQ5&quot;&gt;http://t.co/6joJiNdJQ5&lt;/a&gt; #feedbackplz pic.twitter.com/YToBduBVtx
— mixonic (@mixonic) August 23, 2015&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;After some quick hacking, I’ve modified it to work with Rust. You can find the project here: &lt;a href=&quot;https://github.com/steveklabnik/rust-community-versions&quot;&gt;https://github.com/steveklabnik/rust-community-versions&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;TL;DR: Put this into your blog post, substituting the appropriate date and title:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&amp;#x3C;iframe&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  width=&quot;178&quot; height=&quot;24&quot; style=&quot;border:0px&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  src=&quot;http://steveklabnik.github.io/rust-community-versions/2013/10/18/pointers-in-rust-a-guide.html&quot;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&amp;#x3C;/iframe&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then, make a &lt;a href=&quot;https://github.com/steveklabnik/rust-community-versions/pulls&quot;&gt;pull request&lt;/a&gt; adding a new post with some front-matter:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;---&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;layout: post&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;url: /writing/pointers-in-rust-a-guide/&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;title: &quot;Pointers in Rust: a Guide&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;date: 2013-10-18&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;start_version: 0.8&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;end_version: 0.9&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;---&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;(&lt;code&gt;end_version&lt;/code&gt; is optional)&lt;/p&gt;
&lt;p&gt;And bam! You get a nice looking badge. Check out out on this blog post of mine: /writing/pointers-in-rust-a-guide/&lt;/p&gt;
&lt;p&gt;What’s nice about this approach is that, if your post ever gets out of date, someone else can modify the YAML in the repo, and your badge will automatically update to include the end date. No remembering to go back and fix it.&lt;/p&gt;
&lt;p&gt;Let’s see how this goes!&lt;/p&gt;</content:encoded></item><item><title>A new introduction to Rust</title><link>https://steveklabnik.com/writing/a-new-introduction-to-rust/</link><guid isPermaLink="true">https://steveklabnik.com/writing/a-new-introduction-to-rust/</guid><description>Lately, I’ve been giving a lot of thought to first impressions of Rust. On May 15, we’re going to have a lot of them . And you only get one chance at a first impression. So I’ve been wondering if our Intro and Basics are putting our best foot forward. At first I thought yes, but…</description><pubDate>Fri, 27 Feb 2015 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Lately, I’ve been giving a lot of thought to first impressions of Rust. On May 15, &lt;a href=&quot;http://blog.rust-lang.org/2015/02/13/Final-1.0-timeline.html&quot;&gt;we’re going to have a lot of them&lt;/a&gt;. And you only get one chance at a first impression. So I’ve been wondering if our &lt;a href=&quot;http://doc.rust-lang.org/intro.html&quot;&gt;Intro&lt;/a&gt; and &lt;a href=&quot;http://doc.rust-lang.org/book/basic.html&quot;&gt;Basics&lt;/a&gt; are putting our best foot forward. At first I thought yes, but a few days ago, I had an idea, and it’s making me doubt it, maybe. So instead of re-writing all of our introductory material, I’m just going to write the first bit. A spike, if you will. And I’d like to hear what you think about it. This would take the same place as &lt;a href=&quot;http://doc.rust-lang.org/book/variable-bindings.html&quot;&gt;2.4: Variable bindings&lt;/a&gt; in the existing structure: They’ve installed Rust and gotten Hello World working.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;$ rustc --version&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;rustc 1.0.0-dev (dcc6ce2c7 2015-02-22) (built 2015-02-22)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;hello-ownership&quot;&gt;Hello, Ownership&lt;/h2&gt;
&lt;p&gt;Let’s learn more about Rust’s central concept: ownership. Along the way, we’ll learn more about its syntax, too. Here’s the program we’re going to talk about:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;fn main() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    let x = 5;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This small snippit is enough to start with. First up: &lt;code&gt;let&lt;/code&gt;. A &lt;code&gt;let&lt;/code&gt; statement introduces a &lt;strong&gt;variable binding&lt;/strong&gt;. Bindings allow you to associate a name with some sort of value.&lt;/p&gt;
&lt;p&gt;Why ‘variable binding’? Rust draws heavily from both systems languages and functional programming languages. The name “variable binding” is a great example of this. Many systems languages let you declare a variable. These variables are called by that name because they can change over time, they’re mutable. Many functional languages let you declare bindings. These bindings are called by that name because they bind a name to a value, and don’t change over time. They’re immutable.&lt;/p&gt;
&lt;p&gt;Rust’s variable bindings are immutable by default, but can become mutable, allowing them to be re-bound to something else. In other words,&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;fn main() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    let x = 5;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    x = 6; // error: re-assignment of immutable variable&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    let mut y = 5;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    y = 6; // just fine&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You won’t be typing &lt;code&gt;mut&lt;/code&gt; that often.&lt;/p&gt;
&lt;p&gt;In any case, there’s one way in which &lt;code&gt;let&lt;/code&gt; bindings work just like variables in other languages, but they’re the key insight into ownership. As you know, a computer program is executed line by line. At least, until you hit a control flow structure, anyway. Let’s give our program line numbers, so we can talk about it.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;// 1&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;fn main() {    // 2&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;               // 3&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    let x = 5; // 4&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;               // 5&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}              // 6&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;               // 7&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Line one is before our program starts. The endless void. Not actually endless, though, as line two is where we start &lt;code&gt;main&lt;/code&gt;. This is the first line that is actually executed, and kicks off our program. Great. Line three is blank, so nothing happens, just like one. Line four is where the first actually interesting thing occurs: we introduce a new variable binding, &lt;code&gt;x&lt;/code&gt;. We set &lt;code&gt;x&lt;/code&gt;’s initial value to five, allocated on the stack. If you don’t know what that means, we’ll talk about it right after ownership. For now, &lt;code&gt;x&lt;/code&gt; is five. No big deal. Line six has a closing curly brace, and so &lt;code&gt;main&lt;/code&gt;, and thus, our program, is over. Line seven, the void returns.&lt;/p&gt;
&lt;p&gt;This is basically the same thing as many programming languages. But let’s point out an aspect you, as a programmer, probably take for granted. Scoping. If I asked you, “Is &lt;code&gt;x&lt;/code&gt; valid on line one?” you would say “no.” “Three? Seven?” “Nope, nada. &lt;code&gt;x&lt;/code&gt; is valid from line four, where it was declared, to line six, where it goes out of scope.” This illustrates the idea. There is a certain scope, a certain set of lines, where &lt;code&gt;x&lt;/code&gt; is a valid identifier. That scope starts from where it was declared, and goes until the end of the block. We can look at this scope in two ways: for the first, imagine this source code printed on a piece of paper. You highlight lines four three six. In some sense, this is a distance: three lines of code, rather than three meters. But if we imagine the computer running this program, this scope represents a time: three statements of processor execution. Even though that number is actually different based on the assembly, but at our level of abstraction, three units.&lt;/p&gt;
&lt;p&gt;In Rust, we have names for these concepts, which are implicit in other languages. The thing that introduces a new scope is called the ‘owner.’ It’s in charge of the data it’s bound to, so we say that it ‘owns’ that data. The length of a scope is called a ‘lifetime,’ taken from that idea of time passing as your program executes. But you can also think of it as a segment of lines of code.&lt;/p&gt;
&lt;p&gt;So if other programs do this, why does this make Rust special? Sure, Rust gives these concepts specific names, but names themselves aren’t significantly different. The difference is that Rust takes this concept and cranks it up to 11. Where most programming languages only keep track of how long variables are in scope, Rust knows how to connect the scopes of variables that are pointing to the same thing, as well as how to know the scope of things that are more than just stack-allocated memory.&lt;/p&gt;
&lt;p&gt;Let’s talk more about this connecting of scopes. Here’s another Rust program:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;fn main() {         // 1&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    let x = 5;      // 2&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                    // 3&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    {               // 4&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                    // 5&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        let y = &amp;#x26;x; // 6&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                    // 7&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    }               // 8&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                    // 9&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}                   // 10&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In line four, we use an open curly brace to create a new scope. This scope, like in many languages needs to be closed before the scope of &lt;code&gt;main&lt;/code&gt; gets closed. It’s nested inside of it.&lt;/p&gt;
&lt;p&gt;In this new scope, on line six, we declare a new binding, &lt;code&gt;y&lt;/code&gt;, and we set it equal to &lt;code&gt;&amp;#x26;x&lt;/code&gt;. This reads as “a reference to &lt;code&gt;x&lt;/code&gt;,” as &lt;code&gt;&amp;#x26;&lt;/code&gt; is the reference operator in Rust. References are Rust’s version of ‘pointers’ from other systems programming languages. Here’s a quick introduction, if you haven’t had to deal with pointers before.&lt;/p&gt;
&lt;p&gt;By default, in Rust, data is allocated on “the stack.” Your program is given a chunk of memory, and it’s able to allocate information there. The stack starts at the bottom address of memory, and then grows upwards. For example, at the start of our program, the stack has nothing in it:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;A%20new%20introduction%20to%20Rust%204bbc792c85e141fb81570865cbbe2f87/Untitled%20Database%20e35b5948ec7546b7a905f4db1ea869c6.csv&quot;&gt;Untitled&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;At line2, we introduce &lt;code&gt;x&lt;/code&gt;, and it stack-allocates the number five, like this:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;A%20new%20introduction%20to%20Rust%204bbc792c85e141fb81570865cbbe2f87/Untitled%20Database%20935c84280787447b8fefcaaefb4575c0.csv&quot;&gt;Untitled&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;We’ve got an address in memory, the value at that address, and the name we’ve used in our program. It starts at the bottom because remember, the stack grows upward. Finally,on line six, we have &lt;code&gt;y&lt;/code&gt;:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;A%20new%20introduction%20to%20Rust%204bbc792c85e141fb81570865cbbe2f87/Untitled%20Database%20f7b25102df1d41e884fdac5b761fe567.csv&quot;&gt;Untitled&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Instead of being a value itself, &lt;code&gt;y&lt;/code&gt; is a pointer to another location in memory, which holds a value. Because &lt;code&gt;y = &amp;#x26;x&lt;/code&gt;, we take the memory location of &lt;code&gt;x&lt;/code&gt; and store it into &lt;code&gt;y&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;On line eight, the inner scope ends, and &lt;code&gt;y&lt;/code&gt; goes out of scope. Its lifetime is over. It gets deallocated. Our memory is back to this:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;A%20new%20introduction%20to%20Rust%204bbc792c85e141fb81570865cbbe2f87/Untitled%20Database%20daa49962f5c5408d82e28e9e3e073be7.csv&quot;&gt;Untitled&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Finally, on line ten, our program is over. &lt;code&gt;x&lt;/code&gt; goes out of scope, and we look like this:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;A%20new%20introduction%20to%20Rust%204bbc792c85e141fb81570865cbbe2f87/Untitled%20Database%2086c230f1a23e49d892a529d7988a272c.csv&quot;&gt;Untitled&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Everything is gone, all is well.&lt;/p&gt;
&lt;p&gt;Pointers can point other places than the stack: they can also point to ‘the heap.’ The heap starts at the top of your program’s memory, and grows down:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;A%20new%20introduction%20to%20Rust%204bbc792c85e141fb81570865cbbe2f87/Untitled%20Database%20007add295d434d84a281a93e7358f0d5.csv&quot;&gt;Untitled&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The heap starts at &lt;code&gt;0x00&lt;/code&gt; and grows down, and the stack starts at &lt;code&gt;0xff&lt;/code&gt; and grows up. While the stack contains the data that the programming language has allocated for our bindings, our program can request dynamic amounts of memory from the heap. Here’s how to do this in C:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;c&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;#include&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&amp;#x3C;stdio.h&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;#include&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&amp;#x3C;stdlib.h&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;int&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; main&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        int&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; *&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;x &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; malloc&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;sizeof&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;int&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;));&lt;/span&gt;&lt;span style=&quot;color:#6A737D&quot;&gt; // 1&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        *&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;x &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 5&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;                       // 2&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;                                      // 3&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;        printf&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;%i&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;*&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;x);&lt;/span&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;             // 4&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The call to &lt;code&gt;malloc&lt;/code&gt; (‘memory allocate’) on line 1 requests some memory from the heap. We get a pointer, &lt;code&gt;int *x&lt;/code&gt;, to that memory. Our memory looks like this:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;A%20new%20introduction%20to%20Rust%204bbc792c85e141fb81570865cbbe2f87/Untitled%20Database%203e8198d0b0a5408bbcf399a9d682c779.csv&quot;&gt;Untitled&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;We have &lt;code&gt;x&lt;/code&gt;, which is a variable on the stack, as a pointer to our dynamically allocated memory, which is located on the heap at &lt;code&gt;0x00&lt;/code&gt;. But at that location, we haven’t done anything, so who knows what the value is? This means that after line one is done executing, &lt;code&gt;x&lt;/code&gt; will be pointing to garbage memory. Hopefully we set it equal to a value before we try to use it, or bad things could happen.&lt;/p&gt;
&lt;p&gt;On line two, we set that memory location to five. Whew! Memory looks like this:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;A%20new%20introduction%20to%20Rust%204bbc792c85e141fb81570865cbbe2f87/Untitled%20Database%20ccd2c85eb0a34f6483acdbfafa4c841a.csv&quot;&gt;Untitled&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Everything looks good. On line four, we have to print out &lt;code&gt;*x&lt;/code&gt;, not &lt;code&gt;x&lt;/code&gt;: &lt;code&gt;x&lt;/code&gt; is the address of the memory, so we’d get &lt;code&gt;0x00&lt;/code&gt; instead of &lt;code&gt;5&lt;/code&gt;. After line four, &lt;code&gt;x&lt;/code&gt; goes out of scope, and gets deallocated. Memory looks like this:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;A%20new%20introduction%20to%20Rust%204bbc792c85e141fb81570865cbbe2f87/Untitled%20Database%200aec19c2d6a645a3b860bf65cc922853.csv&quot;&gt;Untitled&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;… wait a minute, we never took care of that &lt;code&gt;5&lt;/code&gt;! We left some memory ‘dangling.’ In this program, that’s okay, because now that it’s over, the operating system reclaims all this memory, and so we don’t have any problems. But we &lt;em&gt;do&lt;/em&gt; have a bug. We just don’t know it. This bug will sit there until something changes, and the bug is found. But we’ll get to that.&lt;/p&gt;
&lt;p&gt;A slightly more responsible program looks like this:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;c&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;#include&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&amp;#x3C;stdio.h&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;#include&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&amp;#x3C;stdlib.h&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;int&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; main&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        int&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; *&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;x &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; malloc&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;sizeof&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;int&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;));&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        *&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;x &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 5&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;        printf&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;%i&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;*&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;x);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;        free&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(x);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The call to &lt;code&gt;free&lt;/code&gt; releases the memory pointed to by &lt;code&gt;x&lt;/code&gt;, and all is good.&lt;/p&gt;
&lt;p&gt;Let’s compare this to an equivalent Rust program:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;rust&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;fn&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; main&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    let&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; x &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; Box&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;new&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;5&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;    println!&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;{}&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, x);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It looks similar at first, with &lt;code&gt;Box::new&lt;/code&gt; filling in for &lt;code&gt;malloc&lt;/code&gt;, But where’s the free? Does this have the same bug?&lt;/p&gt;
&lt;p&gt;No. This Rust is in fact equivalent to the one with the &lt;code&gt;malloc&lt;/code&gt; and &lt;code&gt;free&lt;/code&gt;. You see, when we introduce our binding, &lt;code&gt;x&lt;/code&gt;, Rust knows that &lt;code&gt;x&lt;/code&gt; has ownership over the memory in the &lt;code&gt;Box&lt;/code&gt;. and so, at the end of the program, when &lt;code&gt;x&lt;/code&gt; goes out of scope, Rust also ensures to free the memory that the &lt;code&gt;Box&lt;/code&gt; allocated. It happens automatically. The programmer can’t forget it. And the allocation itself was a little easier, because Rust used the type system to figure out how many bytes to allocate, you didn’t need to calculate it with &lt;code&gt;sizeof&lt;/code&gt;. Allocation also set the value to 5 for you, which is convenient and less error-prone. When printing out &lt;code&gt;x&lt;/code&gt;, you could just use the binding name itself, and not need to dereference it with &lt;code&gt;*&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;C++ programmers have ways of doing this kind of thing, with something called “RAII.” As promised before, Rust knows this concept at a deeper, language level. So it can be safe in places that RAII cannot. Here’s an example, in C++:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;c&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;#include&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&amp;#x3C;iostream&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;#include&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&amp;#x3C;vector&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;#include&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&amp;#x3C;string&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;int&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; main&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    std::vector&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;std::string&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&gt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; v;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    v.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;push_back&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;a&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    std::string&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;#x26;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; x &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt; v&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;];&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    v.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;push_back&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;b&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    std::cout &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;#x3C;&amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; x;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This program creates a vector of strings, called &lt;code&gt;v&lt;/code&gt;:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;A%20new%20introduction%20to%20Rust%204bbc792c85e141fb81570865cbbe2f87/Untitled%20Database%20b1e4993d4fc14c9abbe2c2d7deb3be25.csv&quot;&gt;Untitled&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;v&lt;/code&gt; is a ‘fat pointer,’ three pointers in one. The first is a pointer to the data, the second is the length of the array, how many elements are in it. The third is the capacity of the array, how much memory is allocated for this vector. The amount of initial capacity is up to the implementation, I’ve chosen one here. Because this is a vector of strings, we need to allocate a single string, so in line with our capacity. Strings are also a fat pointer, and so we allocate three bytes, starting at &lt;code&gt;0x00&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The program then calls &lt;code&gt;push_back()&lt;/code&gt; on the vector, which pushes a string onto the end of the vector:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;A%20new%20introduction%20to%20Rust%204bbc792c85e141fb81570865cbbe2f87/Untitled%20Database%205c80884c8d7d4ae290de9e2b9caa1f11.csv&quot;&gt;Untitled&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;We’ve now replaced our initial, &lt;code&gt;GARBAGE&lt;/code&gt;, string with a real one. Therefore, our data, length, and capacity are updated: &lt;code&gt;0x03&lt;/code&gt; is the next free location in the heap, so it gets our signle character, &lt;code&gt;A&lt;/code&gt;. We have a length of one, and a capacity of one, so the other two values are set appropriately.&lt;/p&gt;
&lt;p&gt;Next, it creates a pointer to the &lt;code&gt;0&lt;/code&gt;th element of that vector:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;A%20new%20introduction%20to%20Rust%204bbc792c85e141fb81570865cbbe2f87/Untitled%20Database%2031184db665934f5ea7acaea0b98ce4b9.csv&quot;&gt;Untitled&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;x&lt;/code&gt; is allocated on the stack, and points to the first element of &lt;code&gt;v&lt;/code&gt;, which, as we know, is located at address &lt;code&gt;0x00&lt;/code&gt;, as its data pointer, &lt;code&gt;0xff&lt;/code&gt;, shows us. So &lt;code&gt;x&lt;/code&gt; has the initial value of &lt;code&gt;0x00&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Next is where everything goes wrong. It tries to push a string onto the end of that vector. The problem is, we only allocated one element. So we need to allocate more. After this is done, memory looks like this:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;A%20new%20introduction%20to%20Rust%204bbc792c85e141fb81570865cbbe2f87/Untitled%20Database%20900c132e9e144b1e94ffb6c47d5fc068.csv&quot;&gt;Untitled&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Inside &lt;code&gt;push_back()&lt;/code&gt;, there’s a call to &lt;code&gt;malloc&lt;/code&gt;, and that is assigned to some temporary value. We’ve chosen &lt;code&gt;0xfb&lt;/code&gt; and &lt;code&gt;(temp)&lt;/code&gt; to identify it here. It points to the newly allocated data, at &lt;code&gt;0x04&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Now that we’ve got space for two strings, let’s copy the data from the original place to the new one, from &lt;code&gt;0x00&lt;/code&gt; to &lt;code&gt;0x04&lt;/code&gt;:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;A%20new%20introduction%20to%20Rust%204bbc792c85e141fb81570865cbbe2f87/Untitled%20Database%208311f6138fd34b39840f66e8b047db11.csv&quot;&gt;Untitled&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;and then free that original string:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;A%20new%20introduction%20to%20Rust%204bbc792c85e141fb81570865cbbe2f87/Untitled%20Database%20885b35ff100341e6819740529f0d4701.csv&quot;&gt;Untitled&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Then, we have to update &lt;code&gt;v&lt;/code&gt; to point at the newly allocated vector, at &lt;code&gt;0x04&lt;/code&gt;:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;A%20new%20introduction%20to%20Rust%204bbc792c85e141fb81570865cbbe2f87/Untitled%20Database%20ec53dd46647143b58bb3c7b136d66a59.csv&quot;&gt;Untitled&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This step is where the bug is! You see, &lt;code&gt;x&lt;/code&gt; was pointing at the same data that &lt;code&gt;v&lt;/code&gt; was pointing at. This is called ‘aliasing.’ Because C++ does not have the concept of ownership and lifetimes, it doesn’t understand that the validity of &lt;code&gt;x&lt;/code&gt; and the validity of &lt;code&gt;v&lt;/code&gt; are closely intertwined. Thus, we’re allowed to do this reallocate-and-copy dance with what &lt;code&gt;v&lt;/code&gt; points to, but &lt;code&gt;x&lt;/code&gt; has no idea. Look at the diagram above: it still has &lt;code&gt;x&lt;/code&gt; pointing to &lt;code&gt;0x00&lt;/code&gt;. But we just deallocated that memory! This is when the bug occurs, but it’s a silent bug. A time bomb, ticking away.&lt;/p&gt;
&lt;p&gt;Let’s see how it explodes. Our code goes on, oblivious.&lt;/p&gt;
&lt;p&gt;Our new string at &lt;code&gt;0x04&lt;/code&gt; still says that we have one capacity, one length, and that data is at &lt;code&gt;0x03&lt;/code&gt;. That’s all still accurate, so we’re all good. Next, we need to deal with our new string, “B.” We have the space, so we do so:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;A%20new%20introduction%20to%20Rust%204bbc792c85e141fb81570865cbbe2f87/Untitled%20Database%20cc5b92de5ac545878c67a66a878863b6.csv&quot;&gt;Untitled&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;We’ve placed our new string at &lt;code&gt;0x07&lt;/code&gt; to &lt;code&gt;0x09&lt;/code&gt;, with its data pointer, length, and capacity. Our data is at &lt;code&gt;0x0A&lt;/code&gt;, which has the value &lt;code&gt;B&lt;/code&gt; stored at it. All is good, and so we return from &lt;code&gt;push_back&lt;/code&gt;. &lt;code&gt;(temp)&lt;/code&gt; is deallocated, and memory looks like this:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;A%20new%20introduction%20to%20Rust%204bbc792c85e141fb81570865cbbe2f87/Untitled%20Database%20ee6def6517424e0fb6c9ad7c3ec0389e.csv&quot;&gt;Untitled&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;On the final line, we print out the value that &lt;code&gt;x&lt;/code&gt; points to. As we can see above, &lt;code&gt;x&lt;/code&gt; points to &lt;code&gt;0x00&lt;/code&gt;, which has nothing saved at it! &lt;code&gt;x&lt;/code&gt; is invalid memory. Using &lt;code&gt;x&lt;/code&gt; is a bad idea. But the programming language can’t save us, even though the bug happened many lines ago.&lt;/p&gt;
&lt;p&gt;How are you supposed to deal with this problem? Here’s &lt;a href=&quot;http://en.cppreference.com/w/cpp/container/vector/push_back&quot;&gt;the documentation for &lt;code&gt;push_back&lt;/code&gt;&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;If the new size() is greater than capacity() then all iterators and references (including the past-the-end iterator) are invalidated.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;In other words, when you call &lt;code&gt;push_back&lt;/code&gt;, it’s your responsibility to make sure to not use anything that points to the underlying data, because they are now invalid. The documentation has explained our bug perfectly! And while this is a short example, these problems can crop up in huge codebases, and the errors can be very hard to track down.&lt;/p&gt;
&lt;p&gt;Let’s look at the same problem, in Rust:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;fn main() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    let mut v = vec![];&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    v.push(&quot;Hello&quot;.to_string());&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    let x = &amp;#x26;v[0];&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    v.push(&quot;world&quot;.to_string());&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    println!(&quot;{}&quot;, x);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This program has identical semantics to the C++ version presented above. (If we weren’t trying to get the exact same semantics, we could leave off the &lt;code&gt;.to_string()&lt;/code&gt; calls, and it would still work. But let’s ignore that for now.) So does it have the same bug? Well, it would, but it doesn’t compile:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;main.rs:8:5: 8:6 error: cannot borrow `v` as mutable because it is also borrowed as immutable&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;main.rs:8     v.push(&quot;world&quot;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;              ^&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;main.rs:6:14: 6:15 note: previous borrow of `v` occurs here; the immutable borrow prevents subsequent moves or mutable borrows of `v` until the borrow ends&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;main.rs:6     let x = &amp;#x26;v[0];&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                       ^&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;main.rs:11:2: 11:2 note: previous borrow ends here&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;main.rs:1 fn main() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;main.rs:11 }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;           ^&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When you call the method &lt;code&gt;push()&lt;/code&gt; on a vector, it ‘borrows’ the vector. Just like we wrote &lt;code&gt;let y = &amp;#x26;x&lt;/code&gt; before, to borrow the value of &lt;code&gt;x&lt;/code&gt;. Rust now understands that the scope of &lt;code&gt;x&lt;/code&gt; and the scope of &lt;code&gt;v&lt;/code&gt; are connected. There’s just one problem: because &lt;code&gt;push&lt;/code&gt; allocates more memory, it can’t just do a regular borrow, it needs a mutable borrow. If &lt;code&gt;&amp;#x26;x&lt;/code&gt; borrows x, &lt;code&gt;&amp;#x26;mut x&lt;/code&gt; mutably borrows &lt;code&gt;x&lt;/code&gt;. Like we discussed previously, mutability means that you can reassign the value of that binding. But when we mutably &lt;em&gt;borrow&lt;/em&gt; something, we make a guarantee: this is the only reference to this memory that exists. That way, we don’t have the problem of the C++ code, where a reference became outdated. If we’re the only reference, we are free to change what we’re pointing to, becuase that won’t cause any problems.&lt;/p&gt;
&lt;p&gt;So when we create a borrow with &lt;code&gt;&amp;#x26;&lt;/code&gt;, it lasts for the scope that it exists, like this:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;fn main() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    let mut v = vec![];&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    v.push(&quot;A&quot;);   &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    let x = &amp;#x26;v[0];     // &amp;#x3C;+&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                       //  |&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    v.push(&quot;B&quot;);       //  |&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                       //  |&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    println!(&quot;{}&quot;, x); //  |&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}                      // &amp;#x3C;+&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The line indicates the scope, or lifetime, of the borrow. But when we call push with &lt;code&gt;B&lt;/code&gt;, we have to get a mutable borrow, in order to allocate the new memory. But because &lt;code&gt;&amp;#x26;mut&lt;/code&gt; is a promise that there are no other references, this is a violation of the rules. This is the point at which the bug happened in the C++ example, if you remember. And so it’s the place where the Rust compiler throws its error message. It might make more sense this time around:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;main.rs:8:5: 8:6 error: cannot borrow `v` as mutable because it is also borrowed as immutable&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;main.rs:8     v.push(&quot;world&quot;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;              ^&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;main.rs:6:14: 6:15 note: previous borrow of `v` occurs here; the immutable borrow prevents subsequent moves or mutable borrows of `v` until the borrow ends&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;main.rs:6     let x = &amp;#x26;v[0];&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                       ^&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;main.rs:11:2: 11:2 note: previous borrow ends here&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;main.rs:1 fn main() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;main.rs:11 }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;           ^&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We cannot borrow &lt;code&gt;v&lt;/code&gt; as mutable, with &lt;code&gt;push()&lt;/code&gt;, becuase it is also borrowed as immutable, by &lt;code&gt;x&lt;/code&gt;. That’s exactly the problem, and Rust solves it.&lt;/p&gt;
&lt;p&gt;There’s more to both ownership and Rust syntax, so let’s cover some syntactical things, and then talk more about ownership.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;I’m fairly confident with the memory layouts involved, though the addresses are of course not exact. I’m also not sure that this mega deep detail dive is the correct way to do an introduction either, it’s also thorough, but maybe in a bad way? It’s almost the exact opposite of the way that I’ve done things at present. Also, apparently I visuallize things in reverse, with &lt;code&gt;0x00&lt;/code&gt; to &lt;code&gt;0xFF&lt;/code&gt; as going down, but others think the opposite, which may be confusing. Please send me a &lt;a href=&quot;http://twitter.com/steveklabnik&quot;&gt;tweet&lt;/a&gt; or &lt;a href=&quot;mailto:steve@steveklabnik.com&quot;&gt;an email&lt;/a&gt; with your thoughts. Thanks!&lt;/p&gt;</content:encoded></item><item><title>Rust&apos;s documentation is about to drastically improve</title><link>https://steveklabnik.com/writing/rusts-documentation-is-about-to-drastically-improve/</link><guid isPermaLink="true">https://steveklabnik.com/writing/rusts-documentation-is-about-to-drastically-improve/</guid><description>Historically, Rust has had a tough time with documentation. Such a young programming language changes a lot, which means that documentation can quickly be out of date. However, Rust is nearing a 1.0 release, and so that’s about to change. I’ve just signed a contract with Mozilla,…</description><pubDate>Mon, 16 Jun 2014 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Historically, &lt;a href=&quot;http://rust-lang.org/&quot;&gt;Rust&lt;/a&gt; has had a tough time with documentation. Such a young programming language changes a lot, which means that documentation can quickly be out of date. However, Rust is nearing a 1.0 release, and so that’s about to change. I’ve just signed a contract with Mozilla, and starting Monday, June 23rd, I will be devoting forty hours per week of my time to ensuring that Rust has wonderful documentation.&lt;/p&gt;
&lt;p&gt;A year and a half ago, I was in my hometown for Christmas. I happened upon a link: &lt;a href=&quot;https://mail.mozilla.org/pipermail/rust-dev/2012-December/002787.html&quot;&gt;Rust 0.5 released&lt;/a&gt;. I’ve always enjoyed learning new programming languages, and I had vaguely heard of Rust before, but didn’t really remember what it was all about. So I dug in. I loved systems programming in college, but had done web-based stuff my entire professional life, and hadn’t seriously thought about pointers as part of my day-to-day in quite some time.&lt;/p&gt;
&lt;p&gt;There was just one problem: Rust was really difficult to learn. I liked what I saw, but there was very little of it. At the same time, I had been working on some ideas for a new toolchain for my &lt;a href=&quot;http://www.designinghypermediaapis.com/&quot;&gt;book on hypermedia APIs&lt;/a&gt;, but wanted to try it out on something else before I took the time to port the content. And so, &lt;a href=&quot;http://www.rustforrubyists.com/&quot;&gt;Rust for Rubyists&lt;/a&gt; was born. I decided that the best way to teach people Rust was to mimic how I learned Rust. And so, as I learned, I wrote. It ended up at about fifty pages of two weeks of work. I never contributed it to the main repository, because for me, it was really about learning, both about my ebook toolchain as well as Rust itself. I didn’t want the burden that came with writing an official tutorial, making sure that you cover every single feature, pleasing every single Github contributor…&lt;/p&gt;
&lt;p&gt;After learning Rust, I decided that I really liked it. No other language provided such a promising successor to C++. And I really missed low-level programming. So I kept evangelizing Rust, and every so often, contributing official documentation. I figured that even if my low-level chops weren’t up to the task of writing actual patches, I could at least help with my writing skills. I’d previously contributed lots of documentation to Ruby and Rails, so it was something that was very familiar to me. I’ve often found that I start with documentation and then move into contributing code, once I get my head wrapped around everything. Writing is part of my own process of understanding.&lt;/p&gt;
&lt;p&gt;Rust for Rubyists was a great hit, even amongst non-Rubyists (damn my love of alliteration!). Six months ago, on the eve of the first anniversary of the initial release of Rust for Rubyists, I &lt;a href=&quot;https://air.mozilla.org/rust-meetup-december-2013/&quot;&gt;gave a talk&lt;/a&gt; at the Bay Area Rust meetup, specifically on the state of Rust’s documentation. In it, I laid out a plan for how I envisioned docs looking in the future. In the last six months, a lot has improved, but a lot hasn’t. But no more! I’m now going to be able to allocate a significant amount of my time on getting documentation done.&lt;/p&gt;
&lt;p&gt;I’m also pleased in a meta-sense. You see, by contracting someone to work on documentation full-time, Mozilla is indicating that they take Rust and its future very seriously. You can (and I do) talk a lot of trash on Microsoft, but one of the reasons that the Microsoft platform is used by so many people around the world is that Microsoft products often have excellent documentation. I often find that open source ‘products’ are technically superior, but are often much harder to use, because they’re built by a community, for free, and very few people want to write documentation for free. Combined with the work that Tilde is doing on &lt;a href=&quot;https://github.com/carlhuda/cargo&quot;&gt;Cargo&lt;/a&gt;, Mozilla is investing a significant amount of effort and dollars into ensuring that Rust will be a fantastic platform for those developing on it. Since I love Rust, this makes me very, very happy.&lt;/p&gt;
&lt;p&gt;Forty hours a week is a significant amount of documentation, and I have a lot of work in front of me. But my first area of focus will be on the area of Rust’s documentation that’s the most weak, and simultaneously the most important: the tutorial. I tackled the first tip of that iceberg with &lt;a href=&quot;http://doc.rust-lang.org/master/intro.html&quot;&gt;my 30 minute introduction&lt;/a&gt;, and I’d like to tweak it too. The main tutorial, however, is the first place where people go to &lt;em&gt;really&lt;/em&gt; learn about Rust and how it works. And the current tutorial is largely the same as the 0.5 days, back when I first learned Rust. It suffers from receiving patchwork contributions from a variety of people, rather than having one unifying vision. It’s also much more of a list of features and how to use them than a coherent tutorial.&lt;/p&gt;
&lt;p&gt;I’m really excited to get to work. Let’s all make Rust 1.0 a fantastic release.&lt;/p&gt;</content:encoded></item><item><title>A 30 minute introduction to Rust</title><link>https://steveklabnik.com/writing/a-30-minute-introduction-to-rust/</link><guid isPermaLink="true">https://steveklabnik.com/writing/a-30-minute-introduction-to-rust/</guid><description>I recently gave a proposal for Rust’s documentation . An important component of my overall proposal is a short, simple introduction for people who may have heard of Rust, so that they can figure out if Rust is right for them. The other day, I saw this excellent presentation , and…</description><pubDate>Sat, 11 Jan 2014 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I recently gave a &lt;a href=&quot;https://air.mozilla.org/rust-meetup-december-2013/&quot;&gt;proposal for Rust’s documentation&lt;/a&gt;. An important component of my overall proposal is a short, simple introduction for people who may have heard of Rust, so that they can figure out if Rust is right for them. The other day, I saw &lt;a href=&quot;http://www.youtube.com/watch?v=gfCtbGiHcg0&quot;&gt;this excellent presentation&lt;/a&gt;, and thought it might serve as a great basis for this introduction. Consider this an RFC for such an introduction. Feedback very welcome on &lt;a href=&quot;https://mail.mozilla.org/pipermail/rust-dev/2014-January/007903.html&quot;&gt;the rust-dev mailing list&lt;/a&gt; or &lt;a href=&quot;https://twitter.com/steveklabnik&quot;&gt;on Twitter&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;this-tutorial-has-now-become-the-official-one&quot;&gt;This tutorial has now &lt;a href=&quot;http://static.rust-lang.org/doc/master/intro.html&quot;&gt;become the official one&lt;/a&gt;.&lt;/h2&gt;
&lt;p&gt;Rust is a systems programming language that focuses on strong compile-time correctness guarantees. It improves upon the ideas other systems languages like C++, D, and Cyclone by providing very strong guarantees and explicit control over the life cycle of memory. Strong memory guarantees make writing correct concurrent Rust code easier than in other languages. This might sound very complex, but it’s easier than it sounds! This tutorial will give you an idea of what Rust is like in about thirty minutes. It expects that you’re at least vaguely familiar with a previous ‘curly brace’ language. The concepts are more important than the syntax, so don’t worry if you don’t get every last detail: the &lt;a href=&quot;http://static.rust-lang.org/doc/master/tutorial.html&quot;&gt;tutorial&lt;/a&gt; can help you out with that later.&lt;/p&gt;
&lt;p&gt;Let’s talk about the most important concept in Rust, “ownership,” and its implications on a task that programmers usually find very difficult: concurrency.&lt;/p&gt;
&lt;h2 id=&quot;ownership&quot;&gt;Ownership&lt;/h2&gt;
&lt;p&gt;Ownership is central to Rust, and is one of its more interesting and unique features. “Ownership” refers to which parts of your code are allowed to modify various parts of memory. Let’s start by looking at some C++ code:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;int *dangling(void)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    int i = 1234;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    return &amp;#x26;i;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;int add_one(void)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    int *num = dangling();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    return *num + 1;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This function allocates an integer on the stack, and stores it in a variable, &lt;code&gt;i&lt;/code&gt;. It then returns a reference to the variable &lt;code&gt;i&lt;/code&gt;. There’s just one problem: stack memory becomes invalid when the function returns. This means that in the second line of &lt;code&gt;add_one&lt;/code&gt;, &lt;code&gt;num&lt;/code&gt; points to some garbage values, and we won’t get the effect that we want. While this is a trivial example, it can happen quite often in C++ code. There’s a similar problem when memory on the heap is allocated with &lt;code&gt;malloc&lt;/code&gt; (or &lt;code&gt;new&lt;/code&gt;), then freed with &lt;code&gt;free&lt;/code&gt; (or &lt;code&gt;delete&lt;/code&gt;), yet your code attempts to do something with the pointer to that memory. More modern C++ uses RAII with constructors/destructors, but it amounts to the same thing. This problem is called a ‘dangling pointer,’ and it’s not possible to write Rust code that has it. Let’s try:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;fn dangling() -&gt; &amp;#x26;int {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    let i = 1234;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    return &amp;#x26;i;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;fn add_one() -&gt; int {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    let num = dangling();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    return *num + 1;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When you try to compile this program, you’ll get an interesting (and long) error message:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;temp.rs:3:11: 3:13 error: borrowed value does not live long enough&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;temp.rs:3     return &amp;#x26;i;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;temp.rs:1:22: 4:1 note: borrowed pointer must be valid for the anonymous lifetime #1 defined on the block at 1:22...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;temp.rs:1 fn dangling() -&gt; &amp;#x26;int {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;temp.rs:2     let i = 1234;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;temp.rs:3     return &amp;#x26;i;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;temp.rs:4 }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                            &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;temp.rs:1:22: 4:1 note: ...but borrowed value is only valid for the block at 1:22&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;temp.rs:1 fn dangling() -&gt; &amp;#x26;int {      &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;temp.rs:2     let i = 1234;            &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;temp.rs:3     return &amp;#x26;i;               &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;temp.rs:4  }                            &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;error: aborting due to previous error&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In order to fully understand this error message, we need to talk about what it means to “own” something. So for now, let’s just accept that Rust will not allow us to write code with a dangling pointer, and we’ll come back to this code once we understand ownership.&lt;/p&gt;
&lt;p&gt;Let’s forget about programming for a second and talk about books. I like to read physical books, and sometimes I really like one and tell my friends they should read it. While I’m reading my book, I own it: the book is in my possession. When I loan the book out to someone else for a while, they “borrow” it from me. And when you borrow a book, it’s yours for a certain period of time, and then you give it back to me, and I own it again. Right?&lt;/p&gt;
&lt;p&gt;This concept applies directly to Rust code as well: some code “owns” a particular pointer to memory. It’s the sole owner of that pointer. It can also lend that memory out to some other code for a while: the code “borrows” it. It borrows it for a certain period of time, called a “lifetime.”&lt;/p&gt;
&lt;p&gt;That’s all there is to it. That doesn’t seem so hard, right? Let’s go back to that error message: &lt;code&gt;error: borrowed value does not live long enough&lt;/code&gt;. We tried to loan out a particular variable, &lt;code&gt;i&lt;/code&gt;, using Rust’s borrowed pointers: the &lt;code&gt;&amp;#x26;&lt;/code&gt;. But Rust knew that the variable would be invalid after the function returns, and so it tells us that: &lt;code&gt;borrowed pointer must be valid for the anonymous lifetime #1... but borrowed value is only valid for the block&lt;/code&gt;. Neat!&lt;/p&gt;
&lt;p&gt;That’s a great example for stack memory, but what about heap memory? Rust has a second kind of pointer, a ‘unique’ pointer, that you can create with a &lt;code&gt;~&lt;/code&gt;. Check it out:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;fn dangling() -&gt; ~int {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    let i = ~1234;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    return i;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;fn add_one() -&gt; int {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    let num = dangling();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    return *num + 1;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This code will successfully compile. Note that instead of a stack allocated &lt;code&gt;1234&lt;/code&gt;, we use an owned pointer to that value instead: &lt;code&gt;~1234&lt;/code&gt;. You can roughly compare these two lines:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;// rust&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;let i = ~1234;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;// C++&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;int *i = new int;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;*i = 1234;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Rust is able to infer the size of the type, then allocates the correct amount of memory and sets it to the value you asked for. This means that it’s impossible to allocate uninitialized memory: Rust does not have the concept of null. Hooray! There’s one other difference between this line of Rust and the C++: The Rust compiler also figures out the lifetime of &lt;code&gt;i&lt;/code&gt;, and then inserts a corresponding &lt;code&gt;free&lt;/code&gt; call after it’s invalid, like a destructor in C++. You get all of the benefits of manually allocated heap memory without having to do all the bookkeeping yourself. Furthermore, all of this checking is done at compile time, so there’s no runtime overhead. You’ll get (basically) the exact same code that you’d get if you wrote the correct C++, but it’s impossible to write the incorrect version, thanks to the compiler.&lt;/p&gt;
&lt;p&gt;You’ve seen one way that ownership and lifetimes are useful to prevent code that would normally be dangerous in a less-strict language, but let’s talk about another: concurrency.&lt;/p&gt;
&lt;h2 id=&quot;concurrency&quot;&gt;Concurrency&lt;/h2&gt;
&lt;p&gt;Concurrency is an incredibly hot topic in the software world right now. It’s always been an interesting area of study for computer scientists, but as usage of the Internet explodes, people are looking to improve the number of users a given service can handle. Concurrency is one way of achieving this goal. There is a pretty big drawback to concurrent code, though: it can be hard to reason about, because it is non-deterministic. There are a few different approaches to writing good concurrent code, but let’s talk about how Rust’s notions of ownership and lifetimes can assist with achieving correct but concurrent code.&lt;/p&gt;
&lt;p&gt;First, let’s go over a simple concurrency example in Rust. Rust allows you to spin up ‘tasks,’ which are lightweight, ‘green’ threads. These tasks do not have any shared memory, and so, we communicate between tasks with a ‘channel’. Like this:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;fn main() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    let numbers = [1,2,3];&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    let (port, chan)  = Chan::new();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    chan.send(numbers);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    do spawn {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        let numbers = port.recv();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        println!(&quot;{:d}&quot;, numbers[0]);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In this example, we create a vector of numbers. We then make a new &lt;code&gt;Chan&lt;/code&gt;, which is the name of the package Rust implements channels with. This returns two different ends of the channel: a channel and a port. You send data into the channel end, and it comes out the port end. The &lt;code&gt;spawn&lt;/code&gt; function spins up a new task. As you can see in the code, we call &lt;code&gt;port.recv()&lt;/code&gt; (short for ‘receive’) inside of the new task, and we call &lt;code&gt;chan.send()&lt;/code&gt; outside, passing in our vector. We then print the first element of the vector.&lt;/p&gt;
&lt;p&gt;This works out because Rust copies the vector when it is sent through the channel. That way, if it were mutable, there wouldn’t be a race condition. However, if we’re making a lot of tasks, or if our data is very large, making a copy for each task inflates our memory usage with no real benefit.&lt;/p&gt;
&lt;p&gt;Enter Arc. Arc stands for ‘atomically reference counted,’ and it’s a way to share immutable data between multiple tasks. Here’s some code:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;extern mod extra;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;use extra::arc::Arc;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;fn main() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    let numbers = [1,2,3];&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    let numbers_arc = Arc::new(numbers);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    for num in range(0, 3) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        let (port, chan)  = Chan::new();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        chan.send(numbers_arc.clone());&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        do spawn {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            let local_arc = port.recv();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            let task_numbers = local_arc.get();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            println!(&quot;{:d}&quot;, task_numbers[num]);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is very similar to the code we had before, except now we loop three times, making three tasks, and sending an &lt;code&gt;Arc&lt;/code&gt; between them. &lt;code&gt;Arc::new&lt;/code&gt; creates a new Arc, &lt;code&gt;.clone()&lt;/code&gt; makes a new reference to that Arc, and &lt;code&gt;.get()&lt;/code&gt; gets the value out of the Arc. So we make a new reference for each task, send that reference down the channel, and then use the reference to print out a number. Now we’re not copying our vector.&lt;/p&gt;
&lt;p&gt;Arcs are great for immutable data, but what about mutable data? Shared mutable state is the bane of the concurrent programmer. You can use a mutex to protect shared mutable state, but if you forget to acquire the mutex, bad things can happen.&lt;/p&gt;
&lt;p&gt;Rust provides a tool for shared mutable state: &lt;code&gt;RWArc&lt;/code&gt;. This variant of an Arc allows the contents of the Arc to be mutated. Check it out:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;extern mod extra;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;use extra::arc::RWArc;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;fn main() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    let numbers = [1,2,3];&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    let numbers_arc = RWArc::new(numbers);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    for num in range(0, 3) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        let (port, chan)  = Chan::new();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        chan.send(numbers_arc.clone());&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        do spawn {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            let local_arc = port.recv();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            local_arc.write(|nums| {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                nums[num] += 1&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            });&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            local_arc.read(|nums| {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                println!(&quot;{:d}&quot;, nums[num]);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            })&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We now use the &lt;code&gt;RWArc&lt;/code&gt; package to get a read/write Arc. The read/write Arc has a slightly different API than &lt;code&gt;Arc&lt;/code&gt;: &lt;code&gt;read&lt;/code&gt; and &lt;code&gt;write&lt;/code&gt; allow you to, well, read and write the data. They both take closures as arguments, and the read/write Arc will, in the case of write, acquire a mutex, and then pass the data to this closure. After the closure does its thing, the mutex is released.&lt;/p&gt;
&lt;p&gt;You can see how this makes it impossible to mutate the state without remembering to aquire the lock. We gain the efficiency of shared mutable state, while retaining the safety of disallowing shared mutable state.&lt;/p&gt;
&lt;p&gt;But wait, how is that possible? We can’t both allow and disallow mutable state. What gives?&lt;/p&gt;
&lt;h2 id=&quot;a-footnote-unsafe&quot;&gt;A footnote: unsafe&lt;/h2&gt;
&lt;p&gt;So, the Rust language does not allow for shared mutable state, yet I just showed you some code that has it. How’s this possible? The answer: &lt;code&gt;unsafe&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;You see, while the Rust compiler is very smart, and saves you from making mistakes you might normally make, it’s not an artificial intelligence. Because we’re smarter than the compiler, sometimes, we need to over-ride this safe behavior. For this purpose, Rust has an &lt;code&gt;unsafe&lt;/code&gt; keyword. Within an &lt;code&gt;unsafe&lt;/code&gt; block, Rust turns off many of its safety checks. If something bad happens to your program, you only have to audit what you’ve done inside &lt;code&gt;unsafe&lt;/code&gt;, and not the entire program itself.&lt;/p&gt;
&lt;p&gt;If one of the major goals of Rust was safety, why allow that safety to be turned off? Well, there are really only three main reasons to do it: interfacing with external code, such as doing FFI into a C library, performance (in certain cases), and to provide a safe abstraction around operations that normally would not be safe. Our Arcs are an example of this last purpose. We can safely hand out multiple references to the &lt;code&gt;Arc&lt;/code&gt;, because we are sure the data is immutable, and therefore it is safe to share. We can hand out multiple references to the &lt;code&gt;RWArc&lt;/code&gt;, because we know that we’ve wrapped the data in a mutex, and therefore it is safe to share. But the Rust compiler can’t know that we’ve made these choices, so &lt;em&gt;inside&lt;/em&gt; the implementation of the Arcs, we use &lt;code&gt;unsafe&lt;/code&gt; blocks to do (normally) dangerous things. But we expose a safe interface, which means that the Arcs are impossible to use incorrectly.&lt;/p&gt;
&lt;p&gt;This is how Rust’s type system allows you to not make some of the mistakes that make concurrent programming difficult, yet get the efficiency of languages such as C++.&lt;/p&gt;
&lt;h2 id=&quot;thats-all-folks&quot;&gt;That’s all, folks&lt;/h2&gt;
&lt;p&gt;I hope that this taste of Rust has given you an idea if Rust is the right language for you. If that’s true, I encourage you to check out &lt;a href=&quot;http://static.rust-lang.org/doc/0.9/tutorial.html&quot;&gt;the tutorial&lt;/a&gt; for a full, in-depth exploration of Rust’s syntax and concepts.&lt;/p&gt;</content:encoded></item><item><title>Rust is surprisingly expressive</title><link>https://steveklabnik.com/writing/rust-is-surprisingly-expressive/</link><guid isPermaLink="true">https://steveklabnik.com/writing/rust-is-surprisingly-expressive/</guid><description>Do you remember the first time you saw Rails’ ActiveSupport library? I do: it totally blew my mind. The only dynamic language I had used up to that point was Perl, and it had a similarly mind-blowing effect on my young self. I thought that dynamic typing was mostly a requirement…</description><pubDate>Sat, 28 Dec 2013 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Do you remember the first time you saw Rails’ ActiveSupport library? I do: it totally blew my mind. The only dynamic language I had used up to that point was Perl, and it had a similarly mind-blowing effect on my young self. I thought that dynamic typing was mostly a requirement towards making this kind of expressiveness possible, but it turns out Rust can be just as expressive, while retaining type safety and static dispatch.&lt;/p&gt;
&lt;p&gt;There was a time in the early days of Rails when its evangelists would show off snippets of what it let you do. These were often ActiveSupport extensions to the core language itself. It’d go something like this:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Hey, have you tried Rails? Check this out:&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;irb(main):002:0&gt; Time.now - 2.days&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;=&gt; 2009-12-26 09:57:02 -0800&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;irb(main):003:0&gt; 2.days.ago&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;=&gt; 2009-12-26 09:57:04 -0800&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;Did I just blow your mind???&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;At the time, I enthusiastically replied “Yes, yes you did!” and immediately typed &lt;code&gt;rails new foo&lt;/code&gt;. And all was well and good in the world.&lt;/p&gt;
&lt;p&gt;Fast forward a few years. I now know that static typing is not equivalent to &lt;code&gt;public static void main(String [] args) {&lt;/code&gt;. I’ve seen the &lt;a href=&quot;http://www.cafepress.com/mf/2498088/what-part-of-types-dont-you-understand_tshirt?shop=skicalc&amp;#x26;productId=6225368&quot;&gt;Hindley-Milner&lt;/a&gt; light. Yet, for all practical purposes, I’ve still been hacking in Ruby for these past few years. For the most part, I’d found the complaints about dynamic typing from the static typing camp to be very FUD-y. I very rarely get &lt;code&gt;TypeError&lt;/code&gt;s in my Ruby code. Refactoring generally isn’t very difficult.&lt;/p&gt;
&lt;p&gt;But slowly, this has started to change. I think that it’s that I tend to do more infrastructure and plumbing work now. I’ve run into more and more situations where types would be helpful, or picking the mutable state path has caused headaches.&lt;/p&gt;
&lt;p&gt;Then, I wake up to an IM from &lt;a href=&quot;http://twitter.com/wycats&quot;&gt;Yehuda&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;bro, did you see my tweets?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Basically, this:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;➜  active_support git:(master) cat main.rs&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;extern mod active_support;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;use active_support::Period;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;use active_support::Time;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;fn main() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  let time = Time::now();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  println!(&quot;{:?}&quot;, time);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  println!(&quot;{:?}&quot;, 2.days().from_now());&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  println!(&quot;{:?}&quot;, 2.weeks().from_now());&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  println!(&quot;{:?}&quot;, 2.months().from_now());&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  println!(&quot;{:?}&quot;, 2.years().from_now());&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;➜  active_support git:(master) ./main &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;active_support::time::Time{date: active_support::date::Date{year: 2013, month: 12u, day: 28u}, hours: 0u, minutes: 59u, seconds: 6u, nanos: 242647081u}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;active_support::time::Time{date: active_support::date::Date{year: 2013, month: 12u, day: 30u}, hours: 0u, minutes: 59u, seconds: 6u, nanos: 243287552u}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;active_support::time::Time{date: active_support::date::Date{year: 2014, month: 1u, day: 11u}, hours: 0u, minutes: 59u, seconds: 6u, nanos: 243347757u}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;active_support::time::Time{date: active_support::date::Date{year: 2013, month: 2u, day: 28u}, hours: 0u, minutes: 59u, seconds: 6u, nanos: 243388962u}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;active_support::time::Time{date: active_support::date::Date{year: 2015, month: 12u, day: 28u}, hours: 0u, minutes: 59u, seconds: 6u, nanos: 243427393u}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Whaaaat? Yup. To compare side-by-side:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;# Ruby&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;2.days.from_now&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;// Rust&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;2.days().from_now()&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Awesome. Please note that in Rust, this is fully type-checked, safe, and &lt;em&gt;statically dispatched&lt;/em&gt;. No slow reflection techniques used here!&lt;/p&gt;
&lt;p&gt;Now, I should say that I almost &lt;em&gt;never&lt;/em&gt; use &lt;code&gt;2.days&lt;/code&gt;, but the point is that it’s a benchmark of expressiveness: if you can write it, you can do all sorts of other flexible things. Thinking back to my ‘libraries vs. application code’ confusion over types, I’m reminded by something &lt;a href=&quot;https://twitter.com/garybernhardt&quot;&gt;Gary Bernhardt&lt;/a&gt; once said about Ruby vs. Python. I’m paraphrasing, but as I remember it:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Python is a beautiful, clean language. But the same restrictions that make it nice and clean mean that it’s hard to write beautiful, clean libraries. Ruby, on the other hand, is a complicated, ugly language. But that complexity allows you to write really clean, nice, easy-to-use libraries. The end result is that I prefer Python the language, but I find myself preferring programming with Ruby.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I’m starting to wonder if maybe I feel the same way about static vs. dynamic typing: I like the simplicity and the speed of programming in a dynamic language, but maybe, given the right static language, I’ll end up preferring to program in $LANGUAGE better.&lt;/p&gt;
&lt;p&gt;And that language might just be Rust.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;You can check out Yehuda’s &lt;a href=&quot;https://github.com/wycats/rust-activesupport&quot;&gt;rust-activesupport on GitHub&lt;/a&gt;, if you’d like to see how this is accomplished. He’s also told me that he will write a post explaining its implementation in technical detail, I’ll link to it here when he’s written it.&lt;/p&gt;</content:encoded></item><item><title>Pointers in Rust, a guide</title><link>https://steveklabnik.com/writing/pointers-in-rust-a-guide/</link><guid isPermaLink="true">https://steveklabnik.com/writing/pointers-in-rust-a-guide/</guid><description>Rust’s pointers are one of its more unique and compelling features. Pointers are also one of the more confusing topics for newcomers to Rust. They can also be confusing for people coming from other languages that support pointers, such as C++. This tutorial will help you…</description><pubDate>Fri, 18 Oct 2013 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Rust’s pointers are one of its more unique and compelling features. Pointers are also one of the more confusing topics for newcomers to Rust. They can also be confusing for people coming from other languages that support pointers, such as C++. This tutorial will help you understand this important topic.&lt;/p&gt;
&lt;h1 id=&quot;you-dont-actually-need-pointers&quot;&gt;You don’t actually need pointers&lt;/h1&gt;
&lt;p&gt;I have good news for you: you probably don’t need to care about pointers, especially as you’re getting started. Think of it this way: Rust is a language that emphasizes safety. Pointers, as the joke goes, are very pointy: it’s easy to accidentally stab yourself. Therefore, Rust is made in a way such that you don’t need them very often.&lt;/p&gt;
&lt;p&gt;“But tutorial!” you may cry. “My co-worker wrote a function that looks like this:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;fn succ(x: &amp;#x26;int) -&gt; int { *x + 1 }&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So I wrote this code to try it out:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;fn main() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    let number = 5;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    let succ_number = succ(number);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    println!(&quot;{}&quot;, succ_number);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And now I get an error:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;error: mismatched types: expected `&amp;#x26;int` but found `&amp;#x3C;VI0&gt;` (expected &amp;#x26;-ptr but found integral variable)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;What gives? It needs a pointer! Therefore I have to use pointers!”&lt;/p&gt;
&lt;p&gt;Turns out, you don’t. All you need is a reference. Try this on for size:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;fn main() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    let number = 5;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    let succ_number = succ(&amp;#x26;number);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    println!(&quot;{}&quot;, succ_number);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It’s that easy! One extra little &lt;code&gt;&amp;#x26;&lt;/code&gt; there. This code will run, and print &lt;code&gt;6&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;That’s all you need to know. Your co-worker could have written the function like this:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;fn succ(x: int) -&gt; int { x + 1 }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;fn main() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    let number = 5;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    let succ_number = succ(number);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    println!(&quot;{}&quot;, succ_number);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;No pointers even needed. Then again, this is a simple example. I assume that your real-world &lt;code&gt;succ&lt;/code&gt; function is more complicated, and maybe your co-worker had a good reason for &lt;code&gt;x&lt;/code&gt; to be a pointer of some kind. In that case, references are your best friend. Don’t worry about it, life is too short.&lt;/p&gt;
&lt;p&gt;However.&lt;/p&gt;
&lt;p&gt;Here are the use-cases for pointers. I’ve prefixed them with the name of the pointer that satisfies that use-case:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Owned: ~Trait must be a pointer, becuase you don’t know the size of the object, so indirection is mandatory.&lt;/li&gt;
&lt;li&gt;Owned: You need a recursive data structure. These can be infinite sized, so indirection is mandatory.&lt;/li&gt;
&lt;li&gt;Owned: A very, very, very rare situation in which you have a &lt;em&gt;huge&lt;/em&gt; chunk of data that you wish to pass to many methods. Passing a pointer will make this more efficient. If you’re coming from another language where this technique is common, such as C++, please read “A note…” below.&lt;/li&gt;
&lt;li&gt;Managed: Having only a single owner to a piece of data would be inconvenient or impossible. This is only often useful when a program is very large or very complicated. Using a managed pointer will activate Rust’s garbage collection mechanism.&lt;/li&gt;
&lt;li&gt;Borrowed: You’re writing a function, and you need a pointer, but you don’t care about its ownership. If you make the argument a borrowed pointer, callers can send in whatever kind they want.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Five exceptions. That’s it. Otherwise, you shouldn’t need them. Be skeptical of pointers in Rust: use them for a deliberate purpose, not just to make the compiler happy.&lt;/p&gt;
&lt;h2 id=&quot;a-note-for-those-proficient-in-pointers&quot;&gt;A note for those proficient in pointers&lt;/h2&gt;
&lt;p&gt;If you’re coming to Rust from a language like C or C++, you may be used to passing things by reference, or passing things by pointer. In some languages, like Java, you can’t even have objects without a pointer to them. Therefore, if you were writing this Rust code:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;struct Point {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    x: int,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    y: int,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;fn main() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    let p0 = Point { x: 5, y: 10};&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    let p1 = transform(p0);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    println!(&quot;{:?}&quot;, p1);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I think you’d implement &lt;code&gt;transform&lt;/code&gt; like this:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;fn transform(p: &amp;#x26;Point) -&gt; Point {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    Point { x: p.x + 1, y: p.y + 1}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;// and change this:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;let p1 = transform(&amp;#x26;p0);&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This does work, but you don’t need to create those references! The better way to write this is simply:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;struct Point {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    x: int,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    y: int,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;fn transform(p: Point) -&gt; Point {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    Point { x: p.x + 1, y: p.y + 1}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;fn main() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    let p0 = Point { x: 5, y: 10};&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    let p1 = transform(p0);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    println!(&quot;{:?}&quot;, p1);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;But won’t this be inefficent? Well, that’s a complicated question, but it’s important to know that Rust, like C and C++, store aggregate data types ‘unboxed,’ whereas languages like Java and Ruby store these types as ‘boxed.’ For smaller structs, this way will be more efficient. For larger ones, it may be less so. But don’t reach for that pointer until you must! Make sure that the struct is large enough by performing some tests before you add in the complexity of pointers.&lt;/p&gt;
&lt;h1 id=&quot;owned-pointers&quot;&gt;Owned Pointers&lt;/h1&gt;
&lt;p&gt;Owned pointers are the conceptually simplest kind of pointer in Rust. A rough approximation of owned pointers follows:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Only one owned pointer may exist to a particular place in memory. It may be borrowed from that owner, however.&lt;/li&gt;
&lt;li&gt;The Rust compiler uses static analysis to determine where the pointer is in scope, and handles allocating and de-allocating that memory. Owned pointers are not garbage collected.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;These two properties make for three use cases.&lt;/p&gt;
&lt;h2 id=&quot;references-to-traits&quot;&gt;References to Traits&lt;/h2&gt;
&lt;p&gt;Traits must be referenced through a pointer, becuase the struct that implements the trait may be a different size than a different struct that implements the trait. Therefore, unboxed traits don’t make any sense, and aren’t allowed.&lt;/p&gt;
&lt;h2 id=&quot;recursive-data-structures&quot;&gt;Recursive Data Structures&lt;/h2&gt;
&lt;p&gt;Sometimes, you need a recursive data structure. The simplest is known as a ‘cons list’:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;enum List&amp;#x3C;T&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    Nil,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    Cons(T, ~List&amp;#x3C;T&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;fn main() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    let list: List&amp;#x3C;int&gt; = Cons(1, ~Cons(2, ~Cons(3, ~Nil)));&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    println!(&quot;{:?}&quot;, list);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This prints:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Cons(1, ~Cons(2, ~Cons(3, ~Nil)))&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The inner lists &lt;em&gt;must&lt;/em&gt; be an owned pointer, becuase we can’t know how many elements are in the list. Without knowing the length, we don’t know the size, and therefore require the indirection that pointers offer.&lt;/p&gt;
&lt;h2 id=&quot;efficiency&quot;&gt;Efficiency&lt;/h2&gt;
&lt;p&gt;This should almost never be a concern, but because creating an owned pointer boxes its value, it therefore makes referring to the value the size of the box. This may make passing an owned pointer to a function less expensive than passing the value itself. Don’t worry yourself with this case until you’ve proved that it’s an issue through benchmarks.&lt;/p&gt;
&lt;p&gt;For example, this will work:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;struct Point {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    x: int,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    y: int,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;fn main() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    let a = Point { x: 10, y: 20 };&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    do spawn {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        println(a.x.to_str());&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This struct is tiny, so it’s fine. If &lt;code&gt;Point&lt;/code&gt; were large, this would be more efficient:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;struct Point {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    x: int,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    y: int,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;fn main() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    let a = ~Point { x: 10, y: 20 };&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    do spawn {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        println(a.x.to_str());&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now it’ll be copying a pointer-sized chunk of memory rather than the whole struct.&lt;/p&gt;
&lt;h1 id=&quot;managed-pointers&quot;&gt;Managed Pointers&lt;/h1&gt;
&lt;p&gt;Managed pointers, notated by an &lt;code&gt;@&lt;/code&gt;, are used when having a single owner for some data isn’t convenient or possible. This generally happens when your program is very large and complicated.&lt;/p&gt;
&lt;p&gt;For example, let’s say you’re using an owned pointer, and you want to do this:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;struct Point {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    x: int,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    y: int,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;fn main() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    let a = ~Point { x: 10, y: 20 };&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    let b = a;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    println(b.x.to_str());&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    println(a.x.to_str());&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You’ll get this error:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;test.rs:10:12: 10:13 error: use of moved value: `a`&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;test.rs:10     println(a.x.to_str());&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                       ^&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;test.rs:8:8: 8:9 note: `a` moved here because it has type `~Point`, which is moved by default (use `ref` to override)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;test.rs:8     let b = a;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                  ^&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As the message says, owned pointers only allow for one owner at a time. When you assign &lt;code&gt;a&lt;/code&gt; to &lt;code&gt;b&lt;/code&gt;, &lt;code&gt;a&lt;/code&gt; becomes invalid. Change your code to this, however:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;struct Point {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    x: int,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    y: int,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;fn main() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    let a = @Point { x: 10, y: 20 };&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    let b = a;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    println(b.x.to_str());&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    println(a.x.to_str());&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And it works:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;10&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;10&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So why not just use managed pointers everywhere? There are two big drawbacks to managed pointers:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;They activate Rust’s garbage collector. Other pointer types don’t share this drawback.&lt;/li&gt;
&lt;li&gt;You cannot pass this data to another task. Shared ownership across concurrency boundaries is the source of endless pain in other languages, so Rust does not let you do this.&lt;/li&gt;
&lt;/ol&gt;
&lt;h1 id=&quot;borrowed-pointers&quot;&gt;Borrowed Pointers&lt;/h1&gt;
&lt;p&gt;Borrowed pointers are the third major kind of pointer Rust supports. They are simultaneously the simplest and the most complicated kind. Let me explain: they’re called ‘borrowed’ pointers because they claim no ownership over the data they’re pointing to. They’re just borrowing it for a while. So in that sense, they’re simple: just keep whatever ownership the data already has. For example:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;use std::num::sqrt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;struct Point {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    x: float,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    y: float,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;fn compute_distance(p1: &amp;#x26;Point, p2: &amp;#x26;Point) -&gt; float {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    let x_d = p1.x - p2.x;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    let y_d = p1.y - p2.y;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    sqrt(x_d * x_d + y_d * y_d)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;fn main() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    let origin = @Point { x: 0.0, y: 0.0 };&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    let p1     = ~Point { x: 5.0, y: 3.0 };&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    println!(&quot;{:?}&quot;, compute_distance(origin, p1));&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This prints &lt;code&gt;5.83095189&lt;/code&gt;. You can see that the &lt;code&gt;compute_distance&lt;/code&gt; function takes in two borrowed pointers, but we give it a managed and unique pointer. Of course, if this were a real program, we wouldn’t have any of these pointers, they’re just there to demonstrate the concepts.&lt;/p&gt;
&lt;p&gt;So how is this hard? Well, because we’re igorning ownership, the compiler needs to take great care to make sure that everything is safe. Despite their complete safety, a borrowed pointer’s representation at runtime is the same as that of an ordinary pointer in a C program. They introduce zero overhead. The compiler does all safety checks at compile time.&lt;/p&gt;
&lt;p&gt;This theory is called ‘region pointers,’ and involve a concept called ‘lifetimes’. Here’s the simple explanation: would you expect this code to compile?&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;fn main() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    println(x.to_str());&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    let x = 5;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Probably not. That’s becuase you know that the name &lt;code&gt;x&lt;/code&gt; is valid from where it’s declared to when it goes out of scope. In this case, that’s the end of the &lt;code&gt;main&lt;/code&gt; function. So you know this code will cause an error. We call this duration a ‘lifetime’. Let’s try a more complex example:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;fn main() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    let mut x = ~5;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    if(*x &amp;#x3C; 10) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        let y = &amp;#x26;x;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        println!(&quot;Oh no: {:?}&quot;, y);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        return;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    *x = *x - 1;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    println!(&quot;Oh no: {:?}&quot;, x);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here, we’re borrowing a pointer to &lt;code&gt;x&lt;/code&gt; inside of the &lt;code&gt;if&lt;/code&gt;. The compiler, however, is able to determine that that pointer will go out of scope without &lt;code&gt;x&lt;/code&gt; being mutated, and therefore, lets us pass. This wouldn’t work:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;fn main() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    let mut x = ~5;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    if(*x &amp;#x3C; 10) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        let y = &amp;#x26;x;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        *x = *x - 1;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        println!(&quot;Oh no: {:?}&quot;, y);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        return;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    *x = *x - 1;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    println!(&quot;Oh no: {:?}&quot;, x);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It gives this error:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;test.rs:5:8: 5:10 error: cannot assign to `*x` because it is borrowed&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;test.rs:5         *x = *x - 1;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                  ^~&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;test.rs:4:16: 4:18 note: borrow of `*x` occurs here&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;test.rs:4         let y = &amp;#x26;x;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                          ^~&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As you might guess, this kind of analysis is complex for a human, and therefore hard for a computer, too! There is an entire &lt;a href=&quot;http://static.rust-lang.org/doc/0.8/tutorial-borrowed-ptr.html&quot;&gt;tutorial devoted to borrowed pointers and lifetimes&lt;/a&gt; that goes into lifetimes in great detail, so if you want the full details, check that out.&lt;/p&gt;
&lt;h1 id=&quot;returning-pointers&quot;&gt;Returning Pointers&lt;/h1&gt;
&lt;p&gt;We’ve talked a lot about funtions that accept various kinds of pointers, but what about returning them? Here’s the rule of thumb: only return a unique or managed pointer if you were given one in the first place.&lt;/p&gt;
&lt;p&gt;What does that mean? Don’t do this:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;fn foo(x: ~int) -&gt; ~int {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    return ~*x;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;fn main() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    let x = ~5;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    let y = foo(x);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Do this:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;fn foo(x: ~int) -&gt; int {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    return *x;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;fn main() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    let x = ~5;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    let y = ~foo(x);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This gives you flexibility, without sacrificing performance. For example, this will also work:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;fn foo(x: ~int) -&gt; int {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    return *x;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;fn main() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    let x = ~5;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    let y = @foo(x);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You may think that this gives us terrible performance: return a value and then immediately box it up?!?! Isn’t that the worst of both worlds? Rust is smarter than that. There is no copy in this code. &lt;code&gt;main&lt;/code&gt; allocates enough room for the &lt;code&gt;@int&lt;/code&gt;, passes it into &lt;code&gt;foo&lt;/code&gt; as &lt;code&gt;x&lt;/code&gt;, and then &lt;code&gt;foo&lt;/code&gt; writes the value into the new box. This writes the return value directly into the allocated box.&lt;/p&gt;
&lt;p&gt;This is important enough that it bears repeating: pointers are not for optimizing returning values from your code. Allow the caller to choose how they want to use your output.&lt;/p&gt;</content:encoded></item><item><title>Rust-y Scraps: iterating with a step</title><link>https://steveklabnik.com/writing/rust--y-scraps--iterating-with-a-step/</link><guid isPermaLink="true">https://steveklabnik.com/writing/rust--y-scraps--iterating-with-a-step/</guid><description>This blog post works with Rust v 0.6, and may change in the future :). A common need in various algorithms is to iterate with some sort of step. A simple way to do this in Rust is with unit::range_step : let nums = [1,2,3,4,5,6,7]; for uint::range_step(0, bytes.len() - 1, 2) |i|…</description><pubDate>Thu, 30 May 2013 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;This blog post works with &lt;a href=&quot;http://rust-lang.org/&quot;&gt;Rust&lt;/a&gt; v 0.6, and may change in the future :).&lt;/p&gt;
&lt;p&gt;A common need in various algorithms is to iterate with some sort of step. A simple way to do this in Rust is with &lt;code&gt;unit::range_step&lt;/code&gt;:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;let nums = [1,2,3,4,5,6,7];&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;for uint::range_step(0, bytes.len() - 1, 2) |i| {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    println(fmt!(&quot;%d &amp;#x26; %d&quot;, nums[i], nums[i+1]));&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This yields&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;1 &amp;#x26; 2&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;3 &amp;#x26; 4&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;5 &amp;#x26; 6&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Of course, this is awkward: I wish I had some code to do something like:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;let nums = [1,2,3,4,5,6,7];&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;for nums.in_groups |i, j| {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  println(fmt!(&quot;%d &amp;#x26; %d&quot;, i, j));&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;But I think this is just out of my abilities. The issue is that the closure needs to take the same number of arguments as the step, and I’m not sure that I have the Rust-fu to make it work yet.&lt;/p&gt;
&lt;p&gt;After a discussion in the IRC room, Rust doesn’t have the Rust-fu yet either; varargs aren’t there, so this style is a no-go for now.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;Oh, and since there were no examples of this yet, &lt;a href=&quot;https://github.com/mozilla/rust/pull/6841&quot;&gt;I added some to the docs&lt;/a&gt;.&lt;/p&gt;</content:encoded></item><item><title>Upgrading from Rust 0.5 to 0.6</title><link>https://steveklabnik.com/writing/upgrading-from-rust-0-5-to-0-6/</link><guid isPermaLink="true">https://steveklabnik.com/writing/upgrading-from-rust-0-5-to-0-6/</guid><description>Here are some error messages that I got when updating Rust for Rubyists from Rust 0.5 to the new 0.6, and how to fix those errors. Error: rust.rs:1:4: 1:16 error: unresolved name rust.rs:1 use task::spawn; ^~~~~~~~~~~~ rust.rs:1:4: 1:16 error: failed to resolve import:…</description><pubDate>Sun, 07 Apr 2013 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Here are some error messages that I got when updating &lt;a href=&quot;http://www.rustforrubyists.com/&quot;&gt;Rust for Rubyists&lt;/a&gt; from Rust 0.5 to the new 0.6, and how to fix those errors.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;Error:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;rust.rs:1:4: 1:16 error: unresolved name&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;rust.rs:1 use task::spawn;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;              ^~~~~~~~~~~~&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;rust.rs:1:4: 1:16 error: failed to resolve import: task::spawn&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;rust.rs:1 use task::spawn;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;              ^~~~~~~~~~~~&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;error: failed to resolve imports&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;error: aborting due to 3 previous errors&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;make: *** [all] Error 101&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;or&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;rust.rs:1:4: 1:16 error: unresolved name&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;rust.rs:1 use io::println;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;              ^~~~~~~~~~~~&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;rust.rs:1:4: 1:16 error: failed to resolve import: io::println&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;rust.rs:1 use io::println;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;              ^~~~~~~~~~~~&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;error: failed to resolve imports&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;error: aborting due to 3 previous errors&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;make: *** [all] Error 101&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The fix:&lt;/p&gt;
&lt;p&gt;Imports are now more explicit, so you can’t just import things from &lt;code&gt;core&lt;/code&gt; without specifying that you want to any more.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;+ use core::task::spawn;- use task::spawn;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;or&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;+ use core::io::println;- use io::println;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;etc.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;Error:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;error: main function not found&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;error: aborting due to previous error&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The fix:&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;When I used to write TDD’d Rust, I wouldn’t often write a &lt;code&gt;main&lt;/code&gt; function until I had done a bunch of tests. This was okay, but now, you need one.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;+ fn main() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;+ }&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;hr&gt;
&lt;p&gt;Error:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;rustc rust.rs --test&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;rust.rs:5:2: 5:6 error: unresolved name: `fail`.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;rust.rs:5   fail;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            ^~~~&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;error: aborting due to previous error&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;make: *** [build_test] Error 101&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The fix:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;fail&lt;/code&gt; was turned into a macro. It now needs to be passed an owned pointer to a string:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;- fail;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;+ fail!(~&quot;Fail!&quot;);&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;hr&gt;
&lt;p&gt;Error:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;rust.rs:5:18: 5:26 error: unresolved name: `int::str`.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;rust.rs:5           println(int::str(num))&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                            ^~~~~~~~&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;error: aborting due to previous error&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;make: *** [build] Error 101&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The fix:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;int::str&lt;/code&gt; is now &lt;code&gt;int::to_str&lt;/code&gt;&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;- int::str&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;+ int::to_str&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;hr&gt;
&lt;p&gt;Error:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;rust.rs:5:12: 5:18 error: cannot determine a type for this local variable: unconstrained type&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;rust.rs:5     let mut answer;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                      ^~~~~~&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;error: aborting due to previous error&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;make: *** [build] Error 101&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The fix:&lt;/p&gt;
&lt;p&gt;You have to tell it what kind it is. In my case, it was a string:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;- let mut answer;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;+ let mut answer = &quot;&quot;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;hr&gt;
&lt;p&gt;Error:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;rust.rs:3:11: 3:21 error: expected `;` or `}` after expression but found `is_fifteen`&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;rust.rs:3     assert is_fifteen(15)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                     ^~~~~~~~~~&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;make: *** [build_test] Error 101&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The fix:&lt;/p&gt;
&lt;p&gt;This happens because &lt;code&gt;assert&lt;/code&gt; is now a macro.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;- assert is_fifteen(15)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;+ assert!(is_fifteen(15))&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;hr&gt;
&lt;p&gt;Error:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;rustc rust.rs&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;rust.rs:11:10: 11:24 error: the type of this value must be known in this context&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;rust.rs:11 chan.send(10);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;^~~~~~~~~~~~~~&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;error: aborting due to previous error&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;make: *** [build] Error 101&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The fix:&lt;/p&gt;
&lt;p&gt;Rust 0.6 got rid of ‘capture clauses.’ Don’t worry about it.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;- do spawn |chan| {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;+ do spawn {&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;hr&gt;
&lt;p&gt;Error:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;rust.rs:10:17: 10:21 error: expected `,` but found `chan`&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;rust.rs:10   do spawn |move chan| {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                            ^~~~&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;make: *** [build] Error 101&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The fix:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;move&lt;/code&gt; is gone. Just remove it.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;- do spawn |move chan| {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;+ do spawn |chan| {&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Note that this diff wouldn’t actually make it work, you’d still run into the issue above. But it gets rid of the &lt;code&gt;move&lt;/code&gt; error.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;Error:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;rust.rs:13:6: 13:12 error: unexpected token: `static`&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;rust.rs:13       static fn count() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                 ^~~~~~&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;make: *** [build] Error 101&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The fix:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;static&lt;/code&gt; was removed. Any method that doesn’t take &lt;code&gt;self&lt;/code&gt; is static.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;- static fn count() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;+ fn count() {&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;hr&gt;
&lt;p&gt;Error:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;rust.rs:11:30: 11:37 error: obsolete syntax: colon-separated impl syntax&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The fix:&lt;/p&gt;
&lt;p&gt;As it says, the colon syntax is gone. Replace it with &lt;code&gt;for&lt;/code&gt;:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;- impl float: Num&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;+ impl Num for float&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;hr&gt;
&lt;p&gt;Error:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;rust.rs:5:18: 5:22 error: use of undeclared type name `self`&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;rust.rs:5       fn new() -&gt; self;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                            ^~~~&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The fix:&lt;/p&gt;
&lt;p&gt;This happens when you’re making a trait, and you want the implementations to return whatever type they are. The type name is now &lt;code&gt;Self&lt;/code&gt;:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;- fn new() -&gt; self;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;+ fn new() -&gt; Self;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;hr&gt;
&lt;p&gt;I hope you found that informative! Happy hacking!&lt;/p&gt;</content:encoded></item></channel></rss>