<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
  <title>eli.thegreenplace.net</title>
  <subtitle>Browse aymeric&#39;s, an independent, searchable archive of readable snapshots from followed feeds, preserved in Git with aggr.</subtitle>
  <id>https://aggr.aymericbeaumet.com/sources/eli.thegreenplace.net/</id>
  <link rel="alternate" type="text/html" href="https://aggr.aymericbeaumet.com/sources/eli.thegreenplace.net/"/>
  <link rel="self" type="application/atom+xml" href="https://aggr.aymericbeaumet.com/sources/eli.thegreenplace.net/atom.xml"/>
  <updated>2026-10-13T18:11:46+00:00</updated>
  <author>
    <name>aymeric&#39;s</name>
  </author>
  <generator version="2.0.0" uri="https://github.com/aymericbeaumet/aggr">aggr</generator>
  <entry>
    <id>urn:aggr:item:ab798f54808d375331d2bc144f2b720b8a80eca3</id>
    <title type="text">Monte-Carlo Simulations</title>
    <link rel="alternate" type="text/html" href="https://aggr.aymericbeaumet.com/items/hnrss-org/2026-10-13-monte-carlo-simulations/"/>
    <link rel="via" type="text/html" href="https://eli.thegreenplace.net/2026/monte-carlo-simulations/"/>
    <published>2026-10-13T18:11:46+00:00</published>
    <updated>2026-10-13T18:11:46+00:00</updated>
    <author>
      <name>ibobev</name>
    </author>
    <category term="news"/>
    <source>
      <title>Hacker News: Front Page</title>
    </source>
    <summary type="text">Monte Carlo simulations (or methods) is the technique of applying randomness and the Law of large numbers to the solution of various scientific and engineering problems. One of its first documented uses was by Stanislaw Ulam and John von…</summary>
    <content type="html">&lt;p&gt;Monte Carlo simulations (or &lt;em&gt;methods&lt;/em&gt;) is the technique of applying randomness and the &lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://en.wikipedia.org/wiki/Law_of_large_numbers&quot;&gt;Law of large numbers&lt;/a&gt; to the solution of various scientific and engineering problems. One of its first documented uses was by Stanislaw Ulam and John von Neumann for nuclear weapon simulations after WWII &lt;sup class=&quot;citation-ref&quot;&gt;&lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://eli.thegreenplace.net/2026/monte-carlo-simulations/#footnote-1&quot;&gt;[1]&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;p&gt;In this post I want to provide examples of some simple uses of Monte Carlo simulations. We&#39;ll start with the classical example of calculating the value of by throwing darts.&lt;/p&gt;
