ExamplesBy LevelBy TopicLearning Paths
149 Intermediate

Extension Traits

Functional Programming

Tutorial Video

Text description (accessibility)

This video demonstrates the "Extension Traits" functional Rust example. Difficulty level: Intermediate. Key concepts covered: Functional Programming. Rust's orphan rule prevents implementing an external trait on an external type — you cannot add `Display` to `Vec<T>` if both come from other crates. Key difference from OCaml: 1. **Method dispatch**: Rust's extension traits enable `iter.my_method()` dot

Tutorial

The Problem

Rust's orphan rule prevents implementing an external trait on an external type — you cannot add Display to Vec<T> if both come from other crates. Extension traits solve this by defining a new trait with the desired methods and implementing it for the external type — since the new trait is yours, the orphan rule permits it. This pattern is widely used in Rust libraries to add methods to standard types (IteratorExt, ReadExt, FutureExt).

🎯 Learning Outcomes

  • • Understand the orphan rule and why it exists (coherence guarantee)
  • • Learn the extension trait pattern: a new trait adding methods to an existing type
  • • See how use MyExt in scope brings the new methods into visibility
  • • Recognize extension traits in the Rust ecosystem: futures::StreamExt, itertools::Itertools
  • Code Example

    #![allow(clippy::all)]
    // Stub — awaiting conversion from OCaml source.

    Key Differences

  • Method dispatch: Rust's extension traits enable iter.my_method() dot-notation; OCaml's extensions are plain functions (ListExt.my_function lst).
  • Orphan rule: Rust's orphan rule requires the trait or the type to be local; OCaml modules have no such restriction — you can add functions to any type.
  • Visibility: Rust extension methods require importing the trait (use MyExt); OCaml module functions are always accessible via Module.f.
  • Ecosystem pattern: itertools, futures, tokio heavily use extension traits; OCaml's Base, Core add functions to List, String etc. via module inclusion.
  • OCaml Approach

    OCaml achieves method extension through modules. To add functions to a library type:

    module ListExt = struct
      include List  (* bring existing functions into scope *)
      let sum = List.fold_left (+) 0
      let chunk n lst = ...
    end
    

    There is no concept of method dispatch in OCaml's standard library (no obj.method() syntax), so extensions are just functions in a module that call the original library functions. Open dispatch with polymorphic variants provides more dynamic alternatives.

    Full Source

    #![allow(clippy::all)]
    // Stub — awaiting conversion from OCaml source.

    Deep Comparison

    OCaml vs Rust: Extension Traits

    Overview

    See the example.rs and example.ml files for detailed implementations.

    Key Differences

    AspectOCamlRust
    Type systemHindley-MilnerOwnership + traits
    MemoryGCZero-cost abstractions
    MutabilityExplicit refmut keyword
    Error handlingOption/ResultResult<T, E>

    See README.md for detailed comparison.

    Exercises

  • Write StringExt with methods truncate_at(n: usize) -> String and word_count() -> usize for &str.
  • Add tally<K: Hash + Eq>(self) -> HashMap<K, usize> to IteratorExt that counts occurrences of each item.
  • Create an extension trait for Option<T> that adds or_error(msg: &str) -> Result<T, String>.
  • Open Source Repos