Skip to content

Commit

Permalink
Bonus 13: I Still Make Silly Mistakes
Browse files Browse the repository at this point in the history
  • Loading branch information
chriskrycho committed Feb 28, 2019
1 parent e1d5323 commit 02e5ef6
Show file tree
Hide file tree
Showing 4 changed files with 546 additions and 2 deletions.
114 changes: 114 additions & 0 deletions docs/bonus/13-silly-mistakes.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
# Bonus: I Still Make Silly Mistakes

Hello, I’m Chris Krycho and this is New Rustacean: a show about the Rust programming language and the people who use it. This is a bonus episode: I Still Make Silly Mistakes.

## Sponsor: Parity

First up, Parity is back sponsoring the show again because they want *you* to come write Rust with them! Parity is advancing the state of the art in decentralized technology, and they’re using Rust to do it, leaning hard on its trifecta of performance, reliability, and productivity. They're building cutting-edge tech in areas like WebAssembly and peer-to-peer networking. Two of the larger projects they're working on are: Substrate, a framework for building blockchains, and Polkadot, a platform leveraging blockchain tech for scaling and interoperability in decentralized systems.

If that sounds interesting, check out their jobs at <parity.io/jobs>!

## That mistake…

So, the mistake I titled this episode after. Every time I draft an episode of New Rustacean, I start by writing out a script for it, long-form, in my preferred Markdown editor. (You can find those scripts in the show notes!) When I record the show, I’m reading that script—usually with some minor improvisation. One of the things I do as I’m writing is include links inline in the script. I do that for two reasons:

- first, so that anyone who is reading the script has an easy way to link to the things I’m talking about throughout the episode
- and second, so that when I pull that script over into the repository for the show, I can just pull those links out and put them in the show notes