&lt;h2&gt;Estimating pi&lt;/h2&gt;
&lt;p&gt;Suppose we take a square board and inscribe a quarter of a circle into it. We then proceed to throw darts at the board and record whether each dart hits inside or outside the quarter circle. Having thrown many such darts, we calculate the ratio of the darts inside the circle to the total number thrown.&lt;/p&gt;
&lt;p&gt;Assuming our darts are distributed uniformly over the square, by the Law of large numbers this ratio should approach the ratio of areas of the quarter circle to the full square .&lt;/p&gt;
&lt;p&gt;With a square side length of 1, we have:&lt;/p&gt;
&lt;p&gt;Therefore:&lt;/p&gt;
&lt;p&gt;Here&#39;s a visualization:&lt;/p&gt;
&lt;p&gt;A quarter circle of radius 1 inside a unit square.&lt;/p&gt;
&lt;p&gt;Samples 200&lt;/p&gt;
&lt;p&gt;10 1000&lt;/p&gt;
&lt;p&gt;π ≈ —&lt;/p&gt;
&lt;p&gt;Change the number of samples (dart throws) and click &amp;quot;Run&amp;quot; to regenerate. The code is very simple - here&#39;s a slightly sanitized version:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;code-snippet&quot; data-language=&quot;JavaScript&quot;&gt;&lt;span class=&quot;syntax-source syntax-js&quot;&gt;&lt;span class=&quot;syntax-storage syntax-type syntax-js&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;syntax-variable syntax-other syntax-readwrite syntax-js&quot;&gt;total&lt;/span&gt; &lt;span class=&quot;syntax-keyword syntax-operator syntax-assignment syntax-js&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;syntax-meta syntax-function-call syntax-js&quot;&gt;&lt;span class=&quot;syntax-variable syntax-function syntax-js&quot;&gt;Number&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-js&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-js&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-variable syntax-other syntax-object syntax-js&quot;&gt;samples&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-accessor syntax-js&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-property syntax-object syntax-js&quot;&gt;value&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-js&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-js&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-terminator syntax-statement syntax-js&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;syntax-storage syntax-type syntax-js&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;syntax-variable syntax-other syntax-readwrite syntax-js&quot;&gt;inside&lt;/span&gt; &lt;span class=&quot;syntax-keyword syntax-operator syntax-assignment syntax-js&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;syntax-constant syntax-numeric syntax-js&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-terminator syntax-statement syntax-js&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;syntax-meta syntax-for syntax-js&quot;&gt;&lt;span class=&quot;syntax-keyword syntax-control syntax-loop syntax-js&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;syntax-meta syntax-group syntax-js&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-js&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-storage syntax-type syntax-js&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;syntax-variable syntax-other syntax-readwrite syntax-js&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;syntax-keyword syntax-operator syntax-assignment syntax-js&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;syntax-constant syntax-numeric syntax-js&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-terminator syntax-statement syntax-js&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;syntax-variable syntax-other syntax-readwrite syntax-js&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;syntax-keyword syntax-operator syntax-relational syntax-js&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;syntax-variable syntax-other syntax-readwrite syntax-js&quot;&gt;total&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-terminator syntax-statement syntax-js&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;syntax-variable syntax-other syntax-readwrite syntax-js&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;syntax-keyword syntax-operator syntax-arithmetic syntax-js&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-js&quot;&gt;)&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;syntax-meta syntax-block syntax-js&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-block syntax-js&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;syntax-storage syntax-type syntax-js&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;syntax-variable syntax-other syntax-readwrite syntax-js&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;syntax-keyword syntax-operator syntax-assignment syntax-js&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;syntax-support syntax-class syntax-builtin syntax-js&quot;&gt;Math&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-accessor syntax-js&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-function-call syntax-method syntax-js&quot;&gt;&lt;span class=&quot;syntax-variable syntax-function syntax-js&quot;&gt;random&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-js&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-js&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-js&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-js&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-terminator syntax-statement syntax-js&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;syntax-storage syntax-type syntax-js&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;syntax-variable syntax-other syntax-readwrite syntax-js&quot;&gt;y&lt;/span&gt; &lt;span class=&quot;syntax-keyword syntax-operator syntax-assignment syntax-js&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;syntax-support syntax-class syntax-builtin syntax-js&quot;&gt;Math&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-accessor syntax-js&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-function-call syntax-method syntax-js&quot;&gt;&lt;span class=&quot;syntax-variable syntax-function syntax-js&quot;&gt;random&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-js&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-js&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-js&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-js&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-terminator syntax-statement syntax-js&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;syntax-storage syntax-type syntax-js&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;syntax-variable syntax-other syntax-readwrite syntax-js&quot;&gt;inCircle&lt;/span&gt; &lt;span class=&quot;syntax-keyword syntax-operator syntax-assignment syntax-js&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;syntax-variable syntax-other syntax-readwrite syntax-js&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;syntax-keyword syntax-operator syntax-arithmetic syntax-js&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;syntax-variable syntax-other syntax-readwrite syntax-js&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;syntax-keyword syntax-operator syntax-arithmetic syntax-js&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;syntax-variable syntax-other syntax-readwrite syntax-js&quot;&gt;y&lt;/span&gt; &lt;span class=&quot;syntax-keyword syntax-operator syntax-arithmetic syntax-js&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;syntax-variable syntax-other syntax-readwrite syntax-js&quot;&gt;y&lt;/span&gt; &lt;span class=&quot;syntax-keyword syntax-operator syntax-relational syntax-js&quot;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&quot;syntax-constant syntax-numeric syntax-js&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-terminator syntax-statement syntax-js&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;syntax-meta syntax-conditional syntax-js&quot;&gt;&lt;span class=&quot;syntax-keyword syntax-control syntax-conditional syntax-js&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;syntax-meta syntax-group syntax-js&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-js&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-variable syntax-other syntax-readwrite syntax-js&quot;&gt;inCircle&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-js&quot;&gt;)&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;syntax-variable syntax-other syntax-readwrite syntax-js&quot;&gt;inside&lt;/span&gt;&lt;span class=&quot;syntax-keyword syntax-operator syntax-arithmetic syntax-js&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-terminator syntax-statement syntax-js&quot;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-block syntax-js&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-block syntax-js&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;syntax-variable syntax-other syntax-readwrite syntax-js&quot;&gt;estimateValue&lt;/span&gt; &lt;span class=&quot;syntax-keyword syntax-operator syntax-assignment syntax-js&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;syntax-constant syntax-numeric syntax-js&quot;&gt;4&lt;/span&gt; &lt;span class=&quot;syntax-keyword syntax-operator syntax-arithmetic syntax-js&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;syntax-variable syntax-other syntax-readwrite syntax-js&quot;&gt;inside&lt;/span&gt; &lt;span class=&quot;syntax-keyword syntax-operator syntax-arithmetic syntax-js&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;syntax-variable syntax-other syntax-readwrite syntax-js&quot;&gt;total&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-terminator syntax-statement syntax-js&quot;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You&#39;ll notice that the estimate is relatively poor - even with 1000 samples - if you click &amp;quot;Run&amp;quot; several times, some numbers will be way off mark. While this method does estimate , it&#39;s not a particularly &lt;em&gt;good&lt;/em&gt; estimate. I find that running ~10 billion samples is necessary to estimate it to 4 digits after the decimal with reasonable reliability.&lt;/p&gt;
&lt;p&gt;In general, for independent trials like these, the typical sampling error decreases in proportion to , where N is the number of trials. This means that halving the error requires four times as many samples.&lt;/p&gt;
&lt;p&gt;While the estimation may seem whimsical, it&#39;s an example of an important class of problems to which Monte Carlo simulation is applied: numerical integration. Our simulation estimates the area under the quarter-circle curve, which is a definite integral.&lt;/p&gt;
&lt;p&gt;Many integrals are very difficult to solve analytically, and much research has been done in the area of numerical analysis to develop methods to calculate integrals. Monte Carlo methods are particularly useful for high-dimensional integrals, where other numerical methods can become prohibitively expensive.&lt;/p&gt;
&lt;h2&gt;Combinatorial simulation - the game of SET&lt;/h2&gt;
&lt;p&gt;A common use of Monte Carlo methods is estimating complex combinatorial calculations. These often don&#39;t have analytical solutions, and enumerating all options is intractable due to the scale of the numbers involved. As an example, let&#39;s consider &lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://en.wikipedia.org/wiki/Set_(card_game)&quot;&gt;the game of SET&lt;/a&gt;. Each SET card has four attributes:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Number of shapes (1, 2 or 3)&lt;/li&gt;
&lt;li&gt;Color (Red, Green or Purple)&lt;/li&gt;
&lt;li&gt;Shape type (Oval, Diamond or Squiggle)&lt;/li&gt;
&lt;li&gt;Shading (Empty, Striped or Solid)&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;And the goal is to find a &amp;quot;set&amp;quot; - three cards that are either all different or all the same &lt;em&gt;for each attribute separately&lt;/em&gt;. As an example, here&#39;s a hand with a single set; see if you can find it &lt;sup class=&quot;citation-ref&quot;&gt;&lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://eli.thegreenplace.net/2026/monte-carlo-simulations/#footnote-2&quot;&gt;[2]&lt;/a&gt;&lt;/sup&gt;:&lt;/p&gt;
&lt;p&gt;And the next hand doesn&#39;t have any sets:&lt;/p&gt;
&lt;p&gt;Here&#39;s a question: given a freshly shuffled SET deck, what are the odds that the first 12 cards drawn will have no sets among them? This question is difficult to answer without using a computer.&lt;/p&gt;
&lt;p&gt;It&#39;s easy to calculate the number of ways to deal a 12-card hand from a deck of 81:&lt;/p&gt;
&lt;p&gt;But how many of these hands have no sets? Enumerating 70 trillion SET hands and checking each one can take quite a while, and there is no straightforward counting formula to answer this question. Some clever methods can be employed to leverage symmetries and other mathematical properties of SET to cut down this search space considerably. Donald Knuth himself worked on this problem and came up with a neat program (&lt;code&gt;setset-all&lt;/code&gt; on &lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://cs.stanford.edu/~knuth/programs.html&quot;&gt;his programs page&lt;/a&gt;) that found 2,284,535,476,080 such hands. Therefore, the answer to our question is:&lt;/p&gt;
&lt;p&gt;There&#39;s a 3.23% chance that a randomly drawn hand of 12 cards from a full deck of SET will have no set in it.&lt;/p&gt;
&lt;p&gt;Let&#39;s see how we can use a Monte Carlo simulation to answer this question with relatively small effort, without deep knowledge of the mathematical properties of SET that enable cutting down the search space Knuth-style. We can use the following pseudo-code:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;code-snippet&quot;&gt;C = 0
run N times:
  draw a random 12-card hand from a fresh deck
  count sets in the hand
  if no sets:
    C += 1

Estimated probability = C / N
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;After running 10 million simulated draws, I got an answer of 0.0323, which matches the real answer very closely.&lt;/p&gt;
&lt;p&gt;The Monte Carlo approach lets us solve rather complicated problems in a very simple way. Suppose we want to answer the same question for a hand of 15 cards; this would blow up the search space considerably - there are about 100x more ways to select 15-card hands than there are to select 12-card hands. But for a Monte Carlo simulation, we adjust one small parameter and get a very reliable &lt;sup class=&quot;citation-ref&quot;&gt;&lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://eli.thegreenplace.net/2026/monte-carlo-simulations/#footnote-3&quot;&gt;[3]&lt;/a&gt;&lt;/sup&gt; answer (about 0.00037, in case you were wondering).&lt;/p&gt;
&lt;h2&gt;Retirement projection&lt;/h2&gt;
&lt;p&gt;One domain where Monte Carlo simulations are ubiquitous is projections for retirement portfolios. Suppose someone prepares to retire with a total sum of 1 million dollars in their portfolio; they&#39;d like to be able to draw $30,000 a year from the portfolio for their living expenses. Would that work?&lt;/p&gt;
&lt;p&gt;There&#39;s a large number of factors to take into account when analyzing this question, but for simplicity let&#39;s focus on just two: portfolio return and inflation. We can run a naive estimate, assuming average values: suppose an average yearly portfolio return of 4%, and average yearly inflation of 2% &lt;sup class=&quot;citation-ref&quot;&gt;&lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://eli.thegreenplace.net/2026/monte-carlo-simulations/#footnote-4&quot;&gt;[4]&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;Let&#39;s denote our portfolio return as , and inflation as . Then the real return each year is:&lt;/p&gt;
&lt;p&gt;Starting with $1,000,000, at the end of the year we&#39;ll have $1,019,600 and then draw $30,000 for living expenses &lt;sup class=&quot;citation-ref&quot;&gt;&lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://eli.thegreenplace.net/2026/monte-carlo-simulations/#footnote-5&quot;&gt;[5]&lt;/a&gt;&lt;/sup&gt;, ending with $989,600. If we continue this way, the money runs out after ~55 years, which means that a person retiring at the age of 65 should be reasonably safe, right?&lt;/p&gt;
&lt;p&gt;But this is &lt;em&gt;very simplistic&lt;/em&gt;; assuming just average returns is risky, because they do a poor job of representing reality, and many factors have uncertainty. For example, the sequence of returns matters a lot; a bad year (-10%) followed by a great year (+18%) would still count as &amp;quot;4% on average&amp;quot; but produces significantly less money than two consecutive +4% years. Inflation is also unpredictable, and sometimes correlated with portfolio returns; there could be bad years of high inflation and low / volatile returns that can wreak havoc on a portfolio.&lt;/p&gt;
&lt;p&gt;As we add factors (variance in yearly draws, mixed portfolios of stocks, bonds, real estate, life expectancy, unexpected events, changing tax laws etc.), relying on a single average estimate becomes increasingly more fraught. This is why Monte Carlo simulations are very popular in this domain: by drawing from reasonable distributions based on historical data, a Monte Carlo simulation can easily run a million different scenarios and provide estimates: for example, what are the odds of money running out before death.&lt;/p&gt;
&lt;p&gt;Here&#39;s a useful chart from a simulation I ran:&lt;/p&gt;
&lt;p&gt;&lt;picture class=&quot;article-picture article-picture-fallback&quot; style=&quot;--image-ratio:16 / 9&quot;&gt;&lt;img src=&quot;https://eli.thegreenplace.net/images/2026/retirement-monte-carlo.png&quot; alt=&quot;Monte Carlo simulation of retirement, showing percentiles and odds of funds running out&quot; loading=&quot;eager&quot; decoding=&quot;async&quot; fetchpriority=&quot;high&quot; referrerpolicy=&quot;no-referrer&quot; class=&quot;progressive-image&quot;&gt;&lt;/picture&gt;&lt;/p&gt;
&lt;p&gt;In the top chart:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The dashed line shows the constant assumptions mentioned before: what happens when yearly return is always 4% and inflation is always 2%.&lt;/li&gt;
&lt;li&gt;The shaded blue areas demonstrate the outcomes of 1,000,000 simulations where inflation and return numbers are drawn from reasonable normal distributions based on historical data. We see that in 25% of the cases, all money ran out by roughly 22 years.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In the bottom chart:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;It&#39;s even easier to see how long the funds last; if we&#39;re interested in knowing, say, what are the odds that this plan will have enough money for 30 years - the chart shows it&#39;s about 60% (since in 40% of the simulations the funds were depleted at this point).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Looking a this simulation, under the current assumptions the plan sounds much riskier than the average assumption makes it appear. Assuming that a 65-y.o. person would plan for 25 years of retirement until death, the ~30% odds of not having sufficient funds for this duration of time are sobering. Perhaps a change in plans is needed (such as a more frugal lifestyle or securing additional funds in some way).&lt;/p&gt;
&lt;p&gt;Retirement projection is only one of may ways in which Monte Carlo simulations are used for financial and economical applications; given the high uncertainty of these domains, it&#39;s very difficult to plan using analytical calculations. Company sales projections, growth projections, stock offering prices and much more uses Monte Carlo simulations to arrive at estimates with reasonable error bars.&lt;/p&gt;
&lt;h2&gt;Code&lt;/h2&gt;
&lt;p&gt;All the code for the explorations in this post is &lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://github.com/eliben/code-for-blog/tree/main/2026/monte-carlo&quot;&gt;available on GitHub&lt;/a&gt;.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;&lt;sup class=&quot;citation-ref&quot;&gt;&lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://eli.thegreenplace.net/2026/monte-carlo-simulations/#footnote-reference-1&quot;&gt;[1]&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;While these techniques were conceptually understood much earlier, it&#39;s not surprising that their first real applications coincided with the development of the first digital computers. As we&#39;ll see later in the post, Monte Carlo simulations benefit from running large numbers of trials to get reasonable accuracy.&lt;/p&gt;
&lt;p&gt;&lt;sup class=&quot;citation-ref&quot;&gt;&lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://eli.thegreenplace.net/2026/monte-carlo-simulations/#footnote-reference-2&quot;&gt;[2]&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;The answer is: three empty red diamonds, three solid purple ovals, three striped green squiggles. Note that for each of the 4 SET attributes, these three cards are either all the same or all different.&lt;/p&gt;
&lt;p&gt;&lt;sup class=&quot;citation-ref&quot;&gt;&lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://eli.thegreenplace.net/2026/monte-carlo-simulations/#footnote-reference-3&quot;&gt;[3]&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;For the same number of trials, this estimate has greater relative uncertainty than the 12-card estimate, because we encounter far fewer hands without a set.&lt;/p&gt;
&lt;p&gt;&lt;sup class=&quot;citation-ref&quot;&gt;&lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://eli.thegreenplace.net/2026/monte-carlo-simulations/#footnote-reference-4&quot;&gt;[4]&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;For the examples in this post, we&#39;ll be using &lt;em&gt;real dollars&lt;/em&gt;, or today&#39;s value of the money. We&#39;ll assume that the $30,000 yearly draw doesn&#39;t change and will instead apply inflation to the portfolio itself.&lt;/p&gt;
&lt;p&gt;&lt;sup class=&quot;citation-ref&quot;&gt;&lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://eli.thegreenplace.net/2026/monte-carlo-simulations/#footnote-reference-5&quot;&gt;[5]&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;More sophisticated simulations would let us control these parameters; for example, are the expense funds drawn at the beginning or end of each year, or distributed on a monthly basis?&lt;/p&gt;
</content>
  </entry>
  <entry>
    <id>urn:aggr:item:613fcee8cf038ec3c68e5096f3394d23357290b1</id>
    <title type="text">Rusty thoughts on &quot;Parse, don&#39;t validate&quot;</title>
    <link rel="alternate" type="text/html" href="https://aggr.aymericbeaumet.com/items/lobste-rs/2026-09-26-rusty-thoughts-on-parse-don-t-validate/"/>
    <link rel="via" type="text/html" href="https://eli.thegreenplace.net/2026/rusty-thoughts-on-parse-dont-validate/"/>
    <published>2026-09-26T20:45:24+00:00</published>
    <updated>2026-09-26T20:45:24+00:00</updated>
    <author>
      <name>eli.thegreenplace.net via carlana</name>
    </author>
    <category term="news"/>
    <category term="programming"/>
    <category term="rust"/>
    <source>
      <title>Lobsters: Top Stories of the Past Week</title>
    </source>
    <summary type="text">Comments</summary>
    <content type="html">&lt;p&gt;Like many programmers, I find Alexis King&#39;s &lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://lexi-lambda.github.io/blog/2019/11/05/parse-don-t-validate/&quot;&gt;Parse, don&#39;t validate&lt;/a&gt; article fascinating, because it gives a name to an idiom that seems familiar and important - one I&#39;ve observed and used in the past without naming it explicitly. This post is a review of the &amp;quot;Parse, don&#39;t validate&amp;quot; pattern applied to the Rust programming language (the original post uses Haskell). I was particularly interested in finding educational examples of this pattern in the Rust standard library and other well-known projects.&lt;/p&gt;
&lt;p&gt;Without repeating the original article (please read it first!), here&#39;s the gist of it.&lt;/p&gt;
&lt;p&gt;Consider the venerable &lt;code&gt;Vec&lt;/code&gt;; its &lt;code&gt;first&lt;/code&gt; method returns &lt;code&gt;Option&amp;lt;&amp;amp;T&amp;gt;&lt;/code&gt;. Why? Because a vector is not guaranteed to have any elements in it, so what to do if &lt;code&gt;first&lt;/code&gt; is invoked on an empty one? Returning an &lt;code&gt;Option&lt;/code&gt; in this case is idiomatic in Rust &lt;sup class=&quot;citation-ref&quot;&gt;&lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://eli.thegreenplace.net/2026/rusty-thoughts-on-parse-dont-validate/#footnote-1&quot;&gt;[1]&lt;/a&gt;&lt;/sup&gt;, with convenient syntax sugar for accepting the result of functions that return &lt;code&gt;Option&lt;/code&gt; and deciding what to do next.&lt;/p&gt;
&lt;p&gt;So what&#39;s the issue?&lt;/p&gt;
&lt;p&gt;Imagine we have a function to read some configuration paths from an env var, while enforcing the invariant that the list can&#39;t be empty:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;code-snippet&quot; data-language=&quot;Rust&quot;&gt;&lt;span class=&quot;syntax-source syntax-rust&quot;&gt;&lt;span class=&quot;syntax-keyword syntax-other syntax-rust&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;syntax-meta syntax-path syntax-rust&quot;&gt;anyhow&lt;span class=&quot;syntax-punctuation syntax-accessor syntax-rust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-block syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-block syntax-begin syntax-rust&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;syntax-support syntax-type syntax-rust&quot;&gt;Result&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-separator syntax-rust&quot;&gt;,&lt;/span&gt; ensure&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-block syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-block syntax-end syntax-rust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-terminator syntax-rust&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;syntax-meta syntax-function syntax-rust&quot;&gt;&lt;span class=&quot;syntax-meta syntax-function syntax-rust&quot;&gt;&lt;span class=&quot;syntax-storage syntax-type syntax-function syntax-rust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;syntax-entity syntax-name syntax-function syntax-rust&quot;&gt;get_configuration_directories&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-function syntax-rust&quot;&gt;&lt;span class=&quot;syntax-meta syntax-function syntax-parameters syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-parameters syntax-begin syntax-rust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-function syntax-rust&quot;&gt;&lt;span class=&quot;syntax-meta syntax-function syntax-parameters syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-parameters syntax-end syntax-rust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-function syntax-rust&quot;&gt; &lt;span class=&quot;syntax-meta syntax-function syntax-return-type syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-separator syntax-rust&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;syntax-meta syntax-generic syntax-rust&quot;&gt;Result&lt;span class=&quot;syntax-punctuation syntax-definition syntax-generic syntax-begin syntax-rust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-generic syntax-rust&quot;&gt;Vec&lt;span class=&quot;syntax-punctuation syntax-definition syntax-generic syntax-begin syntax-rust&quot;&gt;&amp;lt;&lt;/span&gt;PathBuf&lt;span class=&quot;syntax-punctuation syntax-definition syntax-generic syntax-end syntax-rust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-definition syntax-generic syntax-end syntax-rust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-function syntax-rust&quot;&gt;&lt;span class=&quot;syntax-meta syntax-block syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-block syntax-begin syntax-rust&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;syntax-storage syntax-type syntax-rust&quot;&gt;let&lt;/span&gt; value &lt;span class=&quot;syntax-keyword syntax-operator syntax-rust&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;syntax-meta syntax-path syntax-rust&quot;&gt;env&lt;span class=&quot;syntax-punctuation syntax-accessor syntax-rust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;var&lt;span class=&quot;syntax-meta syntax-group syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-begin syntax-rust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-string syntax-quoted syntax-double syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-definition syntax-string syntax-begin syntax-rust&quot;&gt;&amp;quot;&lt;/span&gt;CONFIG_DIRS&lt;span class=&quot;syntax-punctuation syntax-definition syntax-string syntax-end syntax-rust&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-end syntax-rust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;.&lt;span class=&quot;syntax-support syntax-function syntax-rust&quot;&gt;context&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-begin syntax-rust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-string syntax-quoted syntax-double syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-definition syntax-string syntax-begin syntax-rust&quot;&gt;&amp;quot;&lt;/span&gt;could not read CONFIG_DIRS&lt;span class=&quot;syntax-punctuation syntax-definition syntax-string syntax-end syntax-rust&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-end syntax-rust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-keyword syntax-operator syntax-rust&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-terminator syntax-rust&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;syntax-storage syntax-type syntax-rust&quot;&gt;let&lt;/span&gt; directories&lt;span class=&quot;syntax-punctuation syntax-separator syntax-rust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;syntax-meta syntax-generic syntax-rust&quot;&gt;Vec&lt;span class=&quot;syntax-punctuation syntax-definition syntax-generic syntax-begin syntax-rust&quot;&gt;&amp;lt;&lt;/span&gt;PathBuf&lt;span class=&quot;syntax-punctuation syntax-definition syntax-generic syntax-end syntax-rust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;syntax-keyword syntax-operator syntax-rust&quot;&gt;=&lt;/span&gt; value
        .&lt;span class=&quot;syntax-support syntax-function syntax-rust&quot;&gt;split&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-begin syntax-rust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-string syntax-quoted syntax-single syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-definition syntax-string syntax-begin syntax-rust&quot;&gt;&amp;#39;&lt;/span&gt;,&lt;span class=&quot;syntax-punctuation syntax-definition syntax-string syntax-end syntax-rust&quot;&gt;&amp;#39;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-end syntax-rust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
        .&lt;span class=&quot;syntax-support syntax-function syntax-rust&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-begin syntax-rust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-storage syntax-type syntax-rust&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-path syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-accessor syntax-rust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;trim&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-end syntax-rust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
        .&lt;span class=&quot;syntax-support syntax-function syntax-rust&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-begin syntax-rust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-path syntax-rust&quot;&gt;PathBuf&lt;span class=&quot;syntax-punctuation syntax-accessor syntax-rust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;from&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-end syntax-rust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
        .&lt;span class=&quot;syntax-support syntax-function syntax-rust&quot;&gt;collect&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-begin syntax-rust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-end syntax-rust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-terminator syntax-rust&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;syntax-support syntax-macro syntax-rust&quot;&gt;ensure!&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-begin syntax-rust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-keyword syntax-operator syntax-rust&quot;&gt;!&lt;/span&gt;directories.&lt;span class=&quot;syntax-support syntax-function syntax-rust&quot;&gt;is_empty&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-begin syntax-rust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-end syntax-rust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-separator syntax-rust&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;syntax-string syntax-quoted syntax-double syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-definition syntax-string syntax-begin syntax-rust&quot;&gt;&amp;quot;&lt;/span&gt;empty CONFIG_DIRS&lt;span class=&quot;syntax-punctuation syntax-definition syntax-string syntax-end syntax-rust&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-end syntax-rust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-terminator syntax-rust&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;syntax-support syntax-type syntax-rust&quot;&gt;Ok&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-begin syntax-rust&quot;&gt;(&lt;/span&gt;directories&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-end syntax-rust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-block syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-block syntax-end syntax-rust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So far, so good. Now let&#39;s take a typical usage of this function:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;code-snippet&quot; data-language=&quot;CSS&quot;&gt;&lt;span class=&quot;syntax-source syntax-css&quot;&gt;&lt;span class=&quot;syntax-meta syntax-selector syntax-css&quot;&gt;fn &lt;span class=&quot;syntax-entity syntax-name syntax-tag syntax-css&quot;&gt;main&lt;/span&gt;(&lt;/span&gt;) -&amp;gt;&lt;span class=&quot;syntax-meta syntax-selector syntax-css&quot;&gt; Result&amp;lt;(&lt;/span&gt;)&amp;gt; &lt;span class=&quot;syntax-meta syntax-property-list syntax-css&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-property-list syntax-css&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;syntax-meta syntax-property-name syntax-css&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;syntax-meta syntax-property-name syntax-css&quot;&gt;config&lt;/span&gt;_&lt;span class=&quot;syntax-meta syntax-property-name syntax-css&quot;&gt;dirs&lt;/span&gt; = &lt;span class=&quot;syntax-meta syntax-property-name syntax-css&quot;&gt;get&lt;/span&gt;_&lt;span class=&quot;syntax-meta syntax-property-name syntax-css&quot;&gt;configuration&lt;/span&gt;_&lt;span class=&quot;syntax-meta syntax-property-name syntax-css&quot;&gt;directories&lt;/span&gt;()?;

    &lt;span class=&quot;syntax-meta syntax-property-name syntax-css&quot;&gt;match&lt;/span&gt; &lt;span class=&quot;syntax-meta syntax-property-name syntax-css&quot;&gt;config&lt;/span&gt;_&lt;span class=&quot;syntax-meta syntax-property-name syntax-css&quot;&gt;dirs&lt;/span&gt;.&lt;span class=&quot;syntax-meta syntax-property-name syntax-css&quot;&gt;first&lt;/span&gt;() {
        S&lt;span class=&quot;syntax-meta syntax-property-name syntax-css&quot;&gt;ome&lt;/span&gt;(&lt;span class=&quot;syntax-meta syntax-property-name syntax-css&quot;&gt;cache&lt;/span&gt;_&lt;span class=&quot;syntax-meta syntax-property-name syntax-css&quot;&gt;dir&lt;/span&gt;) =&amp;gt; &lt;span class=&quot;syntax-meta syntax-property-name syntax-css&quot;&gt;initialize&lt;/span&gt;_&lt;span class=&quot;syntax-meta syntax-property-name syntax-css&quot;&gt;cache&lt;/span&gt;(&lt;span class=&quot;syntax-meta syntax-property-name syntax-css&quot;&gt;cache&lt;/span&gt;_&lt;span class=&quot;syntax-meta syntax-property-name syntax-css&quot;&gt;dir&lt;/span&gt;),
        N&lt;span class=&quot;syntax-meta syntax-property-name syntax-css&quot;&gt;one&lt;/span&gt; =&amp;gt; &lt;span class=&quot;syntax-meta syntax-property-name syntax-css&quot;&gt;unreachable&lt;/span&gt;!(&amp;quot;&lt;span class=&quot;syntax-meta syntax-property-name syntax-css&quot;&gt;already&lt;/span&gt; &lt;span class=&quot;syntax-meta syntax-property-name syntax-css&quot;&gt;checked&lt;/span&gt; &lt;span class=&quot;syntax-meta syntax-property-name syntax-css&quot;&gt;that&lt;/span&gt; CONFIG_DIRS &lt;span class=&quot;syntax-meta syntax-property-name syntax-css&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;syntax-meta syntax-property-name syntax-css&quot;&gt;non-empty&lt;/span&gt;&amp;quot;),
&lt;/span&gt;    &lt;span class=&quot;syntax-punctuation syntax-section syntax-property-list syntax-css&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;syntax-meta syntax-selector syntax-css&quot;&gt;    Ok((&lt;/span&gt;))
}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Once &lt;code&gt;get_configuration_directories&lt;/code&gt; returns a successful result, we are guaranteed that the vector isn&#39;t empty. And yet, if we want to get the first element of this vector, we have to use the &lt;code&gt;first&lt;/code&gt; method that returns &lt;code&gt;Option&amp;lt;&amp;amp;T&amp;gt;&lt;/code&gt;. We are therefore forced - again - to handle a potentially empty case (where the option is &lt;code&gt;None&lt;/code&gt;).&lt;/p&gt;
&lt;p&gt;As the original article states, this has a number of problems with code clarity, potential performance implications and a ticking time bomb if the invariant is ever changed in &lt;code&gt;get_configuration_directories&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The core issue is that &lt;code&gt;Vec&lt;/code&gt; is fundamentally a type that can be empty; we can carry along a &amp;quot;This one can&#39;t be empty, pinky promise!&amp;quot; comment on all the relevant code, but it&#39;s not formally checked by anything.&lt;/p&gt;
&lt;h2&gt;A type for &amp;quot;non-empty&amp;quot; vector&lt;/h2&gt;
&lt;p&gt;The solution is leveraging the type system to enforce a newly established invariant. We can use a separate type for &amp;quot;a vector that cannot be empty&amp;quot;; in fact, such types already exist in several Rust crates - for example &lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://docs.rs/nonempty/latest/nonempty/&quot;&gt;nonempty&lt;/a&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;code-snippet&quot;&gt;pub struct NonEmpty&amp;lt;T&amp;gt; {
    pub head: T,
    pub tail: Vec&amp;lt;T&amp;gt;,
}
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This type has no constructor that permits &amp;quot;no elements&amp;quot;; its &lt;code&gt;new&lt;/code&gt; takes one element, and its &lt;code&gt;first&lt;/code&gt; method returns &lt;code&gt;&amp;amp;T&lt;/code&gt; without an &lt;code&gt;Option&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;code-snippet&quot;&gt;pub const fn new(e: T) -&amp;gt; Self {
    Self::singleton(e)
}

pub const fn singleton(head: T) -&amp;gt; Self {
    NonEmpty {
        head,
        tail: Vec::new(),
    }
}

pub const fn first(&amp;amp;self) -&amp;gt; &amp;amp;T {
    &amp;amp;self.head
}
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The rest of the crate deals with making &lt;code&gt;NonEmpty&lt;/code&gt; behave as close as possible to a normal &lt;code&gt;Vec&lt;/code&gt;, by implementing many useful traits, as well as conversions like:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;code-snippet&quot; data-language=&quot;CSS&quot;&gt;&lt;span class=&quot;syntax-source syntax-css&quot;&gt;&lt;span class=&quot;syntax-meta syntax-selector syntax-css&quot;&gt;pub fn from_vec(mut vec: Vec&amp;lt;T&lt;span class=&quot;syntax-punctuation syntax-separator syntax-combinator syntax-css&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;) -&amp;gt;&lt;span class=&quot;syntax-meta syntax-selector syntax-css&quot;&gt; Option&amp;lt;NonEmpty&amp;lt;T&lt;span class=&quot;syntax-punctuation syntax-separator syntax-combinator syntax-css&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-property-list syntax-css&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-property-list syntax-css&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;syntax-meta syntax-property-name syntax-css&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;syntax-meta syntax-property-name syntax-css&quot;&gt;vec&lt;/span&gt;.&lt;span class=&quot;syntax-meta syntax-property-name syntax-css&quot;&gt;is&lt;/span&gt;_&lt;span class=&quot;syntax-meta syntax-property-name syntax-css&quot;&gt;empty&lt;/span&gt;() {
        N&lt;span class=&quot;syntax-meta syntax-property-name syntax-css&quot;&gt;one&lt;/span&gt;
&lt;/span&gt;    &lt;span class=&quot;syntax-punctuation syntax-section syntax-property-list syntax-css&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-selector syntax-css&quot;&gt; else &lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-property-list syntax-css&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-property-list syntax-css&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;syntax-meta syntax-property-name syntax-css&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;syntax-meta syntax-property-name syntax-css&quot;&gt;head&lt;/span&gt; = &lt;span class=&quot;syntax-meta syntax-property-name syntax-css&quot;&gt;vec&lt;/span&gt;.&lt;span class=&quot;syntax-meta syntax-property-name syntax-css&quot;&gt;remove&lt;/span&gt;(0);
        S&lt;span class=&quot;syntax-meta syntax-property-name syntax-css&quot;&gt;ome&lt;/span&gt;(N&lt;span class=&quot;syntax-meta syntax-property-name syntax-css&quot;&gt;on&lt;/span&gt;E&lt;span class=&quot;syntax-meta syntax-property-name syntax-css&quot;&gt;mpty&lt;/span&gt; { &lt;span class=&quot;syntax-meta syntax-property-name syntax-css&quot;&gt;head&lt;/span&gt;, &lt;span class=&quot;syntax-meta syntax-property-name syntax-css&quot;&gt;tail&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-separator syntax-key-value syntax-css&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-property-value syntax-css&quot;&gt; &lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-property-value syntax-css&quot;&gt;vec &lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-property-list syntax-css&quot;&gt;}&lt;/span&gt;)
    }
}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Let&#39;s see how our &lt;code&gt;get_configuration_directories&lt;/code&gt; function would look if it returned a &lt;code&gt;NonEmpty&lt;/code&gt; instead of a plain &lt;code&gt;Vec&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;code-snippet&quot; data-language=&quot;CSS&quot;&gt;&lt;span class=&quot;syntax-source syntax-css&quot;&gt;&lt;span class=&quot;syntax-meta syntax-selector syntax-css&quot;&gt;fn get_configuration_directories(&lt;/span&gt;) -&amp;gt;&lt;span class=&quot;syntax-meta syntax-selector syntax-css&quot;&gt; Result&amp;lt;NonEmpty&amp;lt;PathBuf&lt;span class=&quot;syntax-punctuation syntax-separator syntax-combinator syntax-css&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-property-list syntax-css&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-property-list syntax-css&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;syntax-meta syntax-property-name syntax-css&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;syntax-meta syntax-property-name syntax-css&quot;&gt;value&lt;/span&gt; = &lt;span class=&quot;syntax-meta syntax-property-name syntax-css&quot;&gt;env&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-separator syntax-key-value syntax-css&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-property-value syntax-css&quot;&gt;:&lt;span class=&quot;syntax-meta syntax-function-call syntax-css&quot;&gt;&lt;span class=&quot;syntax-support syntax-function syntax-var syntax-css&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-css&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-definition syntax-group syntax-begin syntax-css&quot;&gt;(&lt;/span&gt;&amp;quot;CONFIG_DIRS&amp;quot;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-css&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-definition syntax-group syntax-end syntax-css&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;.context(&lt;span class=&quot;syntax-string syntax-quoted syntax-double syntax-css&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-definition syntax-string syntax-begin syntax-css&quot;&gt;&amp;quot;&lt;/span&gt;could not read CONFIG_DIRS&lt;span class=&quot;syntax-punctuation syntax-definition syntax-string syntax-end syntax-css&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;)?;

    &lt;span class=&quot;syntax-meta syntax-property-name syntax-css&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;syntax-meta syntax-property-name syntax-css&quot;&gt;directories&lt;/span&gt; = &lt;span class=&quot;syntax-meta syntax-property-name syntax-css&quot;&gt;value&lt;/span&gt;
        .&lt;span class=&quot;syntax-meta syntax-property-name syntax-css&quot;&gt;split&lt;/span&gt;(&amp;#39;,&amp;#39;)
        .&lt;span class=&quot;syntax-meta syntax-property-name syntax-css&quot;&gt;map&lt;/span&gt;(&lt;span class=&quot;syntax-meta syntax-property-name syntax-css&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-separator syntax-key-value syntax-css&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-property-value syntax-css&quot;&gt;:trim&lt;/span&gt;)
        .&lt;span class=&quot;syntax-meta syntax-property-name syntax-css&quot;&gt;map&lt;/span&gt;(P&lt;span class=&quot;syntax-meta syntax-property-name syntax-css&quot;&gt;ath&lt;/span&gt;B&lt;span class=&quot;syntax-meta syntax-property-name syntax-css&quot;&gt;uf&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-separator syntax-key-value syntax-css&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-property-value syntax-css&quot;&gt;:&lt;span class=&quot;syntax-support syntax-constant syntax-property-value syntax-css&quot;&gt;from&lt;/span&gt;&lt;/span&gt;)
        .&lt;span class=&quot;syntax-meta syntax-property-name syntax-css&quot;&gt;collect&lt;/span&gt;();

    &lt;span class=&quot;syntax-meta syntax-property-name syntax-css&quot;&gt;let&lt;/span&gt; S&lt;span class=&quot;syntax-meta syntax-property-name syntax-css&quot;&gt;ome&lt;/span&gt;(&lt;span class=&quot;syntax-meta syntax-property-name syntax-css&quot;&gt;directories&lt;/span&gt;) = N&lt;span class=&quot;syntax-meta syntax-property-name syntax-css&quot;&gt;on&lt;/span&gt;E&lt;span class=&quot;syntax-meta syntax-property-name syntax-css&quot;&gt;mpty&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-separator syntax-key-value syntax-css&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-property-value syntax-css&quot;&gt;:from_vec(directories&lt;/span&gt;) &lt;span class=&quot;syntax-meta syntax-property-name syntax-css&quot;&gt;else&lt;/span&gt; {
        &lt;span class=&quot;syntax-meta syntax-property-name syntax-css&quot;&gt;bail&lt;/span&gt;!(&amp;quot;CONFIG_DIRS &lt;span class=&quot;syntax-meta syntax-property-name syntax-css&quot;&gt;cannot&lt;/span&gt; &lt;span class=&quot;syntax-meta syntax-property-name syntax-css&quot;&gt;be&lt;/span&gt; &lt;span class=&quot;syntax-meta syntax-property-name syntax-css&quot;&gt;empty&lt;/span&gt;&amp;quot;);
&lt;/span&gt;    &lt;span class=&quot;syntax-punctuation syntax-section syntax-property-list syntax-css&quot;&gt;}&lt;/span&gt;;

&lt;span class=&quot;syntax-meta syntax-selector syntax-css&quot;&gt;    Ok(directories&lt;/span&gt;)
}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Note the use of &lt;code&gt;NonEmpty::from_vec&lt;/code&gt; here - this is where the invariant is established. Now a successful result is &lt;code&gt;NonEmpty&lt;/code&gt;, not just &lt;code&gt;Vec&lt;/code&gt;. The client code looks like:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;code-snippet&quot; data-language=&quot;Rust&quot;&gt;&lt;span class=&quot;syntax-source syntax-rust&quot;&gt;&lt;span class=&quot;syntax-meta syntax-function syntax-rust&quot;&gt;&lt;span class=&quot;syntax-meta syntax-function syntax-rust&quot;&gt;&lt;span class=&quot;syntax-storage syntax-type syntax-function syntax-rust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;syntax-entity syntax-name syntax-function syntax-rust&quot;&gt;main&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-function syntax-rust&quot;&gt;&lt;span class=&quot;syntax-meta syntax-function syntax-parameters syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-parameters syntax-begin syntax-rust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-function syntax-rust&quot;&gt;&lt;span class=&quot;syntax-meta syntax-function syntax-parameters syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-parameters syntax-end syntax-rust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-function syntax-rust&quot;&gt; &lt;span class=&quot;syntax-meta syntax-function syntax-return-type syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-separator syntax-rust&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;syntax-meta syntax-generic syntax-rust&quot;&gt;Result&lt;span class=&quot;syntax-punctuation syntax-definition syntax-generic syntax-begin syntax-rust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-begin syntax-rust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-end syntax-rust&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-definition syntax-generic syntax-end syntax-rust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-function syntax-rust&quot;&gt;&lt;span class=&quot;syntax-meta syntax-block syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-block syntax-begin syntax-rust&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;syntax-storage syntax-type syntax-rust&quot;&gt;let&lt;/span&gt; config_dirs &lt;span class=&quot;syntax-keyword syntax-operator syntax-rust&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;syntax-support syntax-function syntax-rust&quot;&gt;get_configuration_directories&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-begin syntax-rust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-end syntax-rust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-keyword syntax-operator syntax-rust&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-terminator syntax-rust&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;syntax-support syntax-function syntax-rust&quot;&gt;initialize_cache&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-begin syntax-rust&quot;&gt;(&lt;/span&gt;config_dirs.&lt;span class=&quot;syntax-support syntax-function syntax-rust&quot;&gt;first&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-begin syntax-rust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-end syntax-rust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-end syntax-rust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-keyword syntax-operator syntax-rust&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-terminator syntax-rust&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;syntax-support syntax-type syntax-rust&quot;&gt;Ok&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-begin syntax-rust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-begin syntax-rust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-end syntax-rust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-end syntax-rust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-block syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-block syntax-end syntax-rust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;There&#39;s no need to check if the returned value is empty again; this is enforced by the type system!&lt;/p&gt;
&lt;p&gt;This is where the parse vs. validate terminology of the original article comes from. When &lt;code&gt;get_configuration_directories&lt;/code&gt; returned a &lt;code&gt;Vec&lt;/code&gt;, it simply validated it. But when it returns a &lt;code&gt;NonEmpty&lt;/code&gt; - the vector is transformed into another entity which carries additional meaning. If we treat the concept of parsing in the most generic sense - &amp;quot;transforming data from one format to another&amp;quot;, this fits.&lt;/p&gt;
&lt;p&gt;To mention a less artificial example, the &lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://github.com/rustcoreutils/posixutils-rs&quot;&gt;Rust rewrite of core POSIX utilities&lt;/a&gt; uses &lt;code&gt;NonEmpty&lt;/code&gt; in several places &lt;sup class=&quot;citation-ref&quot;&gt;&lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://eli.thegreenplace.net/2026/rusty-thoughts-on-parse-dont-validate/#footnote-2&quot;&gt;[2]&lt;/a&gt;&lt;/sup&gt;. For example, when constructing a shell pipeline:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;code-snippet&quot;&gt;pub struct Pipeline {
    pub commands: NonEmpty&amp;lt;Command&amp;gt;,
    pub negate_status: bool,
}
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The command parser&#39;s code:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;code-snippet&quot; data-language=&quot;CSS&quot;&gt;&lt;span class=&quot;syntax-source syntax-css&quot;&gt;&lt;span class=&quot;syntax-meta syntax-selector syntax-css&quot;&gt;fn parse_pipeline(&amp;amp;mut self, alias_table: &amp;amp;AliasTable&lt;/span&gt;) -&amp;gt;&lt;span class=&quot;syntax-meta syntax-selector syntax-css&quot;&gt; ParseResult&amp;lt;Option&amp;lt;Pipeline&lt;span class=&quot;syntax-punctuation syntax-separator syntax-combinator syntax-css&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-property-list syntax-css&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-property-list syntax-css&quot;&gt;{&lt;/span&gt;
    // &lt;span class=&quot;syntax-meta syntax-property-name syntax-css&quot;&gt;pipeline&lt;/span&gt; = &amp;quot;!&amp;quot; &lt;span class=&quot;syntax-meta syntax-property-name syntax-css&quot;&gt;command&lt;/span&gt; (&amp;quot;|&amp;quot; &lt;span class=&quot;syntax-meta syntax-property-name syntax-css&quot;&gt;linebreak&lt;/span&gt; &lt;span class=&quot;syntax-meta syntax-property-name syntax-css&quot;&gt;command&lt;/span&gt;)*
    &lt;span class=&quot;syntax-meta syntax-property-name syntax-css&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;syntax-meta syntax-property-name syntax-css&quot;&gt;negate&lt;/span&gt;_&lt;span class=&quot;syntax-meta syntax-property-name syntax-css&quot;&gt;status&lt;/span&gt; = &lt;span class=&quot;syntax-meta syntax-property-name syntax-css&quot;&gt;self&lt;/span&gt;.&lt;span class=&quot;syntax-meta syntax-property-name syntax-css&quot;&gt;match&lt;/span&gt;_&lt;span class=&quot;syntax-meta syntax-property-name syntax-css&quot;&gt;alternatives&lt;/span&gt;(&amp;amp;[C&lt;span class=&quot;syntax-meta syntax-property-name syntax-css&quot;&gt;ommand&lt;/span&gt;T&lt;span class=&quot;syntax-meta syntax-property-name syntax-css&quot;&gt;oken&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-separator syntax-key-value syntax-css&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-property-value syntax-css&quot;&gt;:Bang]&lt;/span&gt;)?.&lt;span class=&quot;syntax-meta syntax-property-name syntax-css&quot;&gt;is&lt;/span&gt;_&lt;span class=&quot;syntax-meta syntax-property-name syntax-css&quot;&gt;some&lt;/span&gt;();
    &lt;span class=&quot;syntax-meta syntax-property-name syntax-css&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;syntax-meta syntax-property-name syntax-css&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;syntax-meta syntax-property-name syntax-css&quot;&gt;commands&lt;/span&gt; = &lt;span class=&quot;syntax-meta syntax-property-name syntax-css&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;syntax-meta syntax-property-name syntax-css&quot;&gt;let&lt;/span&gt; S&lt;span class=&quot;syntax-meta syntax-property-name syntax-css&quot;&gt;ome&lt;/span&gt;(&lt;span class=&quot;syntax-meta syntax-property-name syntax-css&quot;&gt;command&lt;/span&gt;) = &lt;span class=&quot;syntax-meta syntax-property-name syntax-css&quot;&gt;self&lt;/span&gt;.&lt;span class=&quot;syntax-meta syntax-property-name syntax-css&quot;&gt;parse&lt;/span&gt;_&lt;span class=&quot;syntax-meta syntax-property-name syntax-css&quot;&gt;command&lt;/span&gt;(&lt;span class=&quot;syntax-meta syntax-property-name syntax-css&quot;&gt;alias&lt;/span&gt;_&lt;span class=&quot;syntax-meta syntax-property-name syntax-css&quot;&gt;table&lt;/span&gt;)? {
        N&lt;span class=&quot;syntax-meta syntax-property-name syntax-css&quot;&gt;on&lt;/span&gt;E&lt;span class=&quot;syntax-meta syntax-property-name syntax-css&quot;&gt;mpty&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-separator syntax-key-value syntax-css&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-property-value syntax-css&quot;&gt;:new(command&lt;/span&gt;)
&lt;/span&gt;    &lt;span class=&quot;syntax-punctuation syntax-section syntax-property-list syntax-css&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-selector syntax-css&quot;&gt; else &lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-property-list syntax-css&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-property-list syntax-css&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;syntax-meta syntax-property-name syntax-css&quot;&gt;return&lt;/span&gt; O&lt;span class=&quot;syntax-meta syntax-property-name syntax-css&quot;&gt;k&lt;/span&gt;(N&lt;span class=&quot;syntax-meta syntax-property-name syntax-css&quot;&gt;one&lt;/span&gt;);
&lt;/span&gt;    &lt;span class=&quot;syntax-punctuation syntax-section syntax-property-list syntax-css&quot;&gt;}&lt;/span&gt;;

    //&lt;span class=&quot;syntax-meta syntax-selector syntax-css&quot;&gt; ...
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;A valid &lt;code&gt;Pipeline&lt;/code&gt; is only returned if there are some commands in the parsed AST. Otherwise, it just returns &lt;code&gt;None&lt;/code&gt;. Once this is done, the client code can use &lt;code&gt;commands.first()&lt;/code&gt; without having to worry about the possibility of it returning &lt;code&gt;None&lt;/code&gt;.&lt;/p&gt;
&lt;h2&gt;Gradual parsing and type refinement&lt;/h2&gt;
&lt;p&gt;A somewhat more interesting example can be found in the source code of &lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://github.com/rust-lang/rust-analyzer&quot;&gt;rust-analyzer&lt;/a&gt;. This project has a type that represents an absolute filesystem path:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;code-snippet&quot;&gt;pub struct AbsPathBuf(Utf8PathBuf);
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Instead of carrying around a regular path, the absoluteness is recorded in the type once the initial parsing and validation is done:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;code-snippet&quot; data-language=&quot;CSS&quot;&gt;&lt;span class=&quot;syntax-source syntax-css&quot;&gt;&lt;span class=&quot;syntax-meta syntax-selector syntax-css&quot;&gt;impl TryFrom&amp;lt;Utf8PathBuf&lt;span class=&quot;syntax-punctuation syntax-separator syntax-combinator syntax-css&quot;&gt;&amp;gt;&lt;/span&gt; for AbsPathBuf &lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-property-list syntax-css&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-property-list syntax-css&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;syntax-meta syntax-property-name syntax-css&quot;&gt;type&lt;/span&gt; E&lt;span class=&quot;syntax-meta syntax-property-name syntax-css&quot;&gt;rror&lt;/span&gt; = U&lt;span class=&quot;syntax-meta syntax-property-name syntax-css&quot;&gt;tf&lt;/span&gt;8P&lt;span class=&quot;syntax-meta syntax-property-name syntax-css&quot;&gt;ath&lt;/span&gt;B&lt;span class=&quot;syntax-meta syntax-property-name syntax-css&quot;&gt;uf&lt;/span&gt;;
    &lt;span class=&quot;syntax-meta syntax-property-name syntax-css&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;syntax-meta syntax-property-name syntax-css&quot;&gt;try&lt;/span&gt;_&lt;span class=&quot;syntax-meta syntax-property-name syntax-css&quot;&gt;from&lt;/span&gt;(&lt;span class=&quot;syntax-meta syntax-property-name syntax-css&quot;&gt;path&lt;/span&gt;_&lt;span class=&quot;syntax-meta syntax-property-name syntax-css&quot;&gt;buf&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-separator syntax-key-value syntax-css&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-property-value syntax-css&quot;&gt; &lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-property-value syntax-css&quot;&gt;Utf&lt;span class=&quot;syntax-constant syntax-numeric syntax-css&quot;&gt;8&lt;/span&gt;PathBuf&lt;/span&gt;) &lt;span class=&quot;syntax-meta syntax-property-name syntax-css&quot;&gt;-&lt;/span&gt;&amp;gt; R&lt;span class=&quot;syntax-meta syntax-property-name syntax-css&quot;&gt;esult&lt;/span&gt;&amp;lt;A&lt;span class=&quot;syntax-meta syntax-property-name syntax-css&quot;&gt;bs&lt;/span&gt;P&lt;span class=&quot;syntax-meta syntax-property-name syntax-css&quot;&gt;ath&lt;/span&gt;B&lt;span class=&quot;syntax-meta syntax-property-name syntax-css&quot;&gt;uf&lt;/span&gt;, U&lt;span class=&quot;syntax-meta syntax-property-name syntax-css&quot;&gt;tf&lt;/span&gt;8P&lt;span class=&quot;syntax-meta syntax-property-name syntax-css&quot;&gt;ath&lt;/span&gt;B&lt;span class=&quot;syntax-meta syntax-property-name syntax-css&quot;&gt;uf&lt;/span&gt;&amp;gt; {
        &lt;span class=&quot;syntax-meta syntax-property-name syntax-css&quot;&gt;if&lt;/span&gt; !&lt;span class=&quot;syntax-meta syntax-property-name syntax-css&quot;&gt;path&lt;/span&gt;_&lt;span class=&quot;syntax-meta syntax-property-name syntax-css&quot;&gt;buf&lt;/span&gt;.&lt;span class=&quot;syntax-meta syntax-property-name syntax-css&quot;&gt;is&lt;/span&gt;_&lt;span class=&quot;syntax-meta syntax-property-name syntax-css&quot;&gt;absolute&lt;/span&gt;() {
            &lt;span class=&quot;syntax-meta syntax-property-name syntax-css&quot;&gt;return&lt;/span&gt; E&lt;span class=&quot;syntax-meta syntax-property-name syntax-css&quot;&gt;rr&lt;/span&gt;(&lt;span class=&quot;syntax-meta syntax-property-name syntax-css&quot;&gt;path&lt;/span&gt;_&lt;span class=&quot;syntax-meta syntax-property-name syntax-css&quot;&gt;buf&lt;/span&gt;);
&lt;/span&gt;        &lt;span class=&quot;syntax-punctuation syntax-section syntax-property-list syntax-css&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;syntax-meta syntax-selector syntax-css&quot;&gt;        Ok(AbsPathBuf(path_buf&lt;/span&gt;))
    }
}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Subsequent code doesn&#39;t have to validate the the path is absolute. The type enforces it.&lt;/p&gt;
&lt;p&gt;Note also that &lt;code&gt;AbsPathBuf&lt;/code&gt; wraps &lt;code&gt;Utf8PathBuf&lt;/code&gt;, not &lt;code&gt;PathBuf&lt;/code&gt;. &lt;code&gt;Utf8PathBuf&lt;/code&gt; is itself a custom, &amp;quot;parsed&amp;quot; type refinement from the &lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://docs.rs/camino/latest/camino/&quot;&gt;camino crate&lt;/a&gt;. Regular paths in the Rust standard library aren&#39;t guaranteed to be valid UTF-8, so they cannot be easily converted to a &lt;code&gt;String&lt;/code&gt; (which has to be valid UTF-8 in Rust); &lt;code&gt;camino::Utf8PathBuf&lt;/code&gt; establishes validity on construction, and can then be converted to a string with just:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;code-snippet&quot; data-language=&quot;Rust&quot;&gt;&lt;span class=&quot;syntax-source syntax-rust&quot;&gt;&lt;span class=&quot;syntax-meta syntax-function syntax-rust&quot;&gt;&lt;span class=&quot;syntax-meta syntax-function syntax-rust&quot;&gt;&lt;span class=&quot;syntax-storage syntax-type syntax-function syntax-rust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;syntax-entity syntax-name syntax-function syntax-rust&quot;&gt;as_str&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-function syntax-rust&quot;&gt;&lt;span class=&quot;syntax-meta syntax-function syntax-parameters syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-parameters syntax-begin syntax-rust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-keyword syntax-operator syntax-rust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;syntax-variable syntax-parameter syntax-rust&quot;&gt;self&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-function syntax-rust&quot;&gt;&lt;span class=&quot;syntax-meta syntax-function syntax-parameters syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-parameters syntax-end syntax-rust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-function syntax-rust&quot;&gt; &lt;span class=&quot;syntax-meta syntax-function syntax-return-type syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-separator syntax-rust&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;syntax-keyword syntax-operator syntax-rust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;syntax-storage syntax-type syntax-rust&quot;&gt;str&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-function syntax-rust&quot;&gt;&lt;span class=&quot;syntax-meta syntax-block syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-block syntax-begin syntax-rust&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;syntax-keyword syntax-operator syntax-rust&quot;&gt;...&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-block syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-block syntax-end syntax-rust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So we have an example of gradual parsing and type refinement here:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;code-snippet&quot;&gt;std::path::PathBuf

      |
      |   prove UTF-8
      |
      V

