<story><title>Why Rust closures are somewhat hard</title><url>https://stevedonovan.github.io/rustifications/2018/08/18/rust-closures-are-hard.html</url></story><parent_chain><item><author>glittery</author><text>One thing that&amp;#x27;s always concerned me about Rust is that everyone mononorphizes everything (e.g. closures are always unboxed except in the rare cases where dynamic dispatch is necessary). Hopefully this is a baseless fear, but isn&amp;#x27;t this a recipe for executable bloat?</text></item><item><author>Animats</author><text>Rust decides at compile time how long the data stored in a closure must live. You can create situations where that&amp;#x27;s hard to define, and the compiler, properly, won&amp;#x27;t permit that. It&amp;#x27;s very clever.&lt;p&gt;(Rust tends to use closures heavily, in places other languages don&amp;#x27;t. So they need all the performance they can get.)</text></item></parent_chain><comment><author>withoutboats</author><text>It can be! And arguably people have leaned too hard on the decisions made in the std as an example: in std, everything is generic so that it can be inlined well, because std APIs underlie everything. At the application layer, this is not obviously what you want.&lt;p&gt;However, in many cases, a well designed generic API will be able take a trait object in the place of `T`. That way, at the application layer, you can decide to pass trait objects around, reducing code size and - maybe more importantly to you - compile times. cargo does this for example in some places where the performance regression is insignificant but it saves noticeable compile time.&lt;p&gt;Sometimes libraries accidentally don&amp;#x27;t set things up so that you can pass either a concrete `T` or a dynamically dispatched trait object to their APIs; we&amp;#x27;re hoping to find a way of making it less likely for this to go wrong in the future.</text></comment>
<story><title>Why Rust closures are somewhat hard</title><url>https://stevedonovan.github.io/rustifications/2018/08/18/rust-closures-are-hard.html</url></story><parent_chain><item><author>glittery</author><text>One thing that&amp;#x27;s always concerned me about Rust is that everyone mononorphizes everything (e.g. closures are always unboxed except in the rare cases where dynamic dispatch is necessary). Hopefully this is a baseless fear, but isn&amp;#x27;t this a recipe for executable bloat?</text></item><item><author>Animats</author><text>Rust decides at compile time how long the data stored in a closure must live. You can create situations where that&amp;#x27;s hard to define, and the compiler, properly, won&amp;#x27;t permit that. It&amp;#x27;s very clever.&lt;p&gt;(Rust tends to use closures heavily, in places other languages don&amp;#x27;t. So they need all the performance they can get.)</text></item></parent_chain><comment><author>chc4</author><text>Yes, and there have been some cases of people hitting very large binaries and having to put effort into slimming them down.&lt;p&gt;In most of those cases it&amp;#x27;s due to either wanting to run in very constrained space or distribution size, and then the problem is due to some blanket impl for a bunch of types that can safely be removed though. There are a few cargo submodules that will do executable size analysis with regard to monomorphization to show the outliers.&lt;p&gt;There&amp;#x27;s not really a good solution for this. Having your code be fast by default in exchange for more space seems like the trivially correct choice to make when most people have hundreds of gigabytes of free hard drive space and binaries don&amp;#x27;t get above a few megas, while CPU speed has stagnated. If they want runtime type matching instead, they can still do it.</text></comment>