A
Andrew Gallant
blog.burntsushi.net · Personal blog · on HN since 2012
Andrew Gallant (BurntSushi) writes about Rust, regex engines, and ripgrep, his fast command line search tool.
What HN saysHN links it for the ripgrep benchmarks and his argument that using unwrap() in Rust is acceptable, which commenters cite in error-handling debates.
141HN people shared it
101linked it in comments
53stories submitted
3.5Kstory points
3 months agolast shared
2012people per year2026
Most-shared posts
- 1Ripgrep – A new command line search tool61 people · 846 points · first shared 2016 · 209 comments on HN
- 2Finite state machines as data structure for representing ordered sets and maps27 people · 496 points · first shared 2015 · 25 comments on HN
- 3Error handling in Rust16 people · 191 points · first shared 2015 · 139 comments on HN
- 4Regex Engine Internals as a Library7 people · 73 points · first shared 2023 · 5 comments on HN
- 5Using unwrap() in Rust is Okay (2022)6 people · 60 points · first shared 2025 · 52 comments on HN
- 6Writing type parametric functions in Go6 people · 9 points · first shared 2013 · 1 comments on HN
- 7My FOSS Story5 people · 922 points · first shared 2020 · 200 comments on HN
- 8Ripgrep is faster than {grep, ag, Git grep, ucg, pt, sift}5 people · 1 points · first shared 2025 · discussion on HN
- 9A byte string library for Rust4 people · 288 points · first shared 2022 · 72 comments on HN
- 10Using unwrap() in Rust is okay4 people · 212 points · first shared 2022 · 197 comments on HN
- 11Syntax extensions and regular expressions for Rust4 people · 169 points · first shared 2014 · 25 comments on HN
- 12Index 1.6B Keys with Automata and Rust (2015)4 people · 65 points · first shared 2024 · 6 comments on HN
- 13Rust and CSV parsing3 people · 121 points · first shared 2017 · 23 comments on HN
- 14NFL live statistics with Python3 people · 1 points · first shared 2012 · discussion on HN
- 15Homepage3 people · first shared 2025
What HN people wrote when they linked it
lenkite · 2025-11-26
ON HN, just a couple of years ago, a famous Rust programmer said that it is OK to use unwrap. Rustaceans supported this position. Cloudflare merely followed the community standard.
Using unwrap() in Rust is Okay
https://news.ycombinator.com/item?id=32385102 https://burntsushi.net/unwrap/
drob518 · 2025-10-19
This blog post is also great reading.
https://burntsushi.net/ripgrep/
nicce · 2025-03-11
Classic post where ripgrep is faster than ag, so maybe that does not matter: https://burntsushi.net/ripgrep/
burntsushi · 2025-03-08
My position is articulated here, with real examples: https://burntsushi.net/unwrap/
> Just to be clear, you are making the argument that when a library call detects an error of the form of unexpected NULL/not-NULL, that they abort immediately?
There's no blanket answer here because your scenario isn't specific enough. Is the pointer caller provided? Is the pointer entirely an internal detail whose invariant is managed internally? Is this pointer access important for perf? Is the pointer invariant encapsulated by something else?
Instead, I suggest showing examples of C libraries following your philosophy. Then we'll have something concrete.
In the comment I linked, you'll noticed that I actually looked at and reviewed real code examples. Maybe you could engage with those.
camgunz · 2024-05-17
I'm referring to #2 there: "In ASCII compatible mode, Unicode character classes are not allowed."
> Pretty much all string processing I've built up in Rust over the past ten years is based on the idea of not validating up front. It's too costly to do. There's an entire section in my blog post on bstr about this: https://blog.burntsushi.net/bstr/#motivation-based-on-perfor...
Yeah I read it; it's very good! (like everything you write) I think you're right that you can't handwave away the validation overhead, and that in some cases it matters. I just think ripgrep is pretty niche: there's gazillions of websites out there and like, 10 greps. If you're writing a grep and you want to optimize the shit out of it, well welcome to working around not validating. Otherwise, the safety tradeoffs and weirdo lack of specification aren't worth it.
marvin-hansen · 2023-11-01
There is an excellent FST implementation in Rust:
https://blog.burntsushi.net/transducers/
Xeoncross · 2023-02-28
If you think this is great and/or immediately thought of using a trie to reduce storage costs, then let me introduce you to https://blog.burntsushi.net/transducers/ which pushes storage reuse over the edge to almost competing with compression like gzip while still allowing you to consider edit distance while finding possible alternatives.
typeaheads/autocomplete and spellchecking both need this so worth a read.
paulgdp · 2021-11-22
Having read a great deal from him, I just want to confirm everything said about Andrew Gallant, and I absolutely trust him too!
This blog post is a great testament to his human skills:
https://blog.burntsushi.net/foss/
nindalf · 2021-07-22
It’s funny you should mention ripgrep (text search in Rust) in particular because it’s a great example of a tool being reused in other environments. It could be used with C bindings or by calling the binary. The latter is how Visual Studio Code integrates it. It’s a win for everyone if the fastest grep tool (benchmarks - https://blog.burntsushi.net/ripgrep/) is used widely.
kevincox · 2021-06-14
This post by the author is a great introduction to the techniques used in ripgrep https://blog.burntsushi.net/ripgrep/
forgotpwd16 · 2021-03-23
For anyone interested there're a few such tools that are modern alternatives to traditional Unix utilities. Interestingly all written in Rust.
grep -> ripgrep (command `rg`)
find -> fd
sed -> sd
diff -> delta
ls -> exa && lsd
cat -> bat
wc -> cw
du -> dust
ps -> procs
top -> ytop (**edit** archived; author recommends `bottom`)
They all offer their own modern take but I'll say the first two, which are the only ones I'm using, are the most interesting. Both ripgrep and fd offer easier usage. The ripgrep is also an ack replacement and fd can also replace parallel (even has compatible syntax). The amazing part is that both are an order of magnitude faster their counterparts. The ripgrep dev has extended analysis for how this is achieved on their blog[0].
[0]: https://blog.burntsushi.net/ripgrep/
gsserge · 2021-02-11
> I recommend this blog post: https://nick.groenen.me/posts/rust-error-handling/
This blog post is good indeed. The discussion on /r/rust linked at the end of the post is also worth reading.
Another good and light introduction is http://www.sheshbabu.com/posts/rust-error-handling/
And a more in-depth look https://blog.burntsushi.net/rust-error-handling/
cben · 2020-09-06
https://blog.burntsushi.net/ripgrep/ explains in detail _how_ it's so fast, and is a great reading on practical performance engineering.
The interface is nearly 1:1 with `ag` (and the older `ack`).
One notable difference is that ag enables `--smart-case` by default, so it treats an all-lowercase pattern as case-insensitive, while `rg` doesn't, you need an explicit `rg -i`.
(or set it in a config file, but I'd rather not learn defaults that won't work out-of-the-box on other machines).
ignoramous · 2020-07-28
Recommended reading on FST for the curious: https://blog.burntsushi.net/transducers/
miccah · 2020-07-19
As a beginner to Rust, this blog post has been excellent, and it has really helped me understand the idiomatic way to handle errors.
https://blog.burntsushi.net/rust-error-handling/
sqs · 2019-04-16
Ripgrep is awesome. Thank you for making it!
In addition to being really fast, it "just works". By that I mean it automatically excludes the files I want to be excluded, like `.gitignore`d files and binary files. I know I can configure ack-grep (ag) and other tools to do that, but not needing to configure it is nice.
BTW, if anyone hasn't read https://blog.burntsushi.net/ripgrep/, highly recommended. It's about how ripgrep is so fast. (Edit: Just saw another comment mentioned this, too. Goes to show that making a single high-quality blog post has a big impact.)
sevensor · 2019-03-13
I recommend reading https://blog.burntsushi.net/ripgrep/
I've read masters theses that were significantly less thorough and well-researched.
dfabulich · 2018-09-08
It'd be great if you'd go back and update your blog post https://blog.burntsushi.net/ripgrep/ now that so many of the "anti-pitch" bullets are fixed (and I can only assume that the numbers have changed in the last two years)
cmyr · 2018-09-04
Another great post on this topic, by the other of ripgrep: https://blog.burntsushi.net/transducers/
steveklabnik · 2018-07-26
We talk about it a little, but the best resource on this topic by far is https://blog.burntsushi.net/rust-error-handling/ which works the whole way from first principles. It was in the first edition of the book but due to space requirements didn’t really fit in the second edition.
lillesvin · 2018-06-06
As much as I love `ag`, I feel like ripgrep (https://github.com/BurntSushi/ripgrep) deserves mentioning when it comes to speed. If you haven't tried it, do it sooner rather than later.
Here's an excellent write-up on how it works, benchmarks, etc.: https://blog.burntsushi.net/ripgrep/
JelteF · 2017-10-09
It is definitely faster. The ripgrep author did extremely extensive benchmarking to a lot of tools. For the most common usecase check out this section, but the rest of the article is very much worth a read as well: http://blog.burntsushi.net/ripgrep/#subtitles-literal
whyever · 2017-09-04
It's a lot faster. See http://blog.burntsushi.net/ripgrep.
> Notably absent from this list is ack. We don’t benchmark it here because it is outrageously slow. Even on the simplest benchmark (a literal in the Linux kernel repository), ack is around two orders of magnitude slower than ripgrep. It’s just not worth it.
andy_ppp · 2017-09-04
Wow, rg looks fantastic! Will try it today I think...
http://blog.burntsushi.net/ripgrep/
mschoch · 2017-03-16
Might be using non-standard notation, I just followed what I saw used here: http://blog.burntsushi.net/transducers/
The values after the / are the output values associated with the transition.
Weighted finite state transducers are not supported.
craftkiller · 2015-05-27
Error Handling in Rust by Andrew Gallant is easily the best tutorial I've read in the past year. Very clear explanations with examples walking through the reasoning step by step.
http://blog.burntsushi.net/rust-error-handling/
imrehg · 2013-03-29
I think they should be all fine. Here's some others' info about it, partly from the (excellent) Arch Wiki, and from a blog:
https://wiki.archlinux.org/index.php/ThinkPad_X230
https://wiki.archlinux.org/index.php/Lenovo_ThinkPad_X1
http://blog.burntsushi.net/lenovo-thinkpad-t430-archlinux
osiris88 · 2025-12-28
> I wrote about how to do error handling without libraries literally the day Rust 1.0 was published: https://burntsushi.net/rust-error-handling/
>
> That blog did include a recommendation for `failure` at one point, and now `anyhow`, but it's more of a footnote. The blog shows how to do error handling without any dependencies at all. You didn't have to jump on the error library treadmill. (Although I will say that `anyhow` and `thiserror` have been around for a number of years now and shows no signs of going away.)
Thank you -- I just wanna say, I read a lot of your writing and I love your work. I'm not sure if I read that blog post so many years ago but it looks like a good overview that has aged well.
> I happily downcast in ripgrep: https://github.com/BurntSushi/ripgrep/blob/0a88cccd5188074de...
>
> That also shows the utility of an error chain.
Yeah, I mean, that looks pretty nice.
I still think the error chain abstraction should actually be a tree.
And I think they should never have stabilized an `std::error::Error` trait that was not in core. I think that itself was a mistake. And 8 years later we're only now maybe able to get there.
I actually said something on a github issue about this before rust 1.0 stabilization, and that it would cause an ecosystem split with embedded, and that this really should be fixed, but my comment was not well received, and obviously didn't have much impact. I'll see if I can find it, it's on github and I remember withoutboats…
nextaccountic · 2025-04-06
The ? operator has implicit error conversion. As another user said, it usses the From trait which performs conversions between one type and another. (Note that generally in Rust type conversions don't happen implicitly and you need to call .into() -- the ? situation is an exception)
If you want to have more finer grained control on the error conversion (the From conversion is always the same for some pair of error types) you can use map_err before calling ?, like something.map_err(|e| othererror)?
https://doc.rust-lang.org/std/result/enum.Result.html#method.map_err
If you are using anyhow and wants to attach a string message to the error (maybe to explain what happened to the user), you can also use .context(), also called .wrap_err() in eyre (eyre is a fork of anyhow)
https://docs.rs/anyhow/latest/anyhow/trait.Context.html
https://docs.rs/eyre/latest/eyre/trait.WrapErr.html
The following article is ten years old, but was continually updated to keep it fresh and I think it does a good job explaining how error handling works in Rust:
https://burntsushi.net/rust-error-handling/
luizfelberti · 2023-07-19
Depends on where you draw the line of what a parser is:
- If the parser is "the thing that comes after the lexer" then all of this is abstracted away by the lexer and you can just treat it as a span of bytes;
- If the parser is "everything that needs to be implemented to correctly transduce the input sequence into a tree", then you need to implement this yourself or have a lexer that handles this for you, usually done by having a tiny UTF-8 codepoint recognizing FSM in your lexer (UTF-8 is a self-synchronizing code, which makes this part easier) and ignoring the existence of graphemes.
Most people, however, shy away from implementing a parser "all the way down to the bytes" and properly handling UTF-8 as a formal language. Most lean on a lexer abstracting this away. Ditto for context-sensitivity.
Recently Rust's regex engine underwent a major overhaul, and burntsushi wrote a blog post[0] about doing the "all the way to the bytes" thing in the new regex engine, I highly recommend the read:
[0] https://blog.burntsushi.net/regex-internals/#nfa-optimization-minimal-…