camino::Utf8PathBuf

      |
      |   prove absolute
      |
      V

rust-analyzer&amp;#39;s paths::AbsPathBuf
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Non-zero integers&lt;/h2&gt;
&lt;p&gt;Rust has a generic type called &lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://doc.rust-lang.org/std/num/struct.NonZero.html&quot;&gt;NonZero&lt;/a&gt;, to describe unsigned numeric quantities that are known to be non-zero.&lt;/p&gt;
&lt;p&gt;For example, &lt;code&gt;thread::available_parallelism&lt;/code&gt; is defined as:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;code-snippet&quot; data-language=&quot;Rust&quot;&gt;&lt;span class=&quot;syntax-source syntax-rust&quot;&gt;&lt;span class=&quot;syntax-meta syntax-function syntax-rust&quot;&gt;&lt;span class=&quot;syntax-meta syntax-function syntax-rust&quot;&gt;&lt;span class=&quot;syntax-storage syntax-modifier syntax-rust&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;syntax-storage syntax-type syntax-function syntax-rust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;syntax-entity syntax-name syntax-function syntax-rust&quot;&gt;available_parallelism&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-function syntax-rust&quot;&gt;&lt;span class=&quot;syntax-meta syntax-function syntax-parameters syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-parameters syntax-begin syntax-rust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-function syntax-rust&quot;&gt;&lt;span class=&quot;syntax-meta syntax-function syntax-parameters syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-parameters syntax-end syntax-rust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-function syntax-rust&quot;&gt; &lt;span class=&quot;syntax-meta syntax-function syntax-return-type syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-separator syntax-rust&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;syntax-meta syntax-generic syntax-rust&quot;&gt;Result&lt;span class=&quot;syntax-punctuation syntax-definition syntax-generic syntax-begin syntax-rust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-generic syntax-rust&quot;&gt;NonZero&lt;span class=&quot;syntax-punctuation syntax-definition syntax-generic syntax-begin syntax-rust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;syntax-storage syntax-type syntax-rust&quot;&gt;usize&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-definition syntax-generic syntax-end syntax-rust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-definition syntax-generic syntax-end syntax-rust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If the call is successful, it returns a &lt;code&gt;NonZero&amp;lt;usize&amp;gt;&lt;/code&gt;, which is like a normal &lt;code&gt;usize&lt;/code&gt; with the restriction that it&#39;s not zero. Client code doesn&#39;t have to keep checking whether the parallelism is 0 - it&#39;s enshrined in the type system.&lt;/p&gt;
&lt;p&gt;Rust defines the &lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://doc.rust-lang.org/std/primitive.u32.html#impl-Div%3CNonZero%3Cu32%3E%3E-for-u32&quot;&gt;division operator&lt;/a&gt; with &lt;code&gt;NonZero&amp;lt;usize&amp;gt;&lt;/code&gt; in the denominator as an operation that &amp;quot;cannot panic&amp;quot;.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;NonZero&lt;/code&gt; has an additional advantage: zero is an invalid value for the type, so Rust can use the zero bit pattern to represent &lt;code&gt;None&lt;/code&gt;. Consequently, &lt;code&gt;Option&amp;lt;NonZeroUsize&amp;gt;&lt;/code&gt; is &lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://doc.rust-lang.org/std/option/index.html#representation&quot;&gt;guaranteed to have the same size&lt;/a&gt; and alignment as &lt;code&gt;NonZeroUsize&lt;/code&gt; itself (and as &lt;code&gt;usize&lt;/code&gt;). This can avoid the extra storage that an &lt;code&gt;Option&amp;lt;usize&amp;gt;&lt;/code&gt; would generally require.&lt;/p&gt;
&lt;h2&gt;Parsing JSON&lt;/h2&gt;
&lt;p&gt;A common example of the &amp;quot;parse, don&#39;t validate&amp;quot; idiom appears in deserializing data from a JSON string. Rust&#39;s &lt;code&gt;serde&lt;/code&gt; crate enables us to do the parsing, with validated decisions encoded into the type system, e.g.:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;code-snippet&quot;&gt;#[derive(Debug, Deserialize)]
struct Config {
    name: String,
    workers: NonZeroUsize,
    mode: Mode,
}

