<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
    <title>Mesoloop - Blog</title>
    <link rel="self" type="application/atom+xml" href="https://www.axelmagn.com/blog/atom.xml"/>
    <link rel="alternate" type="text/html" href="https://www.axelmagn.com/blog/"/>
    <generator uri="https://www.getzola.org/">Zola</generator>
    <updated>2026-10-03T00:00:00+00:00</updated>
    <id>https://www.axelmagn.com/blog/atom.xml</id>
    <entry xml:lang="en">
        <title>We have Traits at Home</title>
        <published>2026-10-03T00:00:00+00:00</published>
        <updated>2026-10-03T00:00:00+00:00</updated>
        
        <author>
          <name>
            Axel Magnuson
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.axelmagn.com/blog/202610-zig-traits/"/>
        <id>https://www.axelmagn.com/blog/202610-zig-traits/</id>
        
        <content type="html" xml:base="https://www.axelmagn.com/blog/202610-zig-traits/">&lt;p&gt;I have had more time recently to write code in Zig, and it has been good for my
soul. I wanted to share some insights I have arrived at regarding abstractions
in Zig, including some techniques that I have found useful but not seen employed
more broadly.&lt;/p&gt;
&lt;p&gt;Considerable&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-seguin2023-1&quot;&gt;&lt;a href=&quot;https://www.axelmagn.com/blog/202610-zig-traits/#fn-seguin2023&quot;&gt;[1]&lt;/a&gt;&lt;/sup&gt; ink&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-figuratively-1&quot;&gt;&lt;a href=&quot;https://www.axelmagn.com/blog/202610-zig-traits/#fn-figuratively&quot;&gt;[2]&lt;/a&gt;&lt;/sup&gt; has&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-wong2025-1&quot;&gt;&lt;a href=&quot;https://www.axelmagn.com/blog/202610-zig-traits/#fn-wong2025&quot;&gt;[3]&lt;/a&gt;&lt;/sup&gt; been&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-mckay2025-1&quot;&gt;&lt;a href=&quot;https://www.axelmagn.com/blog/202610-zig-traits/#fn-mckay2025&quot;&gt;[4]&lt;/a&gt;&lt;/sup&gt;
spilled&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-cypert2026-1&quot;&gt;&lt;a href=&quot;https://www.axelmagn.com/blog/202610-zig-traits/#fn-cypert2026&quot;&gt;[5]&lt;/a&gt;&lt;/sup&gt; on Zig Interfaces, and justifiably so. While not a language
feature, interfaces are the de-facto way of implementing runtime polymorphism in
Zig. Yet&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-kelley2021-1&quot;&gt;&lt;a href=&quot;https://www.axelmagn.com/blog/202610-zig-traits/#fn-kelley2021&quot;&gt;[6]&lt;/a&gt;&lt;/sup&gt; more&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-redig2025-1&quot;&gt;&lt;a href=&quot;https://www.axelmagn.com/blog/202610-zig-traits/#fn-redig2025&quot;&gt;[7]&lt;/a&gt;&lt;/sup&gt; has been said about zig&#39;s comptime, and
how it may be leveraged to avoid the performance woes of dynamic dispatch and
write slick, data-oriented code.&lt;/p&gt;
&lt;p&gt;To put it briefly, polymorphism in Zig is conventionally obtained in one of two
ways:&lt;/p&gt;
&lt;ol start=&quot;2&quot;&gt;
&lt;li&gt;&lt;strong&gt;Dynamic Interfaces&lt;/strong&gt;: Use opaque pointers, virtual tables, and dynamic
dispatch to achieve runtime polymorphism.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Comptime Duck Typing&lt;/strong&gt;: Use type reflection, switch statements, and
monomorphism at compile time to achieve static polymorhpism.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;This state of affairs has proven to be quite effective so far, but it is not
without its tradeoffs.&lt;/p&gt;
&lt;p&gt;Interfaces offer the sort of type contracts that we are used to from other
languages. A function that accepts an interface has a guarantee of its method
signatures, but not its implementation. However because interfaces are, by
design, modular at runtime, they also introduce a hard barrier for the compiler
and thus a performance overhead. There is enough indirection that it often
cannot effectively apply the optimizations that it would to monomorphic code.&lt;/p&gt;
&lt;p&gt;For cases of performance critical code, Zig code typically relies on comptime
duck typing. A function argument is either &lt;code&gt;anytype&lt;/code&gt; or parameterized by a type
argument &lt;code&gt;T&lt;/code&gt;, and the function implementation will either perform compile-time
reflection or make assumptions about the type&#39;s methods that can be checked at
compile-time. Implementations can then be monomorphised, similar to C++
templating or C macros. This is slightly more safe than runtime duck typing,
because any interface violations will be caught at compile time rather than
runtime, but the caller and callee must still be careful to document and follow
the contract of what types may be passed.&lt;/p&gt;
&lt;p&gt;If you are coming from another strongly typed language, you would be forgiven
for finding this arrangement rather simplistic. This is perhaps by design
-- Zig aims to be simple. However if you have grown accustomed to Rust&#39;s traits
or Haskell typeclasses, there appears to be no ready equivalent in Zig.&lt;/p&gt;
&lt;p&gt;I will argue that, with a little adaptation, it is perfectly possible to express
similar abstractions over types in Zig userland. I would propose a new
&lt;strong&gt;convention&lt;/strong&gt; for defining compile-time type contracts as &lt;strong&gt;Traits&lt;/strong&gt; in Zig. It
doesn&#39;t require any libraries or machinery - in fact if fits remarkably well
into vanilla Zig. It is inspired by the functional programming world in general,
and OCaml in particular.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Definition:&lt;/strong&gt; a Trait is a compile-time struct which contains related
functions over a given type. &lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-ocaml-inspired-1&quot;&gt;&lt;a href=&quot;https://www.axelmagn.com/blog/202610-zig-traits/#fn-ocaml-inspired&quot;&gt;[8]&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;So as not to bury the lead, let me begin with a brief example of how we might
define a trait for folding (reducing) on a type.&lt;/p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #CDD6F4; background-color: #1E1E2E;&quot; &gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #9399B2;font-style: italic;&quot;&gt;/// T forms a Reducer under an empty value and a combine operation&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;fn&lt;/span&gt;&lt;span style=&quot;color: #F9E2AF;font-style: italic;&quot;&gt; Reducer&lt;/span&gt;&lt;span&gt;(T&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt; type&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;type&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;    return struct&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        empty&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span&gt; T&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        combine&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt; fn&lt;/span&gt;&lt;span&gt; (T&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; T) T&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;        fn&lt;/span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt; reduce&lt;/span&gt;&lt;span&gt;(self&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: #F38BA8;font-style: italic;&quot;&gt; @This&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; xs&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span&gt; []&lt;/span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;const&lt;/span&gt;&lt;span&gt; T) T {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;            var&lt;/span&gt;&lt;span&gt; accum&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; =&lt;/span&gt;&lt;span&gt; self&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;.&lt;/span&gt;&lt;span&gt;empty&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;            for&lt;/span&gt;&lt;span&gt; (xs) &lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;|&lt;/span&gt;&lt;span&gt;x&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;|&lt;/span&gt;&lt;span&gt; accum&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; =&lt;/span&gt;&lt;span&gt; self&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt;combine&lt;/span&gt;&lt;span&gt;(accum&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; x)&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;            return&lt;/span&gt;&lt;span&gt; accum&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #9399B2;font-style: italic;&quot;&gt;/// i32 forms a sum reducer under 0 and addition&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;const&lt;/span&gt;&lt;span&gt; sum_trait&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt; impl&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: #F9E2AF;font-style: italic;&quot;&gt;Reducer&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;i32&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt; struct&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;    pub const&lt;/span&gt;&lt;span&gt; empty&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color: #FAB387;&quot;&gt; 0&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;    pub fn&lt;/span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt; combine&lt;/span&gt;&lt;span&gt;(x&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span&gt; T&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; y&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span&gt; T) T { &lt;/span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;return&lt;/span&gt;&lt;span&gt; x&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; +&lt;/span&gt;&lt;span&gt; y&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;/span&gt;&lt;span&gt; }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;})&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #9399B2;font-style: italic;&quot;&gt;/// i32 forms a product reducer under 1 and multiplication&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;const&lt;/span&gt;&lt;span&gt; product_trait&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt; impl&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: #F9E2AF;font-style: italic;&quot;&gt;Reducer&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;i32&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt; struct&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;    pub const&lt;/span&gt;&lt;span&gt; empty&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color: #FAB387;&quot;&gt; 1&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;    pub fn&lt;/span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt; combine&lt;/span&gt;&lt;span&gt;(x&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span&gt; T&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; y&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span&gt; T) T { &lt;/span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;return&lt;/span&gt;&lt;span&gt; x&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; *&lt;/span&gt;&lt;span&gt; y&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;/span&gt;&lt;span&gt; }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;})&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;export fn&lt;/span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt; run&lt;/span&gt;&lt;span&gt;(buf&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span&gt; [&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;*c&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;i32&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; n&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt; usize&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;i32&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;    const&lt;/span&gt;&lt;span&gt; sum&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; =&lt;/span&gt;&lt;span&gt; sum_trait&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt;reduce&lt;/span&gt;&lt;span&gt;(buf[&lt;/span&gt;&lt;span style=&quot;color: #FAB387;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;..&lt;/span&gt;&lt;span&gt;n])&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;    const&lt;/span&gt;&lt;span&gt; product&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; =&lt;/span&gt;&lt;span&gt; product_trait&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt;reduce&lt;/span&gt;&lt;span&gt;(buf[&lt;/span&gt;&lt;span style=&quot;color: #FAB387;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;..&lt;/span&gt;&lt;span&gt;n])&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;    return&lt;/span&gt;&lt;span&gt; sum&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; +&lt;/span&gt;&lt;span&gt; product&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Ugh. Isn&#39;t that just buttery smooth?&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-so-good-1&quot;&gt;&lt;a href=&quot;https://www.axelmagn.com/blog/202610-zig-traits/#fn-so-good&quot;&gt;[9]&lt;/a&gt;&lt;/sup&gt; The contract is clear, LSP
autocompletion picks it up, the compiler even knows to inline it and unroll the
loop.&lt;/p&gt;
&lt;p&gt;Traits are just bags of functions and types that tell the receiving function how
to execute subtasks that it&#39;s not responsible for defining. They behave a lot
like vtables, except that they are evaluated at comptime rather than runtime.&lt;/p&gt;
&lt;h2 id=&quot;conventional-polymorphism-vs-traits&quot;&gt;Conventional Polymorphism vs Traits&lt;/h2&gt;
&lt;p&gt;To justify traits, let&#39;s take a tour through Zig polymorphism with a common
motivating example: arithmetic operations. I&#39;ve seen a few complaints over the
years about how awkward is it to do math in Zig over user-defined types. In its
pursuit of explicit control flow, Zig has eschewed operator overloading, and
this can be jarring if you&#39;re coming from other typed languages.&lt;/p&gt;
&lt;p&gt;Let&#39;s imagine we have some user-defined types like &lt;code&gt;Rational&lt;/code&gt; and &lt;code&gt;Complex&lt;/code&gt;, and
we want to define their basic arithmentic operations. We would probably end up
with something like the following.&lt;/p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #CDD6F4; background-color: #1E1E2E;&quot; &gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;const&lt;/span&gt;&lt;span&gt; Rational&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt; struct&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    numerator&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt; i32&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    denominator&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt; i32&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;    fn&lt;/span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt; add&lt;/span&gt;&lt;span&gt;(lhs&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span&gt; Rational&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; rhs&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span&gt; Rational) Rational {&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;...&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;    fn&lt;/span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt; sub&lt;/span&gt;&lt;span&gt;(lhs&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span&gt; Rational&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; rhs&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span&gt; Rational) Rational {&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;...&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;    fn&lt;/span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt; mul&lt;/span&gt;&lt;span&gt;(lhs&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span&gt; Rational&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; rhs&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span&gt; Rational) Rational {&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;...&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;    fn&lt;/span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt; div&lt;/span&gt;&lt;span&gt;(lhs&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span&gt; Rational&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; rhs&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span&gt; Rational) Rational {&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;...&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;const&lt;/span&gt;&lt;span&gt; Complex&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt; struct&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    real&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt; f32&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    imaginary&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt; f32&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;    fn&lt;/span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt; add&lt;/span&gt;&lt;span&gt;(lhs&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span&gt; Complex&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; rhs&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span&gt; Complex) Complex {&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;...&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;    fn&lt;/span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt; sub&lt;/span&gt;&lt;span&gt;(lhs&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span&gt; Complex&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; rhs&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span&gt; Complex) Complex {&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;...&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;    fn&lt;/span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt; mul&lt;/span&gt;&lt;span&gt;(lhs&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span&gt; Complex&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; rhs&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span&gt; Complex) Complex {&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;...&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;    fn&lt;/span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt; div&lt;/span&gt;&lt;span&gt;(lhs&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span&gt; Complex&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; rhs&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span&gt; Complex) Complex {&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;...&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For the sake of having something to do with them, let&#39;s say that we want to
compute the
&lt;a rel=&quot;external&quot; href=&quot;https://en.wikipedia.org/wiki/M%C3%B6bius_transformation&quot;&gt;Möbius transformation&lt;/a&gt;:
&lt;code&gt;(a * x + b) / (c * x + d)&lt;/code&gt;, which is useful for complex numbers as well as
rationals. To keep things simple, we&#39;ll assume that all arguments to the
function are of the same type.&lt;/p&gt;
&lt;h3 id=&quot;comptime-duck-typing&quot;&gt;Comptime Duck Typing&lt;/h3&gt;
&lt;p&gt;If we were to implement the Mobius transformation naively, we could just use
built-in operators.&lt;/p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #CDD6F4; background-color: #1E1E2E;&quot; &gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;fn&lt;/span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt; mobius&lt;/span&gt;&lt;span&gt;(T&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt; type&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; x&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span&gt; T&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; a&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span&gt; T&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; b&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span&gt; T&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; c&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span&gt; T&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; d&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span&gt; T) T {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;    return&lt;/span&gt;&lt;span&gt; (a&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; *&lt;/span&gt;&lt;span&gt; x&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; +&lt;/span&gt;&lt;span&gt; b) &lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;/&lt;/span&gt;&lt;span&gt; (c&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; *&lt;/span&gt;&lt;span&gt; x&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; +&lt;/span&gt;&lt;span&gt; d)&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This would work fine, as long as the inputs were all floats of the same type.
Division would break for integers, and of course it wouldn&#39;t work with our
user-defined types, but it&#39;s a starting point.&lt;/p&gt;
&lt;p&gt;We could of course notice that both of our user-defined types have arithmetic
functions with matching names and similar signatures, which would lend
themselves to duck typing as well.&lt;/p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #CDD6F4; background-color: #1E1E2E;&quot; &gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;fn&lt;/span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt; mobius&lt;/span&gt;&lt;span&gt;(T&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt; type&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; x&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span&gt; T&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; a&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span&gt; T&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; b&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span&gt; T&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; c&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span&gt; T&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; d&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span&gt; T) T {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;    const&lt;/span&gt;&lt;span&gt; numerator&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; =&lt;/span&gt;&lt;span&gt; a&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt;mul&lt;/span&gt;&lt;span&gt;(x)&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt;add&lt;/span&gt;&lt;span&gt;(b)&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;    const&lt;/span&gt;&lt;span&gt; denominator&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; =&lt;/span&gt;&lt;span&gt; c&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt;mul&lt;/span&gt;&lt;span&gt;(x)&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt;add&lt;/span&gt;&lt;span&gt;(d)&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;    return&lt;/span&gt;&lt;span&gt; numerator&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt;div&lt;/span&gt;&lt;span&gt;(denominator)&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This will work for our user-defined types, but obviously not with Zig&#39;s
primitive types. We would have to wrap those in our own user-defined types with
their own functions. More troublingly, this sort of ties us to a sort of
object-oriented pattern: the de-facto way to obey this abstraction contract is
to define methods on the struct.&lt;/p&gt;
&lt;p&gt;The good news is that it&#39;s all monomorphised at compile time, allowing the
compiler to simplify and inline these function calls.&lt;/p&gt;
&lt;h3 id=&quot;interfaces-vtables&quot;&gt;Interfaces &amp;amp; VTables&lt;/h3&gt;
&lt;p&gt;If we wanted this to work dynamically at runtime, we could perhaps declare a
&lt;code&gt;Num&lt;/code&gt; interface that uses a VTable and opaque pointer to dynamically dispatch
these math operations.&lt;/p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #CDD6F4; background-color: #1E1E2E;&quot; &gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;const&lt;/span&gt;&lt;span&gt; Num&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt; struct&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    value&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span&gt; [&lt;/span&gt;&lt;span style=&quot;color: #FAB387;&quot;&gt;32&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;u8&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    vtable&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;: *&lt;/span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;const&lt;/span&gt;&lt;span&gt; VTable&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;    const&lt;/span&gt;&lt;span&gt; VTable&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt; struct&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        add&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;: *&lt;/span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;const fn&lt;/span&gt;&lt;span&gt;([&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;*&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;u8&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; [&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;*&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;u8&lt;/span&gt;&lt;span&gt;) Num&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        sub&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;: *&lt;/span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;const fn&lt;/span&gt;&lt;span&gt;([&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;*&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;u8&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; [&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;*&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;u8&lt;/span&gt;&lt;span&gt;) Num&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        mul&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;: *&lt;/span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;const fn&lt;/span&gt;&lt;span&gt;([&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;*&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;u8&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; [&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;*&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;u8&lt;/span&gt;&lt;span&gt;) Num&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        div&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;: *&lt;/span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;const fn&lt;/span&gt;&lt;span&gt;([&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;*&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;u8&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; [&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;*&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;u8&lt;/span&gt;&lt;span&gt;) Num&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;    fn&lt;/span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt; add&lt;/span&gt;&lt;span&gt;(lhs&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span&gt; Num&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; rhs&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span&gt; Num) Num { &lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;...&lt;/span&gt;&lt;span&gt; }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;    fn&lt;/span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt; sub&lt;/span&gt;&lt;span&gt;(lhs&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span&gt; Num&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; rhs&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span&gt; Num) Num { &lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;...&lt;/span&gt;&lt;span&gt; }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;    fn&lt;/span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt; mul&lt;/span&gt;&lt;span&gt;(lhs&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span&gt; Num&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; rhs&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span&gt; Num) Num { &lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;...&lt;/span&gt;&lt;span&gt; }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;    fn&lt;/span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt; div&lt;/span&gt;&lt;span&gt;(lhs&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span&gt; Num&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; rhs&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span&gt; Num) Num { &lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;...&lt;/span&gt;&lt;span&gt; }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;    fn&lt;/span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt; mobius&lt;/span&gt;&lt;span&gt;(x&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span&gt; Num&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; a&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span&gt; Num&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; b&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span&gt; Num&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; c&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span&gt; Num&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; d&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span&gt; Num) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;        const&lt;/span&gt;&lt;span&gt; numerator&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; =&lt;/span&gt;&lt;span&gt; a&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt;mul&lt;/span&gt;&lt;span&gt;(x)&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt;add&lt;/span&gt;&lt;span&gt;(b)&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;        const&lt;/span&gt;&lt;span&gt; denominator&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; =&lt;/span&gt;&lt;span&gt; c&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt;mul&lt;/span&gt;&lt;span&gt;(x)&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt;add&lt;/span&gt;&lt;span&gt;(d)&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;        return&lt;/span&gt;&lt;span&gt; numerator&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt;div&lt;/span&gt;&lt;span&gt;(denominator)&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We would then need to wire up &lt;code&gt;Complex&lt;/code&gt; and &lt;code&gt;Rational&lt;/code&gt; to expose
&lt;code&gt;fn num(self: *Self) Num&lt;/code&gt; (or some such) that wraps our arithmentic functions,
which is a little too tedious to reproduce here, but it would work fine on the
happy path. You would of course need to be a bit careful: there&#39;s nothing
stopping you from mixing complex and rational numbers in your function calls,
and this would lead to undefined behavior. You could probably add some saftey
checks with a bit of overengineering, but we won&#39;t get into that here.&lt;/p&gt;
&lt;p&gt;Not only is this clunkier than comptime duck typing, it will also be slower. We
are effectively demanding dynamic dispatch whenever we want to do a math
operation, which will trip up the compiler and have a significant performance
impact if we&#39;re doing a lot of math.&lt;/p&gt;
&lt;h3 id=&quot;traits&quot;&gt;Traits&lt;/h3&gt;
&lt;p&gt;When we define the mobius function, we really want to say &quot;I don&#39;t know what
type I&#39;m dealing with, but it needs to have arithmetic operations.&quot; In this sort
of case, I think it makes the most sense to just pass the functions it needs to
use at compile-time. This would remove any ambiguity, at the cost of being
rather explicit.&lt;/p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #CDD6F4; background-color: #1E1E2E;&quot; &gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;fn&lt;/span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt; mobius&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;    comptime&lt;/span&gt;&lt;span&gt; T&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt; type&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;    comptime&lt;/span&gt;&lt;span&gt; add&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt; fn&lt;/span&gt;&lt;span&gt; (T&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; T) T&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;    comptime&lt;/span&gt;&lt;span&gt; mul&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt; fn&lt;/span&gt;&lt;span&gt; (T&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; T) T&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;    comptime&lt;/span&gt;&lt;span&gt; div&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt; fn&lt;/span&gt;&lt;span&gt; (T&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; T) T&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    x&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span&gt; T&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    a&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span&gt; T&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    b&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span&gt; T&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    c&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span&gt; T&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    d&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span&gt; T&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;) T {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;    const&lt;/span&gt;&lt;span&gt; numerator&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt; add&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt;mul&lt;/span&gt;&lt;span&gt;(a&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; x)&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; b)&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;    const&lt;/span&gt;&lt;span&gt; denominator&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt; add&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt;mul&lt;/span&gt;&lt;span&gt;(c&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; x)&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; d)&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;    return&lt;/span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt; div&lt;/span&gt;&lt;span&gt;(numerator&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; denominator)&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is effectively compile-time dependency injection at a really fine-grained
level. The signature is rather verbose, but there&#39;s actually a lot less
boilerplate to write for &lt;code&gt;Complex&lt;/code&gt; or &lt;code&gt;Rational&lt;/code&gt; compared to runtime interfaces.&lt;/p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #CDD6F4; background-color: #1E1E2E;&quot; &gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt;mobius&lt;/span&gt;&lt;span&gt;(Complex&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; Complex&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;.&lt;/span&gt;&lt;span&gt;add&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; Complex&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;.&lt;/span&gt;&lt;span&gt;mul&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; Complex&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;.&lt;/span&gt;&lt;span&gt;div&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; x&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; a&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; b&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; c&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; d)&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt;mobius&lt;/span&gt;&lt;span&gt;(Real&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; Real&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;.&lt;/span&gt;&lt;span&gt;add&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; Real&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;.&lt;/span&gt;&lt;span&gt;mul&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; Real&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;.&lt;/span&gt;&lt;span&gt;div&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; x&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; a&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; b&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; c&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; d)&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;From here, it&#39;s not a huge leap to traits. We&#39;re effectively just cleaning up
the function signature by gathering together the arithmetic functions into one
struct.&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-num-is-simplified-1&quot;&gt;&lt;a href=&quot;https://www.axelmagn.com/blog/202610-zig-traits/#fn-num-is-simplified&quot;&gt;[10]&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #CDD6F4; background-color: #1E1E2E;&quot; &gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;fn&lt;/span&gt;&lt;span style=&quot;color: #F9E2AF;font-style: italic;&quot;&gt; Num&lt;/span&gt;&lt;span&gt;(T&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt; type&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;type&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;    return struct&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        add&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt; fn&lt;/span&gt;&lt;span&gt; (T&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; T) T&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        sub&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt; fn&lt;/span&gt;&lt;span&gt; (T&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; T) T&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        mul&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt; fn&lt;/span&gt;&lt;span&gt; (T&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; T) T&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        div&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt; fn&lt;/span&gt;&lt;span&gt; (T&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; T) T&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;fn&lt;/span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt; mobius&lt;/span&gt;&lt;span&gt;(T&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt; type&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; num&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: #F9E2AF;font-style: italic;&quot;&gt; Num&lt;/span&gt;&lt;span&gt;(T)&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; x&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span&gt; T&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; a&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span&gt; T&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; b&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span&gt; T&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; c&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span&gt; T&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; d&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span&gt; T) T {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;    const&lt;/span&gt;&lt;span&gt; numerator&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; =&lt;/span&gt;&lt;span&gt; num&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt;add&lt;/span&gt;&lt;span&gt;(num&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt;mul&lt;/span&gt;&lt;span&gt;(a&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; x)&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; b)&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;    const&lt;/span&gt;&lt;span&gt; denominator&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; =&lt;/span&gt;&lt;span&gt; num&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt;add&lt;/span&gt;&lt;span&gt;(num&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt;mul&lt;/span&gt;&lt;span&gt;(c&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; x)&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; d)&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;    return&lt;/span&gt;&lt;span&gt; num&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt;div&lt;/span&gt;&lt;span&gt;(numerator&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; denominator)&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;From here, I usually just declare the trait implementation as part of my type.&lt;/p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #CDD6F4; background-color: #1E1E2E;&quot; &gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;const&lt;/span&gt;&lt;span&gt; Complex&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt; struct&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #9399B2;font-style: italic;&quot;&gt;    // fields...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;    const&lt;/span&gt;&lt;span&gt; num&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color: #F9E2AF;font-style: italic;&quot;&gt; Num&lt;/span&gt;&lt;span&gt;(Complex) { &lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;.&lt;/span&gt;&lt;span&gt;add&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; =&lt;/span&gt;&lt;span&gt; add&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; .&lt;/span&gt;&lt;span&gt;sub&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; =&lt;/span&gt;&lt;span&gt; sub&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; .&lt;/span&gt;&lt;span&gt;mul&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; =&lt;/span&gt;&lt;span&gt; mul&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; .&lt;/span&gt;&lt;span&gt;div&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; =&lt;/span&gt;&lt;span&gt; div }&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #9399B2;font-style: italic;&quot;&gt;    // functions (add, sub, mul, div...)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt;mobius&lt;/span&gt;&lt;span&gt;(Complex&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; Complex&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;.&lt;/span&gt;&lt;span&gt;num&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; x&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; a&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; b&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; c&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; d)&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;What I really like about this approach is how flexible it is, while remaining
very clear about the contract between the function and type. For example,
imagine that we wanted to extend our definition of &lt;code&gt;Num&lt;/code&gt; to the primitive types
like &lt;code&gt;i32&lt;/code&gt; and &lt;code&gt;f32&lt;/code&gt;. There are a bunch of ways we could do this, but I would
probably just define a function that produces something appropriate for integer
and float types.&lt;/p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #CDD6F4; background-color: #1E1E2E;&quot; &gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;fn&lt;/span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt; builtinNum&lt;/span&gt;&lt;span&gt;(T&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt; type&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span style=&quot;color: #F9E2AF;font-style: italic;&quot;&gt;Num&lt;/span&gt;&lt;span&gt;(T) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;    const&lt;/span&gt;&lt;span&gt; inner&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt; struct&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;        fn&lt;/span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt; add&lt;/span&gt;&lt;span&gt;(lhs&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span&gt; T&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; rhs&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span&gt; T) T { &lt;/span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;return&lt;/span&gt;&lt;span&gt; lhs&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; +&lt;/span&gt;&lt;span&gt; rhs&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;/span&gt;&lt;span&gt; }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;        fn&lt;/span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt; sub&lt;/span&gt;&lt;span&gt;(lhs&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span&gt; T&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; rhs&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span&gt; T) T { &lt;/span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;return&lt;/span&gt;&lt;span&gt; lhs&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; -&lt;/span&gt;&lt;span&gt; rhs&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;/span&gt;&lt;span&gt; }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;        fn&lt;/span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt; mul&lt;/span&gt;&lt;span&gt;(lhs&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span&gt; T&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; rhs&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span&gt; T) T { &lt;/span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;return&lt;/span&gt;&lt;span&gt; lhs&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; *&lt;/span&gt;&lt;span&gt; rhs&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;/span&gt;&lt;span&gt; }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;    const&lt;/span&gt;&lt;span&gt; div&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt; switch&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span style=&quot;color: #F38BA8;font-style: italic;&quot;&gt;@typeInfo&lt;/span&gt;&lt;span&gt;(T)) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;        .&lt;/span&gt;&lt;span&gt;int&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; .&lt;/span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;comptime_int&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt; struct&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;            fn&lt;/span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt; div&lt;/span&gt;&lt;span&gt;(lhs&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span&gt; T&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; rhs&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span&gt; T) T { &lt;/span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;color: #F38BA8;font-style: italic;&quot;&gt; @divTrunc&lt;/span&gt;&lt;span&gt;(lhs&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; rhs)&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;/span&gt;&lt;span&gt; }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;.&lt;/span&gt;&lt;span&gt;div&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;        .&lt;/span&gt;&lt;span&gt;float&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; .&lt;/span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;comptime_float&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt; struct&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;            fn&lt;/span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt; div&lt;/span&gt;&lt;span&gt;(lhs&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span&gt; T&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; rhs&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span&gt; T) T { &lt;/span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;return&lt;/span&gt;&lt;span&gt; lhs&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; /&lt;/span&gt;&lt;span&gt; rhs&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;/span&gt;&lt;span&gt; }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;.&lt;/span&gt;&lt;span&gt;div&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;        else&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #F38BA8;font-style: italic;&quot;&gt; @compileError&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt;&amp;quot;unsupported type: &amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; ++&lt;/span&gt;&lt;span style=&quot;color: #F38BA8;font-style: italic;&quot;&gt; @typeName&lt;/span&gt;&lt;span&gt;(T))&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;    return&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; .&lt;/span&gt;&lt;span&gt;{ &lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;.&lt;/span&gt;&lt;span&gt;add&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; =&lt;/span&gt;&lt;span&gt; inner&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;.&lt;/span&gt;&lt;span&gt;add&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; .&lt;/span&gt;&lt;span&gt;sub&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; =&lt;/span&gt;&lt;span&gt; inner&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;.&lt;/span&gt;&lt;span&gt;sub&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; .&lt;/span&gt;&lt;span&gt;mul&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; =&lt;/span&gt;&lt;span&gt; inner&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;.&lt;/span&gt;&lt;span&gt;mul&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; .&lt;/span&gt;&lt;span&gt;div&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; =&lt;/span&gt;&lt;span&gt; div }&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt;mobius&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;f32&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt; builtinNum&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;f32&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; x&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; a&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; b&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; c&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; d)&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Traits are also transparent to the compiler, which will happily monomorphize and
inline these functions. I prefer this over runtime polymorphism most of the
time, especially in hot loops or for library functions that are unopinionated on
data layout.&lt;/p&gt;
&lt;h3 id=&quot;limitations&quot;&gt;Limitations&lt;/h3&gt;
&lt;p&gt;You&#39;ll notice that traits have to be explicitly conditioned on a known type.
Unlike interfaces, there&#39;s no way to say &quot;give me a number, I don&#39;t care what
kind.&quot;  For some applications, it would be nice if we could have an associated
type.&lt;/p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #CDD6F4; background-color: #1E1E2E;&quot; &gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;fn&lt;/span&gt;&lt;span style=&quot;color: #F9E2AF;font-style: italic;&quot;&gt; Iter&lt;/span&gt;&lt;span&gt;(Elem&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt; type&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;type&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;    return struct&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        T&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt; type&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        next&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt; fn&lt;/span&gt;&lt;span&gt; (T) &lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;?&lt;/span&gt;&lt;span&gt;Elem&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Unfortunately, the above isn&#39;t valid Zig, and it&#39;s unclear how that would even
work at a language level.  Instead, traits insist that the types they are
operating on are known in advance.&lt;/p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #CDD6F4; background-color: #1E1E2E;&quot; &gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;fn&lt;/span&gt;&lt;span style=&quot;color: #F9E2AF;font-style: italic;&quot;&gt; Iter&lt;/span&gt;&lt;span&gt;(T&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt; type&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; Elem&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt; type&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;type&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;    return struct&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        next&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt; fn&lt;/span&gt;&lt;span&gt; (T) &lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;?&lt;/span&gt;&lt;span&gt;Elem&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I have not yet found an ergonomic way around this.  Traits do not play very
well with type erasure.&lt;/p&gt;
&lt;h2 id=&quot;trait-helpers&quot;&gt;Trait Helpers&lt;/h2&gt;
&lt;p&gt;Before proceeding, I want to introduce some small helper functions that have
streamlined how I work with traits.&lt;/p&gt;
&lt;h3 id=&quot;impl&quot;&gt;impl&lt;/h3&gt;
&lt;p&gt;If you adopt traits as a programming pattern and convention, you&#39;ll quickly end
up defining functions and passing them around. You will have already noticed
above that I define a lot of throwaway inner struct types, just so that I can
pull functions out of them. This has led to the following convenience function
for declaring trait implementations, which removes some of the boilerplate.&lt;/p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #CDD6F4; background-color: #1E1E2E;&quot; &gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;pub fn&lt;/span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt; impl&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;comptime&lt;/span&gt;&lt;span&gt; Trait&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt; type&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt; comptime&lt;/span&gt;&lt;span&gt; Impl&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt; type&lt;/span&gt;&lt;span&gt;) Trait {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;    comptime&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;        var&lt;/span&gt;&lt;span&gt; result&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span&gt; Trait&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt; undefined&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;        for&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span style=&quot;color: #F38BA8;font-style: italic;&quot;&gt;@typeInfo&lt;/span&gt;&lt;span&gt;(Trait)&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;.&lt;/span&gt;&lt;span&gt;@&amp;quot;struct&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;.&lt;/span&gt;&lt;span&gt;field_names) &lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;|&lt;/span&gt;&lt;span&gt;field_name&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;|&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F38BA8;font-style: italic;&quot;&gt;            @field&lt;/span&gt;&lt;span&gt;(result&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; field_name) &lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #F38BA8;font-style: italic;&quot;&gt; @field&lt;/span&gt;&lt;span&gt;(Impl&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; field_name)&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;        return&lt;/span&gt;&lt;span&gt; result&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I use this all over the place to derive trait implementations from anonymous
structs. For example, we could use it to rewrite &lt;code&gt;builtinNum&lt;/code&gt; to be a little
more concise and functional. Note that the declarations need to be public for
the type reflection to work.&lt;/p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #CDD6F4; background-color: #1E1E2E;&quot; &gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;fn&lt;/span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt; builtinNum&lt;/span&gt;&lt;span&gt;(T&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt; type&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span style=&quot;color: #F9E2AF;font-style: italic;&quot;&gt;Num&lt;/span&gt;&lt;span&gt;(T) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;    return&lt;/span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt; impl&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: #F9E2AF;font-style: italic;&quot;&gt;Num&lt;/span&gt;&lt;span&gt;(T)&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt; struct&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;        pub fn&lt;/span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt; add&lt;/span&gt;&lt;span&gt;(lhs&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span&gt; T&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; rhs&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span&gt; T) T { &lt;/span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;return&lt;/span&gt;&lt;span&gt; lhs&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; +&lt;/span&gt;&lt;span&gt; rhs&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;/span&gt;&lt;span&gt; }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;        pub fn&lt;/span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt; sub&lt;/span&gt;&lt;span&gt;(lhs&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span&gt; T&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; rhs&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span&gt; T) T { &lt;/span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;return&lt;/span&gt;&lt;span&gt; lhs&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; -&lt;/span&gt;&lt;span&gt; rhs&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;/span&gt;&lt;span&gt; }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;        pub fn&lt;/span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt; mul&lt;/span&gt;&lt;span&gt;(lhs&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span&gt; T&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; rhs&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span&gt; T) T { &lt;/span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;return&lt;/span&gt;&lt;span&gt; lhs&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; *&lt;/span&gt;&lt;span&gt; rhs&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;/span&gt;&lt;span&gt; }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;        pub const&lt;/span&gt;&lt;span&gt; div&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt; switch&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span style=&quot;color: #F38BA8;font-style: italic;&quot;&gt;@typeInfo&lt;/span&gt;&lt;span&gt;(T)) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;            .&lt;/span&gt;&lt;span&gt;int&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; .&lt;/span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;comptime_int&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt; struct&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;                fn&lt;/span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt; div&lt;/span&gt;&lt;span&gt;(lhs&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span&gt; T&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; rhs&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span&gt; T) T { &lt;/span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;color: #F38BA8;font-style: italic;&quot;&gt; @divTrunc&lt;/span&gt;&lt;span&gt;(lhs&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; rhs)&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;/span&gt;&lt;span&gt; }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            }&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;.&lt;/span&gt;&lt;span&gt;div&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;            .&lt;/span&gt;&lt;span&gt;float&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; .&lt;/span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;comptime_float&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt; struct&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;                fn&lt;/span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt; div&lt;/span&gt;&lt;span&gt;(lhs&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span&gt; T&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; rhs&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span&gt; T) T { &lt;/span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;return&lt;/span&gt;&lt;span&gt; lhs&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; /&lt;/span&gt;&lt;span&gt; rhs&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;/span&gt;&lt;span&gt; }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            }&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;.&lt;/span&gt;&lt;span&gt;div&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;            else&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #F38BA8;font-style: italic;&quot;&gt; @compileError&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt;&amp;quot;unsupported type: &amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; ++&lt;/span&gt;&lt;span style=&quot;color: #F38BA8;font-style: italic;&quot;&gt; @typeName&lt;/span&gt;&lt;span&gt;(T))&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    })&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&quot;gettrait&quot;&gt;getTrait&lt;/h3&gt;
&lt;p&gt;Most of the time, I don&#39;t mind passing trait implementations around explicitly.
I&#39;ve gotten into the habit, and just don&#39;t find it to be that big of a deal.
Trait functors make it pretty easy to reduce the boilerplate, and I like having
explicit control over how things are implemented.&lt;/p&gt;
&lt;p&gt;However when I&#39;m dealing with my own structs, 99% of the time the trait
implementation I&#39;m looking for is going to be declared as a const on the struct
itself. I use the function below to to easily retrieve or construct the most
common cases.&lt;/p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #CDD6F4; background-color: #1E1E2E;&quot; &gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;fn&lt;/span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt; getTrait&lt;/span&gt;&lt;span&gt;(Trait&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt; type&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; Impl&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt; type&lt;/span&gt;&lt;span&gt;) Trait {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;    comptime&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #9399B2;font-style: italic;&quot;&gt;        // try to find the trait declared explicitly as a member&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;        for&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span style=&quot;color: #F38BA8;font-style: italic;&quot;&gt;@typeInfo&lt;/span&gt;&lt;span&gt;(Impl)&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;.&lt;/span&gt;&lt;span&gt;@&amp;quot;struct&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;.&lt;/span&gt;&lt;span&gt;decl_names) &lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;|&lt;/span&gt;&lt;span&gt;decl_name&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;|&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;            if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span style=&quot;color: #F38BA8;font-style: italic;&quot;&gt;@TypeOf&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: #F38BA8;font-style: italic;&quot;&gt;@field&lt;/span&gt;&lt;span&gt;(Impl&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; decl_name)) &lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;==&lt;/span&gt;&lt;span&gt; Trait) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;                return&lt;/span&gt;&lt;span style=&quot;color: #F38BA8;font-style: italic;&quot;&gt; @field&lt;/span&gt;&lt;span&gt;(Impl&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; decl_name)&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #9399B2;font-style: italic;&quot;&gt;        // otherwise throw an error&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F38BA8;font-style: italic;&quot;&gt;        @compileError&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt;&amp;quot;trait &amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; ++&lt;/span&gt;&lt;span style=&quot;color: #F38BA8;font-style: italic;&quot;&gt; @typeName&lt;/span&gt;&lt;span&gt;(Trait) &lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;++&lt;/span&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt; &amp;quot; not found on &amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; ++&lt;/span&gt;&lt;span style=&quot;color: #F38BA8;font-style: italic;&quot;&gt; @typeName&lt;/span&gt;&lt;span&gt;(Impl))&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is basically equivalent to saying &quot;eh, it&#39;s duck typed. figure it out&quot;.
Just because we &lt;em&gt;are&lt;/em&gt; explicit, doesn&#39;t mean that we &lt;em&gt;can&#39;t&lt;/em&gt; be lazy. If we want
to take this full circle back to duck typing, we can even define trait functors
that rely on &lt;code&gt;getTrait&lt;/code&gt; to extract traits from the types they pass.&lt;/p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #CDD6F4; background-color: #1E1E2E;&quot; &gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;fn&lt;/span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt; duckMobius&lt;/span&gt;&lt;span&gt;(T&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt; type&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;fn&lt;/span&gt;&lt;span&gt;(T&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; T&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; T&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; T) T {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;    comptime&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;        const&lt;/span&gt;&lt;span&gt; num&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt; getTrait&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: #F9E2AF;font-style: italic;&quot;&gt;Num&lt;/span&gt;&lt;span&gt;(T)&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; T)&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;        return&lt;/span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt; makeMobius&lt;/span&gt;&lt;span&gt;(T&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; num)&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&quot;trait-functors&quot;&gt;Trait Functors&lt;/h2&gt;
&lt;p&gt;With some helpers defined, let&#39;s return to the &lt;code&gt;Num&lt;/code&gt; example.&lt;/p&gt;
&lt;p&gt;Traits in Zig resemble traits in Rust, typeclasses in Haskell, or modules in
Ocaml. In Rust or Haskell, they would be resolved from a global registry managed
by the compiler. This can feel very convenient, but it violates Zig&#39;s principle
of explicit control flow. Rust and Haskell can require a fair bit of hunting for
where a trait is defined, especially when something&#39;s wrong and the LSP isn&#39;t
resolving it properly. It can also be a contributor to long compile times.
Resolving a generic trait in these languages is often equivalent to evaluating a
proof, and that can take time.&lt;/p&gt;
&lt;p&gt;Ocaml modules, however, work quite a bit like Zig traits: modules are
first-class objects, and they are passed as arguments to the functions that
consume them. There is no inference of what modules apply to a type - you locate
them and pass them explicitly. If we were to define &lt;code&gt;Num&lt;/code&gt; as a module, it might
look something like the following.&lt;/p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #CDD6F4; background-color: #1E1E2E;&quot; &gt;&lt;code data-lang=&quot;ocaml&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #94E2D5;font-style: italic;&quot;&gt;(* signature *)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F38BA8;&quot;&gt;module&lt;/span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt; type&lt;/span&gt;&lt;span style=&quot;color: #FAB387;font-style: italic;&quot;&gt; NUM&lt;/span&gt;&lt;span style=&quot;color: #F9E2AF;font-style: italic;&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; sig&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;  type&lt;/span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt; t&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F9E2AF;font-style: italic;&quot;&gt;  val&lt;/span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt; add&lt;/span&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt; :&lt;/span&gt;&lt;span&gt; t&lt;/span&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span&gt; t&lt;/span&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span&gt; t&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F9E2AF;font-style: italic;&quot;&gt;  val&lt;/span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt; sub&lt;/span&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt; :&lt;/span&gt;&lt;span&gt; t&lt;/span&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span&gt; t&lt;/span&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span&gt; t&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F9E2AF;font-style: italic;&quot;&gt;  val&lt;/span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt; mul&lt;/span&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt; :&lt;/span&gt;&lt;span&gt; t&lt;/span&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span&gt; t&lt;/span&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span&gt; t&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F9E2AF;font-style: italic;&quot;&gt;  val&lt;/span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt; div&lt;/span&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt; :&lt;/span&gt;&lt;span&gt; t&lt;/span&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span&gt; t&lt;/span&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span&gt; t&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;end&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #94E2D5;font-style: italic;&quot;&gt;(* Implementation on float *)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F38BA8;&quot;&gt;module&lt;/span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt; Float&lt;/span&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt; :&lt;/span&gt;&lt;span style=&quot;color: #FAB387;font-style: italic;&quot;&gt; NUM&lt;/span&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt; with&lt;/span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt; type&lt;/span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt; t&lt;/span&gt;&lt;span style=&quot;color: #F9E2AF;font-style: italic;&quot;&gt; =&lt;/span&gt;&lt;span&gt; float&lt;/span&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt; =&lt;/span&gt;&lt;span&gt; struct&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;  type&lt;/span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt; t&lt;/span&gt;&lt;span style=&quot;color: #F9E2AF;font-style: italic;&quot;&gt; =&lt;/span&gt;&lt;span&gt; float&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;  let&lt;/span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt; add&lt;/span&gt;&lt;span style=&quot;color: #F9E2AF;font-style: italic;&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt; +.&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; )&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;  let&lt;/span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt; sub&lt;/span&gt;&lt;span style=&quot;color: #F9E2AF;font-style: italic;&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt; -.&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; )&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;  let&lt;/span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt; mul&lt;/span&gt;&lt;span style=&quot;color: #F9E2AF;font-style: italic;&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt; *.&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; )&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;  let&lt;/span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt; div&lt;/span&gt;&lt;span style=&quot;color: #F9E2AF;font-style: italic;&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt; /.&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; )&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;end&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #94E2D5;font-style: italic;&quot;&gt;(* function *)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;let&lt;/span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt; mobius&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;type&lt;/span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt; a&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;) (&lt;/span&gt;&lt;span style=&quot;color: #F38BA8;&quot;&gt;module&lt;/span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt; N&lt;/span&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt; :&lt;/span&gt;&lt;span style=&quot;color: #FAB387;font-style: italic;&quot;&gt; NUM&lt;/span&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt; with&lt;/span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt; type&lt;/span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt; t&lt;/span&gt;&lt;span style=&quot;color: #F9E2AF;font-style: italic;&quot;&gt; =&lt;/span&gt;&lt;span&gt; a&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #EBA0AC;font-style: italic;&quot;&gt; x a b c d&lt;/span&gt;&lt;span style=&quot;color: #F9E2AF;font-style: italic;&quot;&gt; =&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;  let&lt;/span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt; numerator&lt;/span&gt;&lt;span style=&quot;color: #F9E2AF;font-style: italic;&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color: #FAB387;font-style: italic;&quot;&gt; N&lt;/span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;.&lt;/span&gt;&lt;span&gt;add&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color: #FAB387;font-style: italic;&quot;&gt;N&lt;/span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;.&lt;/span&gt;&lt;span&gt;mul a x&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;)&lt;/span&gt;&lt;span&gt; b&lt;/span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt; in&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;  let&lt;/span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt; denominator&lt;/span&gt;&lt;span style=&quot;color: #F9E2AF;font-style: italic;&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color: #FAB387;font-style: italic;&quot;&gt; N&lt;/span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;.&lt;/span&gt;&lt;span&gt;add&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color: #FAB387;font-style: italic;&quot;&gt;N&lt;/span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;.&lt;/span&gt;&lt;span&gt;mul c x&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;)&lt;/span&gt;&lt;span&gt; d&lt;/span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt; in&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FAB387;font-style: italic;&quot;&gt;  N&lt;/span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;.&lt;/span&gt;&lt;span&gt;div numerator denominator&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #94E2D5;font-style: italic;&quot;&gt;(* Usage *)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;let&lt;/span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt; res&lt;/span&gt;&lt;span style=&quot;color: #F9E2AF;font-style: italic;&quot;&gt; =&lt;/span&gt;&lt;span&gt; mobius&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; (&lt;/span&gt;&lt;span&gt;module &lt;/span&gt;&lt;span style=&quot;color: #F9E2AF;&quot;&gt;Float&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;)&lt;/span&gt;&lt;span&gt; x a b c d)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Because modules in Ocaml are first-class values, they can actually take it a
step further. Rather than defining &lt;code&gt;mobius&lt;/code&gt; as written above, it is common in
Ocaml to make use of &quot;module functors&quot;, which are simply functions that take
modules as arguments and return new modules. If we wanted to define &lt;code&gt;mobius&lt;/code&gt; in
terms of a given numeric type, we might instead write it:&lt;/p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #CDD6F4; background-color: #1E1E2E;&quot; &gt;&lt;code data-lang=&quot;ocaml&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #94E2D5;font-style: italic;&quot;&gt;(* MakeMobius receives a NUM module and returns a new module with mobius function *)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F38BA8;&quot;&gt;module&lt;/span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt; MakeMobius&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color: #EBA0AC;font-style: italic;&quot;&gt;N&lt;/span&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt; :&lt;/span&gt;&lt;span style=&quot;color: #FAB387;font-style: italic;&quot;&gt; NUM&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #F9E2AF;font-style: italic;&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; struct&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;  let&lt;/span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt; mobius&lt;/span&gt;&lt;span style=&quot;color: #EBA0AC;font-style: italic;&quot;&gt; x a b c d&lt;/span&gt;&lt;span style=&quot;color: #F9E2AF;font-style: italic;&quot;&gt; =&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;    let&lt;/span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt; numerator&lt;/span&gt;&lt;span style=&quot;color: #F9E2AF;font-style: italic;&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color: #FAB387;font-style: italic;&quot;&gt; N&lt;/span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;.&lt;/span&gt;&lt;span&gt;add&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color: #FAB387;font-style: italic;&quot;&gt;N&lt;/span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;.&lt;/span&gt;&lt;span&gt;mul a x&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;)&lt;/span&gt;&lt;span&gt; b&lt;/span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt; in&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;    let&lt;/span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt; denominator&lt;/span&gt;&lt;span style=&quot;color: #F9E2AF;font-style: italic;&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color: #FAB387;font-style: italic;&quot;&gt; N&lt;/span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;.&lt;/span&gt;&lt;span&gt;add&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color: #FAB387;font-style: italic;&quot;&gt;N&lt;/span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;.&lt;/span&gt;&lt;span&gt;mul c x&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;)&lt;/span&gt;&lt;span&gt; d&lt;/span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt; in&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FAB387;font-style: italic;&quot;&gt;    N&lt;/span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;.&lt;/span&gt;&lt;span&gt;div numerator denominator&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;end&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #94E2D5;font-style: italic;&quot;&gt;(* usage *)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F38BA8;&quot;&gt;module&lt;/span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt; FloatMobius&lt;/span&gt;&lt;span style=&quot;color: #F9E2AF;font-style: italic;&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color: #FAB387;font-style: italic;&quot;&gt; MakeMobius&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color: #FAB387;font-style: italic;&quot;&gt;Float&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;let&lt;/span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt; res&lt;/span&gt;&lt;span style=&quot;color: #F9E2AF;font-style: italic;&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color: #FAB387;font-style: italic;&quot;&gt; FloatMobius&lt;/span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;.&lt;/span&gt;&lt;span&gt;mobius x a b c d&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is effectively currying: we are applying the module arguments now, and the
value arguments later. However it derives a mobius function that doesn&#39;t need to
be taking a bunch of type arguments all the time, and that module can in turn be
used in later constructions. This translates straightforwardly to Zig. If we
wanted to adhere strictly to the traits pattern, it might look like the
following.&lt;/p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #CDD6F4; background-color: #1E1E2E;&quot; &gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;fn&lt;/span&gt;&lt;span style=&quot;color: #F9E2AF;font-style: italic;&quot;&gt; Mobius&lt;/span&gt;&lt;span&gt;(T&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt; type&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;type&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;    return struct&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        mobius&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt; fn&lt;/span&gt;&lt;span&gt;(T&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; T&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; T&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; T&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; T) T&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;fn&lt;/span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt; makeMobius&lt;/span&gt;&lt;span&gt;(T&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt; type&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; num&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: #F9E2AF;font-style: italic;&quot;&gt; Num&lt;/span&gt;&lt;span&gt;(T)) &lt;/span&gt;&lt;span style=&quot;color: #F9E2AF;font-style: italic;&quot;&gt;Mobius&lt;/span&gt;&lt;span&gt;(T) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;    return&lt;/span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt; impl&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: #F9E2AF;font-style: italic;&quot;&gt;Mobius&lt;/span&gt;&lt;span&gt;(T)&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt; struct&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;        fn&lt;/span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt; mobius&lt;/span&gt;&lt;span&gt;(x&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span&gt; T&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; a&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span&gt; T&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; b&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span&gt; T&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; c&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span&gt; T&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; d&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span&gt; T) T {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;            const&lt;/span&gt;&lt;span&gt; numerator&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; =&lt;/span&gt;&lt;span&gt; num&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt;add&lt;/span&gt;&lt;span&gt;(num&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt;mul&lt;/span&gt;&lt;span&gt;(a&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; x)&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; b)&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;            const&lt;/span&gt;&lt;span&gt; denominator&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; =&lt;/span&gt;&lt;span&gt; num&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt;add&lt;/span&gt;&lt;span&gt;(num&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt;mul&lt;/span&gt;&lt;span&gt;(c&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; x)&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; d)&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;            return&lt;/span&gt;&lt;span&gt; num&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt;div&lt;/span&gt;&lt;span&gt;(numerator&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; denominator)&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    })&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;const&lt;/span&gt;&lt;span&gt; complex_mobius&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color: #F9E2AF;font-style: italic;&quot;&gt; MakeMobius&lt;/span&gt;&lt;span&gt;(Complex&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; Complex&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;.&lt;/span&gt;&lt;span&gt;num)&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;complex_mobius&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt;mobius&lt;/span&gt;&lt;span&gt;(x&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; a&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; b&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; c&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; d)&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This works fine, but I think it&#39;s even simpler to move the functor into
&lt;code&gt;Mobius(T)&lt;/code&gt;:&lt;/p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #CDD6F4; background-color: #1E1E2E;&quot; &gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;fn&lt;/span&gt;&lt;span style=&quot;color: #F9E2AF;font-style: italic;&quot;&gt; Mobius&lt;/span&gt;&lt;span&gt;(T&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt; type&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;type&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;    return struct&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        mobius&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt; fn&lt;/span&gt;&lt;span&gt;(T&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; T&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; T&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; T&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; T) T&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;        fn&lt;/span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt; make&lt;/span&gt;&lt;span&gt;(num&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: #F9E2AF;font-style: italic;&quot;&gt; Num&lt;/span&gt;&lt;span&gt;(T)) &lt;/span&gt;&lt;span style=&quot;color: #F9E2AF;font-style: italic;&quot;&gt;Mobius&lt;/span&gt;&lt;span&gt;(T) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;            return&lt;/span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt; impl&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: #F9E2AF;font-style: italic;&quot;&gt;Mobius&lt;/span&gt;&lt;span&gt;(T)&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt; struct&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;                fn&lt;/span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt; mobius&lt;/span&gt;&lt;span&gt;(x&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span&gt; T&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; a&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span&gt; T&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; b&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span&gt; T&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; c&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span&gt; T&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; d&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span&gt; T) T {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;                    const&lt;/span&gt;&lt;span&gt; numerator&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; =&lt;/span&gt;&lt;span&gt; num&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt;add&lt;/span&gt;&lt;span&gt;(num&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt;mul&lt;/span&gt;&lt;span&gt;(a&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; x)&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; b)&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;                    const&lt;/span&gt;&lt;span&gt; denominator&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; =&lt;/span&gt;&lt;span&gt; num&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt;add&lt;/span&gt;&lt;span&gt;(num&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt;mul&lt;/span&gt;&lt;span&gt;(c&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; x)&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; d)&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;                    return&lt;/span&gt;&lt;span&gt; num&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt;div&lt;/span&gt;&lt;span&gt;(numerator&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; denominator)&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            })&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;const&lt;/span&gt;&lt;span&gt; complex_mobius&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color: #F9E2AF;font-style: italic;&quot;&gt; Mobius&lt;/span&gt;&lt;span&gt;(Complex)&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt;make&lt;/span&gt;&lt;span&gt;(Complex&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;.&lt;/span&gt;&lt;span&gt;num)&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;complex_mobius&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt;mobius&lt;/span&gt;&lt;span&gt;(x&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; a&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; b&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; c&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; d)&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;However for single functions like this, unless I knew it would need to be
consumed by another function as a trait, I would probably be tempted to just
implement it as a type-curried function rather than a full-blown trait:&lt;/p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #CDD6F4; background-color: #1E1E2E;&quot; &gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;fn&lt;/span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt; makeMobius&lt;/span&gt;&lt;span&gt;(T&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt; type&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; num&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: #F9E2AF;font-style: italic;&quot;&gt; Num&lt;/span&gt;&lt;span&gt;(T)) &lt;/span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;fn&lt;/span&gt;&lt;span&gt;(T&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; T&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; T&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; T) T {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;    return struct&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;        fn&lt;/span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt; mobius&lt;/span&gt;&lt;span&gt;(x&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span&gt; T&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; a&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span&gt; T&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; b&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span&gt; T&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; c&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span&gt; T&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; d&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span&gt; T) T {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;            const&lt;/span&gt;&lt;span&gt; numerator&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; =&lt;/span&gt;&lt;span&gt; num&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt;add&lt;/span&gt;&lt;span&gt;(num&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt;mul&lt;/span&gt;&lt;span&gt;(a&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; x)&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; b)&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;            const&lt;/span&gt;&lt;span&gt; denominator&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; =&lt;/span&gt;&lt;span&gt; num&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt;add&lt;/span&gt;&lt;span&gt;(num&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt;mul&lt;/span&gt;&lt;span&gt;(c&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; x)&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; d)&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;            return&lt;/span&gt;&lt;span&gt; num&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt;div&lt;/span&gt;&lt;span&gt;(numerator&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; denominator)&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;.&lt;/span&gt;&lt;span&gt;mobius&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;const&lt;/span&gt;&lt;span&gt; complexMobius&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt; makeMobius&lt;/span&gt;&lt;span&gt;(Complex&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; Complex&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;.&lt;/span&gt;&lt;span&gt;num)&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt;complexMobius&lt;/span&gt;&lt;span&gt;(x&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; a&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; b&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; c&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; d)&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The versatility of Zig&#39;s comptime makes all of these more or less equivalent to
the compiler. It&#39;s just a stylistic choice, depending on what the situation
calls for.&lt;/p&gt;
&lt;p&gt;Also, notice that technically we have already used trait functors when we
defined &lt;code&gt;builtinNum&lt;/code&gt;. It&#39;s not a deep, technical concept. It&#39;s just a function
that constructs a trait implementation for you.&lt;/p&gt;
&lt;h2 id=&quot;useful-traits&quot;&gt;Useful Traits&lt;/h2&gt;
&lt;p&gt;Having thoroughly introduced traits, let&#39;s talk about what we can do with them.&lt;/p&gt;
&lt;p&gt;In this section are a few traits that I find myself reaching for with enough
regularity that I keep a file around containing them.  All of these are fairly
humdrum (but wildly applicable) abstractions that I lifted wholecloth from
other languages.&lt;/p&gt;
&lt;h3 id=&quot;into-from&quot;&gt;Into / From&lt;/h3&gt;
&lt;p&gt;I need to convert one type into another all the freaking time.  Often there are
multiple ways to do this, depending on how you want to interpret the upstream
type.  I use &lt;code&gt;Into&lt;/code&gt; and &lt;code&gt;From&lt;/code&gt; to canonicalize methods for converting one type
into another.&lt;/p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #CDD6F4; background-color: #1E1E2E;&quot; &gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #9399B2;font-style: italic;&quot;&gt;/// T can be converted into Out&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;fn&lt;/span&gt;&lt;span style=&quot;color: #F9E2AF;font-style: italic;&quot;&gt; Into&lt;/span&gt;&lt;span&gt;(T&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt; type&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; Out&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt; type&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;type&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;    return struct&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        into&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt; fn&lt;/span&gt;&lt;span&gt;(T) Out&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #9399B2;font-style: italic;&quot;&gt;/// T can be derived from In&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;fn&lt;/span&gt;&lt;span style=&quot;color: #F9E2AF;font-style: italic;&quot;&gt; From&lt;/span&gt;&lt;span&gt;(T&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt; type&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; In&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt; type&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;type&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;    return struct&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        from&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt; fn&lt;/span&gt;&lt;span&gt;(In) T&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&quot;index&quot;&gt;Index&lt;/h3&gt;
&lt;p&gt;Sometimes, rather than iterating, we need keyed access to a value.  The
container could be a slice or a hash table - we don&#39;t care.  For this, I use
&lt;code&gt;Index&lt;/code&gt;.&lt;/p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #CDD6F4; background-color: #1E1E2E;&quot; &gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #9399B2;font-style: italic;&quot;&gt;/// T forms an index over Key and Value&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;fn&lt;/span&gt;&lt;span style=&quot;color: #F9E2AF;font-style: italic;&quot;&gt; Index&lt;/span&gt;&lt;span&gt;(T&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt; type&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; Key&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt; type&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; Value&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt; type&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;type&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;    return struct&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        get&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt; fn&lt;/span&gt;&lt;span&gt;(T&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; Key) &lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;?&lt;/span&gt;&lt;span&gt;Value&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&quot;iterator-iterable&quot;&gt;Iterator / Iterable&lt;/h3&gt;
&lt;p&gt;Another common case: we have a function that iterates over a type, but we don&#39;t
care what sort of iterable data structure we&#39;re going to be working with.  We
usually need two traits: one for the &lt;code&gt;Iterable&lt;/code&gt; collection, and another for the
&lt;code&gt;Iterator&lt;/code&gt;, which keeps track of our progress through the collection.&lt;/p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #CDD6F4; background-color: #1E1E2E;&quot; &gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #9399B2;font-style: italic;&quot;&gt;/// T can be used to iterate over Elem elements of type&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;fn&lt;/span&gt;&lt;span style=&quot;color: #F9E2AF;font-style: italic;&quot;&gt; Iterator&lt;/span&gt;&lt;span&gt;(T&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt; type&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; Elem&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt; type&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;type&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;    return struct&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        next&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt; fn&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;*&lt;/span&gt;&lt;span&gt;T) &lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;?&lt;/span&gt;&lt;span&gt;Elem&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #9399B2;font-style: italic;&quot;&gt;/// T can return an Iter iterator over Elem elements&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;fn&lt;/span&gt;&lt;span style=&quot;color: #F9E2AF;font-style: italic;&quot;&gt; Iterable&lt;/span&gt;&lt;span&gt;(T&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span&gt; Type&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; Elem&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt; type&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; Iter&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt; type&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;type&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;    return struct&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        iter&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt; fn&lt;/span&gt;&lt;span&gt;(T) IterPair&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;        pub const&lt;/span&gt;&lt;span&gt; IterPair&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt; struct&lt;/span&gt;&lt;span&gt; {impl&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span&gt; Iter&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; trait&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: #F9E2AF;font-style: italic;&quot;&gt; Iterator&lt;/span&gt;&lt;span&gt;(Iter&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;/span&gt;&lt;span&gt; Elem)}&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&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 this is a little awkward, because we don&#39;t usually care what
the iterator implementation is.  It&#39;s probably just a usize index over an array
or something.  It would be nice if we could just define &lt;code&gt;Iterable(T: type, Elem: type)&lt;/code&gt;.  I&#39;ve chosen to just let it be awkward.  It&#39;s usually not a big
deal.&lt;/p&gt;
&lt;h2 id=&quot;words-of-warning&quot;&gt;Words of Warning&lt;/h2&gt;
&lt;p&gt;I really don&#39;t want you to walk away from this article thinking &quot;I need to
convert all my code to use traits&quot;.  Traits should not be thought of as a
totalizing pattern.  The last thing I want is for Zig code to start looking
like Rust or Haskell.&lt;/p&gt;
&lt;p&gt;Traits are a sometimes treat.  They are useful for functions that need
abstractions inside of hot loops, where you know that you want monomorphization
and static dispatch.  They can become legible building blocks for some neat
metaprogramming tricks.  However most of the time I only reach for them in a
pull-based manner: I have a function where it would be useful to consume a
trait, because it&#39;s undecided on some implementation detail.&lt;/p&gt;
&lt;p&gt;Used improperly, traits can explode the size of your binary and actually make
it slower.  Each function parameterized on comptime parameters gets its own
templated assembly, and if you nest these a few layers deep, it&#39;s easy to end
up with a combinatorial explosion.  This can thrash your CPU cache, and
depending on the situation, easily be outperformed by dynamic dispatch and
vtables.&lt;/p&gt;
&lt;h2 id=&quot;words-of-encouragement&quot;&gt;Words of Encouragement&lt;/h2&gt;
&lt;p&gt;Traits are ultimately handy and very powerful.  I wish I saw more codebases
that made use of them, especially for abstraction inside of hot loops. I like
that they are a design pattern more than a language feature, and this gives you
a lot of explicit control over when and how you use them.  I was looking for a
solution like this for a long time, and I&#39;m glad I found it.&lt;/p&gt;
&lt;p&gt;I&#39;m sure that other Zig users have stumbled onto this trick, but I have yet to
see it in the wild.  I think that part of the reason is that it doesn&#39;t really
lend itself to a library.  It&#39;s more of a convention that you can choose to
use or ignore.&lt;/p&gt;
&lt;p&gt;My hope is that for someone reading, traits are the right tool for the job.&lt;/p&gt;
&lt;section class=&quot;footnotes&quot;&gt;
&lt;ol class=&quot;footnotes-list&quot;&gt;
&lt;li id=&quot;fn-seguin2023&quot;&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https://www.openmymind.net/Zig-Interfaces/&quot;&gt;Zig Interfaces&lt;/a&gt; by Karl Seguin &lt;a href=&quot;https://www.axelmagn.com/blog/202610-zig-traits/#fr-seguin2023-1&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn-figuratively&quot;&gt;
&lt;p&gt;figuratively &lt;a href=&quot;https://www.axelmagn.com/blog/202610-zig-traits/#fr-figuratively-1&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn-wong2025&quot;&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https://williamw520.github.io/2025/07/13/zig-interface-revisited.html&quot;&gt;Zig Interface Revisited&lt;/a&gt;
by William Wong &lt;a href=&quot;https://www.axelmagn.com/blog/202610-zig-traits/#fr-wong2025-1&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn-mckay2025&quot;&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https://joegm.github.io/blog/inside-zigs-new-writer-interface/&quot;&gt;Inside Zig&#39;s new Writer&lt;/a&gt;
by Joe McKay &lt;a href=&quot;https://www.axelmagn.com/blog/202610-zig-traits/#fr-mckay2025-1&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn-cypert2026&quot;&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https://www.bradcypert.com/interfaces-in-zig/&quot;&gt;Interfaces in Zig&lt;/a&gt; by Brad
Cypert &lt;a href=&quot;https://www.axelmagn.com/blog/202610-zig-traits/#fr-cypert2026-1&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn-kelley2021&quot;&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https://vimeo.com/649009599&quot;&gt;A Practical Guide to Applying Data-Oriented Design&lt;/a&gt;
by Andrew Kelley &lt;a href=&quot;https://www.axelmagn.com/blog/202610-zig-traits/#fr-kelley2021-1&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn-redig2025&quot;&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https://www.scottredig.com/blog/bonkers_comptime/&quot;&gt;Zig Comptime is Bonkers Good&lt;/a&gt;
by Scott Redit &lt;a href=&quot;https://www.axelmagn.com/blog/202610-zig-traits/#fr-redig2025-1&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn-ocaml-inspired&quot;&gt;
&lt;p&gt;&quot;Traits&quot; are directly inspired from OCaml modules, but the
term &quot;module&quot; already refers to something else in Zig. &lt;a href=&quot;https://www.axelmagn.com/blog/202610-zig-traits/#fr-ocaml-inspired-1&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn-so-good&quot;&gt;
&lt;p&gt;&lt;img src=&quot;https://www.axelmagn.com/blog/202610-zig-traits/so_good.png&quot; alt=&quot;Feels Good&quot; /&gt; &lt;a href=&quot;https://www.axelmagn.com/blog/202610-zig-traits/#fr-so-good-1&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn-num-is-simplified&quot;&gt;
&lt;p&gt;This is a pretty simplistic definition of a numeric
trait. In practice, you would probably want to look into
&lt;a rel=&quot;external&quot; href=&quot;https://doc.rust-lang.org/std/ops/index.html&quot;&gt;std::ops&lt;/a&gt; from Rust or
&lt;a rel=&quot;external&quot; href=&quot;https://hackage.haskell.org/package/base-4.17.0.0/docs/GHC-Num.html#t:Num&quot;&gt;Num&lt;/a&gt;
from Haskell. &lt;a href=&quot;https://www.axelmagn.com/blog/202610-zig-traits/#fr-num-is-simplified-1&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Creative Mesocycles</title>
        <published>2024-12-22T00:00:00+00:00</published>
        <updated>2024-12-22T00:00:00+00:00</updated>
        
        <author>
          <name>
            Axel Magnuson
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.axelmagn.com/blog/202412-mesocycles/"/>
        <id>https://www.axelmagn.com/blog/202412-mesocycles/</id>
        
        <content type="html" xml:base="https://www.axelmagn.com/blog/202412-mesocycles/">&lt;figure class=&quot;img-figure&quot;&gt;&lt;img src=&quot;/blog/202412-mesocycles/mesocycles2.png&quot; alt=&quot;Sports Periodization Overview&quot; decoding=&quot;async&quot; loading=&quot;lazy&quot; /&gt;&lt;figcaption&gt;Sports Periodization Overview&lt;/figcaption&gt;&lt;/figure&gt;