The first part works fine. Pulling the links out for the show notes has increasingly annoyed me, though: I have to go through and manually pull out each link from the text, and while that’s not a *ton* of work, it’s repetitive and error-prone. And “repetitive and error-prone” is basically the working definition of what software is good at! So I figured: hey, here’s a chance to play with a couple data structures I’ve not spent much time with in Rust and get more familiar with the [pulldown-cmark](https://github.com/raphlinus/pulldown-cmark) crate, which has a nice API for dealing with Markdown!

(As I mentioned in Part I of the Rust 1.31 and 2018 Edition news episode, I basically default to Rust for these tasks at this point: it takes me about the same amount of time as doing in a scripting language would, and I enjoy it a lot more.)

So I did what I normally do in these kinds of situations and ran `cargo new extract-md-links`. I pulled in the `pulldown-cmark` in my `cargo.toml`, and debated whether I wanted to pull in [the `structopt` crate](https://github.com/TeXitoi/structopt) for command-line argument handling—and decided against it because I figured: all I need to be able to do is pass in a single argument and this is a private tool for my very specific niche problem. No problem; I’ve parsed arguments from the command line manually for over a decade!

Right?

Wrong!

I whipped up my main function and started trying to load a test document to start on the link extraction, figuring that would be the meat of this particular little problem. And then I started seeing an error that made *no* sense to me: `"stream did not contain valid UTF-8"`.

What.

Look: I *know* this file is valid UTF-8. It’s a blog post that currently runs through a Python-powered static site generator; it wouldn’t even have successfully published if it were *not* valid UTF-8. What's more: the file opens as valid UTF-8 in Visual Studio Code and Sublime Text. It validates properly as UTF-8 when I dump it into an online UTF-8 validator. It loads properly if I open a Python REPL and load the exact same path I was passing to my little Rust tool!

At this point, as you can probably imagine, I started to feel like I was losing my mind. I hopped into the Rust Discord channel and started asking *really* basic questions about the things I was seeing. As an aside, if you've never just hopped into one of the Rust chat communities online, you should do that the next time you get stuck. And the rest of this story is a great example of *why*, but the short version is that the Rust community is *incredibly* helpful. Even for silly problems where the question-asker really ought to know better! But we'll get to that.

So I started describing my problem, and a few other Rust users—especially @alercah—started asking helpful questions and offering helpful comments about the file I was trying to work with:

- **What’s the first byte?** So instead of running `std::fs::read_to_string`, I used `std::fs::read`, which gives you back a `Vec<u8>` if it succeeds. It succeeded, so dumped the first byte.
- **That doesn’t seem right; what’s the *second* byte?** At this point I just grabbed the first *eight* bytes the same way and shared those.
- **Those are definitely not valid unicode. What’s the file?** I linked directly to the file I was trying to load from my blog source on GitHub.
- **That file starts with different bytes than the bytes your Rust program is reporting.** And indeed, it started with the bytes I’d have expected: three hyphens (which are what start a block of YAML metadata for my blog posts).

That last point had me *truly* confused. How in the world could two different people read the same file and get different results? And this of course was the key to the whole thing. But I'm getting ahead of myself again.

My next step was to just dump the minimal set of code to reproduce this program straight into a code block in Discord, along with the actual Cargo command I was running and the actual error I was seeing. And then @alercah spotted my problem, and it turned out it had nothing at all to do with the file I thought, or with unicode at all. My problem was simply that I was *opening the wrong file*.

You see, the first argument to a program is always the name of the program itself. There’s good reason for this; I’ve linked [an interesting discussion][unix] in the show notes (using this tool, which now works!) about why you might want the same program to be able to be called with different names and do different things in those circumstances. That's all just fine and dandy. Except that I was thinking the first argument would be the thing I was passing to the program: the path to the file I wanted to process. Instead, it was, you know: not unicode. Because it was a binary: the Rust program I was running! Once I grabbed the *second* argument, not the *first*, everything just worked exactly the way I expected.

[unix]: https://unix.stackexchange.com/questions/315812/why-does-argv-include-the-program-name "Why does argv include the program name?"

So that's what happened *technically*, that's the bug. But, and this is the actually interesting part of this experience, I think: you may recall my comment a minute ago that I’ve been doing this—parsing command line arguments—for over a decade! And I mean that literally: I first parsed command line arguments manually in Fortran and Java programs in 2008. This is a quote-unquote “rookie mistake.” And I laughed *really* hard at myself when I realized what had happened because it's such a "rookie mistake"!

But of course, that phrase is really misleading. “Rookie mistake” suggests that these kinds of mistakes are specific to rookies, and the reality is that they *aren’t*. I'm not a rookie a decade in, at least not at this particular thing. But these kinds of things happen to all of us. And "these kinds of things" are just mistakes that come from *unfamiliarity*. Being new to programming entirely is one reason you might be unfamiliar with something. But just being rusty—no pun intended!—is another reason you might be unfamiliar with something! I haven’t had to hand-parse an argument in about five or six years, because I’ve been using something like [Python’s `argparse` library][argparse], or [Commander in Node][commander], or [clap] and [structopt] in Rust! And that meant it was easy to forget this kind of thing because I just hadn’t had to do it manually for such a long time. So that was the first reminder: *everyone* makes "rookie mistakes," because they're not really *rookie* mistakes; they're unfamiliarity mistakes.

[argparse]: https://docs.python.org/3.7/library/argparse.html#module-argparse
[commander]: https://github.com/tj/commander.js
[clap]: https://clap.rs
[structopt]: https://github.com/TeXitoi/structopt

The second good reminder for me in this was actually from the feeling of frustration itself. It reminded me of what it’s like to be just starting out—to be a rookie!—to be looking at a compiler message that seems like it’s trying really hard to be helpful, but which is clearly telling you something that isn’t *exactly* the problem: it's not the *root* of the problem. “Yes, it’s true," I was saying, "that this is not unicode. But I have no idea *why* it isn’t unicode!” And even when you’re a decade along in your career and have generally developed a reasonable set of debugging techniques and intuitions about why things go wrong, things like this can be totally mystifying—still! And this should remind us—it reminded me—to be sympathetic to people just getting started—because even things which are totally obvious to us can be genuinely confusing to newcomers, *or even to us ourselves* with just a little distance from the specific expertise we’ve developed!

## Outro

Anyway, that’s my fun story and my two takeaways about a silly mistake I made recently; I hope it’s helpful and encouraging when you make your own silly mistakes or when you see someone make what seems like a silly mistake!

Thanks as always to this month’s $10-or-more sponsors:

- Soren Bramer Schmidt
- Graham Wihlidal
- Benjamin Manns
- Matt Rudder
- Bryan Stitt
- Brian McCallister
- Evan Stoll
- Oluseyi Sonaiya
- Nathan Sculli
- Ryan Osial
- Martin Heuschober
- Andrew Dirksen
- Daniel Collin
- Daniel Mason
- Dan Abrams
- Nick Gideo
- Behnam Esfahbod
- Scott Moeller
- Adam Green
- Nicolas Pochet
- Alexander Payne
- Nick Stevens
- Peter Tillemans
- Michael Mc Donnell
- James Hagans II
- Joseph Schrag
- Raph Levien
- Chris Palmer
- Anthony Deschamps
- David Carroll
- Jerome Froelich
- John Rudnick
- Jason Bowen
- Ramon Buckland
- Embark Studios
- Johan Andersson
- Jonathan Knapp
- Rob Tsuk
- Jako Danar
- Paul Naranja
- Chip

You can sponsor the show at patreon.com/newrustacean or via other services listed on the show website, <newrustacean.com>. There, you’ll also find show notes, including links to things I talk about, scripts, code samples, and interview transcripts. The notes for *this* episode are at <newrustacean.com/show_notes/bonus/_13/>.

Please recommend the show to others if you like it, whether in person, via your podcast directory, or in various media online! You can contact me at @chriskrycho or @newrustacean on Twitter, or by sending men an email at [email protected].

Until next time, happy coding!
180 changes: 178 additions & 2 deletions resources/feed.xml
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@
<copyright>2015–2019 Chris Krycho</copyright>
<managingEditor>[email protected] (Chris Krycho)</managingEditor>
<webMaster>[email protected] (Chris Krycho)</webMaster>
<pubDate>Thu, 21 Feb 2019 21:26:16 -0700</pubDate>
<lastBuildDate>Thu, 21 Feb 2019 21:26:17 -0700</lastBuildDate>
<pubDate>Thu, 28 Feb 2019 07:23:51 -0700</pubDate>
<lastBuildDate>Thu, 28 Feb 2019 07:23:52 -0700</lastBuildDate>
<image>
<url>http://newrustacean.com/podcast.png</url>
<title>New Rustacean</title>
Expand Down Expand Up @@ -40,6 +40,182 @@
<itunes:category text="Training"/>
</itunes:category>
<itunes:type>episodic</itunes:type>
<item>
<title>Bonus 13: I Still Make Silly Mistakes</title>
<link>http://newrustacean.com/show_notes/bonus/_13/</link>
<description><![CDATA[<p>A story about parsing command-line arguments manually and some thoughts on “rookie mistakes.”</p>
<h2 id="show-notes">Show Notes</h2>
<ul>
<li><a href="https://unix.stackexchange.com/questions/315812/why-does-argv-include-the-program-name" title="Why does argv include the program name?">why you might want to invoke the same program with different names</a></li>
<li><a href="https://docs.python.org/3.7/library/argparse.html#module-argparse">Python’s argparse library</a></li>
<li><a href="https://github.com/tj/commander.js">Commander in Node</a></li>
<li><a href="https://clap.rs">clap</a></li>
<li><a href="https://github.com/TeXitoi/structopt">structopt</a></li>
<li><a href="https://github.com/raphlinus/pulldown-cmark">pulldown-cmark</a></li>
</ul>
<h2 id="sponsors">Sponsors</h2>
<p>Thanks to <a href="https://www.parity.io/jobs">Parity</a> for sponsoring the show and hiring Rust developers!</p>
<h3 id="patreon-sponsors">Patreon Sponsors</h3>
<ul>
<li>Adam Green</li>
<li>Aleksey Pirogov</li>
<li>Alexander Kryvomaz</li>
<li>Alexander Lozada</li>
<li>Alexander Payne</li>
<li><a href="https://github.com/bddap">Andrew Dirksen</a></li>
<li>Andrew Thompson</li>
<li><a href="https://github.com/adeschamps">Anthony Deschamps</a></li>
<li>Anthony Scotti</li>
<li>Arlen Haftevani</li>
<li><a href="https://asonix.dog/@asonix">Arlo (Hyena)</a></li>
<li><a href="https://github.com/behnam">Behnam Esfahbod</a></li>
<li><a href="https://www.benmanns.com/">Benjamin Manns</a></li>
<li>Benjamin Wasty</li>
<li>Brandon ‘Spanky’ Mills</li>
<li>Brian Casiello</li>
<li>Brian Manning</li>
<li><a href="https://skife.org/">Brian McCallister</a></li>
<li><a href="http://www.stitthappens.com/">Bryan Stitt</a></li>
<li>Caryn Finkelman</li>
<li>Cass Costello</li>
<li>Cat Dad</li>
<li>Chap Lovejoy</li>
<li><a href="https://charlieegan3.com">Charlie Egan</a></li>
<li>Chip</li>
<li><a href="http://home.red-oxide.org/">Chris Palmer</a></li>
<li>Christoffer Ceutz</li>
<li>Dan Abrams</li>
<li>Daniel</li>
<li>Daniel Bross</li>
<li><a href="https://twitter.com/daniel_collin">Daniel Collin</a></li>
<li><a href="https://github.com/gisleburt">Daniel Mason</a></li>
<li>David Carroll</li>
<li>David Hewson</li>
<li><a href="https://twitter.com/derekmorr">Derek Morr</a></li>
<li>Doug Reeves</li>
<li><a href="http://learnrust.io/">Douglas Correa</a></li>
<li><a href="https://github.com/edvorg">Eduard Knyshov</a></li>
<li><a href="https://www.embark-studios.com">Embark Studios</a></li>
<li>Eugene Bulkin</li>
<li><a href="https://decathorpe.com/">Fabio (decathorpe)</a></li>
<li><a href="https://twitter.com/gaveen">Gaveen Prabhasara</a></li>
<li><a href="https://wihlidal.com/">Graham Wihlidal</a></li>
<li><a href="https://hsivonen.fi/">Henri Sivonen</a></li>
<li><a href="https://www.ianmjones.com/">Ian Jones</a></li>
<li>Hoàng Đức Hiếu</li>
<li>“Jake”“ferris”" Taylor"</li>
<li>Jako Danar</li>
<li>James Cooper</li>
<li>James Hagans II</li>
<li><a href="https://twitter.com/jwbowen">Jason Bowen</a></li>
<li><a href="https://www.jendrikillner.com/">Jendrik Illner</a></li>
<li>Jerome Froelich</li>
<li><a href="http://github.com/joar">Joar Wandborg</a></li>
<li><a href="https://www.embark-studios.com">Johan Andersson</a></li>
<li><a href="http://www.cindur.com/">John Rudnick</a></li>
<li>Jon</li>
<li>Jonah</li>
<li><a href="https://www.coffeeandcode.com/">Jonathan Knapp</a></li>
<li>Jonathan Turner</li>
<li>Joseph Hain</li>
<li>Joseph Mou</li>
<li>Joseph Schrag</li>
<li><a href="http://joetdc.com/">Joe Percy</a></li>
<li>Justin Ossevoort</li>
<li>Kai Yao</li>
<li>Kazutaka Mise</li>
<li>Keith Gray</li>
<li>Kilian Rault</li>
<li>Lee Jenkins</li>
<li>Luca Schmid</li>
<li><a href="http://luizirber.org/">Luiz Irber</a></li>
<li>Lukas Eller</li>
<li><a href="https://twitter.com/Malnormalulo">Malnormalulo</a></li>
<li><a href="https://github.com/epsilonhalbe">Martin Heuschober</a></li>
<li>Masashi Fujita</li>
<li>Matt Rudder</li>
<li>Matthew Brenner</li>
<li>Matthias Ruszala</li>
<li><a href="https://twitter.com/maxjacobson">Max Jacobson</a></li>
<li>Max R.R. Collada</li>
<li><a href="https://github.com/messense">Messense Lv</a></li>
<li>Micael Bergeron</li>
<li><a href="https://www.linkedin.com/in/michaelmcdonnell/">Michael Mc Donnell</a></li>
<li><a href="https://www.michaelmelanson.net">Michael Melanson</a></li>
<li>Michael Sanders</li>
<li><a href="http://influential.co/">Nathan Sculli</a></li>
<li><a href="http://github.com/ncoish">Nick Coish</a></li>
<li>Nick Gideo</li>
<li><a href="https://github.com/nastevens">Nick Stevens</a></li>
<li><a href="https://github.com/n-pochet">Nicolas Pochet</a></li>
<li>Olaf Leidinger<br />
</li>
<li>Oliver Uvman</li>
<li><a href="http://oluseyi.info/">Oluseyi Sonaiya</a></li>
<li>Ovidiu Curcan</li>
<li><a href="https://pascalhertleif.de/">Pascal</a></li>
<li><a href="https://twitter.com/patrickod">Patrick O’Doherty</a></li>
<li>Paul Naranja</li>
<li>Paul Osborne</li>
<li>Peter Scholtens</li>
<li>Peter Tillemans</li>
<li>Pierre-Antoine Champin</li>
<li>Ralph Giles</li>
<li><a href="http://www.inosion.com">Ramon Buckland</a></li>
<li>Randy MacLeod</li>
<li>Raph Levien</li>
<li>Richard Dallaway</li>
<li>Rob Tsuk</li>
<li><a href="https://github.com/RobbieClarken/">Robbie Clarken</a></li>
<li>Robert Chrzanowski</li>
<li><a href="http://notryanb.github.io/">Ryan Blecher</a></li>
<li><a href="https://github.com/osialr">Ryan Osial</a></li>
<li>Scott Moeller</li>
<li><a href="https://www.twitter.com/sebasmagri">Sebastián Ramírez Magrí</a></li>
<li><a href="https://www.simonhdickson.com/">Simon Dickson</a></li>
<li>Simon G</li>
<li><a href="http://prisma.io/">Soren Bramer Schmidt</a></li>
<li>Steve Jenson</li>
<li>Steven Knight</li>
<li>Steven Murawski</li>
<li><a href="http://stuarth.github.io/">Stuart Hinson</a></li>
<li>Tim Brooks</li>
<li>Tim Süberkrüb</li>
<li>Tom Prince</li>
<li>Toolmaker’s Guild</li>
<li>Ty Overby</li>
<li>Tyler Harper</li>
<li>Victor Kruger</li>
<li>Will Greenberg</li>
<li><a href="http://willroe.me">William Roe</a></li>
<li>Zak van der Merwe</li>
<li>Zachary Snyder</li>
<li>Zaki</li>
</ul>
<p>(Thanks to the couple people donating who opted out of the reward tier, as well. You know who you are!)</p>
<h3 id="become-a-sponsor">Become a sponsor</h3>
<ul>
<li><a href="https://www.patreon.com/newrustacean">Patreon</a></li>
<li><a href="https://venmo.com/chriskrycho">Venmo</a></li>
<li><a href="https://www.dwolla.com/hub/chriskrycho">Dwolla</a></li>
<li><a href="https://cash.me/$chriskrycho">Cash.me</a></li>
<li><a href="https://flattr.com/profile/chriskrycho">Flattr</a></li>
<li><a href="https://paypal.me/chriskrycho">PayPal.me</a></li>
</ul>
<h2 id="contact">Contact</h2>
<ul>
<li>New Rustacean: + Twitter: <a href="https://www.twitter.com/newrustacean">@newrustacean</a> + Email: <a href="mailto:[email protected]">[email protected]</a></li>
<li>Chris Krycho + GitHub: <a href="https://github.com/chriskrycho">chriskrycho</a> + Twitter: <a href="https://www.twitter.com/chriskrycho">@chriskrycho</a></li>
</ul>
]]></description>
<pubDate>Thu, 28 Feb 2019 07:20:00 -0700</pubDate>
<enclosure url="https://www.podtrac.com/pts/redirect.mp3/f001.backblazeb2.com/file/newrustacean/bonus/13.mp3" length="11766492" type="audio/mpeg"/>
<guid isPermaLink="false">09C99DA4-0275-4128-BE30-26442421BE86</guid>
<itunes:subtitle>A story about parsing command-line arguments manually and some thoughts on “rookie mistakes.”</itunes:subtitle>
<itunes:summary>A story about parsing command-line arguments manually and some thoughts on “rookie mistakes.”</itunes:summary>
<itunes:duration>12:13</itunes:duration>
<itunes:episodeType>full</itunes:episodeType>
</item>
<item>
<title>e028: Meet My Associates</title>
<link>http://newrustacean.com/show_notes/e028/</link>
Expand Down
Loading

0 comments on commit 02e5ef6

Please sign in to comment.