#[derive(Debug, Deserialize)]
#[serde(rename_all = &amp;quot;snake_case&amp;quot;)]
enum Mode {
    Fast,
    Safe,
}
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And then later:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;code-snippet&quot;&gt;let input = r#&amp;quot;
     {
         &amp;quot;name&amp;quot;: &amp;quot;compiler&amp;quot;,
         &amp;quot;workers&amp;quot;: 4,
         &amp;quot;mode&amp;quot;: &amp;quot;fast&amp;quot;
     }
 &amp;quot;#;

 let config: Config = serde_json::from_str(input)?;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;There is a lot happening behind the scenes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The types of all fields are enforced (e.g. &amp;quot;name&amp;quot; cannot be an array).&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;mode&lt;/code&gt; is validated to be one of the enum values of &lt;code&gt;Mode&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;workers&lt;/code&gt; is validated to be a non-zero integer, because of the &lt;code&gt;NonZeroUsize&lt;/code&gt; field type.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;We take code like this for granted these days, but it&#39;s still a great example of the pattern discussed in this post. Once the parser converted &lt;code&gt;mode&lt;/code&gt; into the &lt;code&gt;Mode&lt;/code&gt; enum, no further validation is required.&lt;/p&gt;
&lt;p&gt;In dynamic languages like Python and JS, the process is usually much more manual. Python&#39;s &lt;code&gt;json.loads&lt;/code&gt; gives us a dictionary, and it&#39;s up to the user to validate its contents. Libraries like Pydantic permit an approach closer to Rust&#39;s, but they&#39;re not universally used.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;&lt;sup class=&quot;citation-ref&quot;&gt;&lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://eli.thegreenplace.net/2026/rusty-thoughts-on-parse-dont-validate/#footnote-reference-1&quot;&gt;[1]&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;Other languages - like Go or Python - have a runtime check that raises some sort of exception or panic when &lt;code&gt;lst[0]&lt;/code&gt; is accessed on an empty list or slice.&lt;/p&gt;
&lt;p&gt;&lt;sup class=&quot;citation-ref&quot;&gt;&lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://eli.thegreenplace.net/2026/rusty-thoughts-on-parse-dont-validate/#footnote-reference-2&quot;&gt;[2]&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;The project implements its own &lt;code&gt;NonEmpty&lt;/code&gt;, without relying on the &lt;code&gt;nonempty&lt;/code&gt; crate, but all the points in this post apply.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;For comments, please send me &lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;mailto:eliben@gmail.com&quot;&gt;an email&lt;/a&gt;.&lt;/p&gt;
</content>
  </entry>
</feed>