&lt;p&gt;In 2024 I made two intentional changes to my habits: I started exercising every
day, and I stopped working on creative projects that take more than a month.
Both of these changes have improved my life immensely. In the process, I have
also discovered that my one-month blocks of creative work rhyme in an uncanny
way with a concept from sports periodization called the Mesocycle.&lt;/p&gt;
&lt;p&gt;Sports periodization is a technique of breaking up an athlete’s training into a
hierarchy of time blocks known as macrocycles, mesocycles, and microcycles.
Macrocycles are a year and microcycles are about a week. Mesocycles, like my
projects, take about a month, and focus on one particular aspect of training. As
I progressed throughout the year, I drew more from this paradigm, and I think I
have arrived at a parallel approach to my creative work that I’m truly excited
to share.&lt;/p&gt;
&lt;h2 id=&quot;a-foundation-of-daily-habit-and-enjoyment&quot;&gt;A Foundation of Daily Habit and Enjoyment&lt;/h2&gt;
&lt;p&gt;This 1-month regimen worked out more splendidly than I could have hoped. It
forced me into a dialogue with myself about what would be &lt;em&gt;fun&lt;/em&gt; to work on for a
month, and what my life &lt;em&gt;needed&lt;/em&gt;. The work shifted from servicing an idea or a
vision, and allowed me to choose the work that would be the most nourishing
thing for me. If I was burnt out on games, I could make a small AI tool, or
build a piece of furniture. There was no pressure - one month was barely enough
time for me to accomplish anything at all.&lt;/p&gt;
&lt;p&gt;Nonetheless, I think it was the most creatively productive year I&#39;ve ever had. I
made two games for game jams, I built an assistive AI tool that helps me with
D&amp;amp;D worldbuilding, I ran a one-off D&amp;amp;D adventure, I helped organize a wedding
(my own), I hosted my first game jam, and launched this blog. All of this
emerged organically as I bounced from passion to passion.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;If macrocycles are built on mesocycles, and mesocycles are built on
microcycles, then microcycles are built on daily habit and enjoyment.&lt;/strong&gt; At the
end of the day, the only reason to do unnecessary work in your free time is
because those hours spent add to your life. If the art you do is draining you or
destroying you, then for fuck&#39;s sake, please do anything else.&lt;/p&gt;
&lt;p&gt;I think that the most important thing that working in mesocycles did for me was
allow me to reconnect with that enjoyment I feel when I make something. If you
are interested in adopting this methodology, I would urge you to stay in close
touch with your own enjoyment and sense of play.&lt;/p&gt;
&lt;h2 id=&quot;sports-periodization&quot;&gt;Sports Periodization&lt;/h2&gt;
&lt;p&gt;When accomplished athletes complete, they often plan in terms of yearly training
cycles leading up to the major yearly competition. This yearly cycle is broken
down into smaller periods of focused training through the process of sports
periodization.&lt;/p&gt;
&lt;p&gt;In this discipline, the yearly cycle of training for an event is known as a
macrocycle. This is broken down into mesocycles of 3-6 weeks, which focus on a
particular aspect of training such as strength or endurance. A mesocycle
consists of microcycles (typically about a week) that are a specific training
routine. If you&#39;ve ever done a weekly weight lifting routine, that routine is
your microcycle.&lt;/p&gt;
&lt;p&gt;While there are some valid criticisms of traditional sports periodization being
&lt;a rel=&quot;external&quot; href=&quot;https://en.wikipedia.org/wiki/Sports_periodization#Opposition_to_periodization&quot;&gt;overly reductive&lt;/a&gt;,
it also has a long track record as a viable training methodology because it
provides a straightforward structure for athletes to work within. The
intermediate breakdown into mesocycles allows them to focus on their long-term
goals without becoming overwhelmed by the complexity.&lt;/p&gt;
&lt;p&gt;The process boils down to:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Prioritize the things you need to work on in a year (macrocycle)&lt;/li&gt;
&lt;li&gt;Work on them in 3-6 week blocks (mesocycle)&lt;/li&gt;
&lt;li&gt;Within that block, repeat a weekly routine that improves your focus area
(microcycle)&lt;/li&gt;
&lt;li&gt;Use that time in your weekly routine wisely though: you only have about a
month to make the progress you need.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;creative-periodization&quot;&gt;Creative Periodization&lt;/h2&gt;
&lt;p&gt;When I committed to only doing 1-month creative projects this year, it was in
some ways a declaration of bankruptcy. The truth is that I commit to projects at
a far more rapid pace than I complete them, leading to a complete oversaturation
of my time. I was burnt out, depressed, and buried in over-ambitious game
development and woodworking ideas that I had long ago lost any passion for.&lt;/p&gt;
&lt;p&gt;Despite the circumstances, making things was still meaningful to me. Some days I
was so depressed that even watching TV sounded overwhelming, but somehow I would
still want to noodle on some code. This wasn&#39;t sustainable. Those projects were
still burning me out, even as I noodled on them. I would sink into my work on
them, neglecting other more important parts of my life even as I failed to make
meaningful progress. I started writing a small programming language, but stopped
seeing the dentist. I tried to make a multiplayer platforming game, but couldn’t
bring myself to clean my desk. Both of those projects stalled out on technical
difficulties. I found others, but each time I was more and more exhausted.&lt;/p&gt;
&lt;p&gt;My compromise with myself was to set a time limit. I could keep making things,
but whether they succeeded or failed, after a month I would need to move on to
something else. I would try to choose things that I thought I could get done in
a month, but if I lost interest or the project petered out, no problem. Just
take it as a data point, pull the plug and move on.&lt;/p&gt;
&lt;h2 id=&quot;mesocycles-are-a-sweet-spot&quot;&gt;Mesocycles are a Sweet Spot&lt;/h2&gt;
&lt;p&gt;Sports and creative arts are both endeavors where motivated people invest a lot
of hard work to develop their capacities, but ultimately the only thing that
makes them worthwhile is love for the activity.&lt;/p&gt;
&lt;p&gt;After learning more about sports periodization, I came to view my little 1-month
projects as &lt;strong&gt;&lt;em&gt;Creative Mesocycles&lt;/em&gt;&lt;/strong&gt;. Given shape through a name, Creative
Mesocycles stepped into my world fully reified and concrete. It felt like a
major breakthrough.&lt;/p&gt;
&lt;p&gt;Through the sports lens, I could situate my 1-month sprints within the context
of a larger mesocycle such as improving my craft or making a larger project. I
could see how those mesocycles would need to change depending on the macrocycle.
On the other end of the scale, I could see how I had not been minding the
regularity of my microcycles - if I wanted to do work outside of my job, I
needed to stop sprinting so hard day after day. It led to fatigue and burnout
every time. I’d do a lot better if I had planned rest days where I did something
completely unrelated to my mesocycle like drawing or reading, or if I tried to
superset in something that was less fatiguing like design work and journaling.&lt;/p&gt;
&lt;p&gt;From the creative lens, I could also see how my mesocycles had benefited from
being dynamic and humanistic. If I were to plan out my mesocycles for the whole
macrocycle, it would become a backlog and crushing commitment. I think lots of
pro athletes plan their years like that, but as an amateur being creative for
its own sake and lifting weights for general health improvements, I don’t think
it makes a lot of sense in my case. I think for both exercise and creativity, I
benefit a lot from the reflection period at the end of each mesocycle where I
can honor the work I’ve done and check in to figure out what next step is
singing to my heart.&lt;/p&gt;
&lt;p&gt;Through the application of this framework, I think I have arrived at four
qualities that I find essential in my creative mesocycles:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Scope:&lt;/strong&gt; If I listen to the artist in my brain, he will want to craft a
magnum opus every time. He will have more ideas than I could ever test, much
less execute. However if I gently say &quot;yes, but you only have a month. What
could be done to point a finger at this vision?&quot; then I find this artist in
my head to be pleasantly amenable to a smaller project that captures only the
most compelling and essential parts.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Focus:&lt;/strong&gt; Once the cycle has started, it is easy to hold focus for the month
knowing that the time is so short. When I inevitably have ideas for a newer,
better project halfway through, I can tell myself &quot;that&#39;s great – do it next
month if you feel like it&quot;. When I inevitably suffer setbacks or become
disillusioned, I can tell myself &quot;just do your best. There&#39;s only a week or
two left.&quot;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Time-Boxing:&lt;/strong&gt; At the end of the month, what&#39;s done is done. Sometimes the
project is incomplete. Even when it is complete, I&#39;m usually over it by then,
and want desperately to move on to something else. I like the finality of the
self-imposed deadline: sometimes I learn that what I wanted to do couldn&#39;t be
accomplished in a reasonable timeframe.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Reflection:&lt;/strong&gt; There&#39;s always so much to learn at the end of each mesocycle.
I postmortem the project to myself, figuring out what went wrong and right.
I&#39;m always surprised and delighted by how different it is from what I
expected. Then the best part: figuring out what to work on next. I can never
predict at the beginning of a month what I will want to work on at the end,
so now, I don&#39;t even try.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;I also think that the 1-month timespan holds a special significance. It is about
the minimum time I need to finish a complex feature or simple game-jam game,
while also being the maximum time that I can remain inspired enough to work hard
on something creative. After about a month I usually notice myself losing the
spark of inspiration, and wanting to move on to something else. It’s also about
the maximum time I can make a detailed plan for. Therefore I suspect that the
1-month time box is close to some sort of optimal duration of work for my
psyche.&lt;/p&gt;
&lt;p&gt;Of course, I don&#39;t expect this to hold true for everybody across all creative
disciplines. I think that if you want to adopt this framework, you should tweak
it to fit what makes sense for you. Personally, I think I am going to experiment
with some 6-week mesocycles in 2025, so that I can tackle slightly larger
projects and maybe write some blog posts about them. It will be an evolving
process, but I look forward to documenting it and sharing my findings with all
of you.&lt;/p&gt;
&lt;h2 id=&quot;future-work&quot;&gt;Future Work&lt;/h2&gt;
&lt;p&gt;I think that in 2025 I want to work on a bigger game project. My brain is in a
much healthier place, and it&#39;s feeling like I can finally tackle something like
that. I am thinking of this as my new, more focused macrocycle, and it will be
interesting to adapt my current schema of mesocycles into it. I have been
journaling game concepts that contain a list of core features, and I think that
for most of the year I want to focus on just building prototypes of those
features. I want to use a mixture of the engines and tools I&#39;m familiar with,
and search for a prototype and workflow that I think is fun enough that I can be
inspired by what I already have rather than what I imagine it could be.&lt;/p&gt;
&lt;p&gt;I suspect that every now and then I will have to have a &quot;resting cycle&quot; where I
go off and work on something completely different just for the variety. Or maybe
I will start playing with the idea of &quot;rest days&quot;, and work in planned days of
distraction to my weekly schedule. I&#39;m not entirely sure yet - we&#39;ll have to
play around with it and stay on our toes. In general, I&#39;m fascinated by this
idea of treating my creative time like a workout regimen, and I&#39;m sure I&#39;ll have
more to share as things progress.&lt;/p&gt;
&lt;p&gt;I also want to write about my progress as I go, which is why I started this
blog. I hope to start a youtube channel in the coming months as well, and
publish devlogs as well as some companion videos for these essays. I hope you’ll
follow along, and if you try this, please let me know how it works for you!&lt;/p&gt;
</content>
        
    </entry>
</feed>
