Generating All Subsets of a List Recursively
Functional Programming
Tutorial
The Problem
The power set of a set with n elements contains 2ⁿ subsets. Generating all subsets is fundamental to combinatorial algorithms: exhaustive search, constraint satisfaction, feature selection in machine learning, and generating test cases. The recursive insight is elegant — for each element, either include it or exclude it, then recurse on the rest. This divide-and-conquer structure maps directly onto functional recursion.
🎯 Learning Outcomes
Vec<Vec<T>> from recursive functions correctlyCode Example
#![allow(clippy::all)]
// placeholderKey Differences
x :: s is O(1); Rust must clone() each subset to add an element, making it O(k) per subset.| [] -> ... | x :: rest -> is the canonical idiom; Rust uses if let Some((first, rest)) = slice.split_first().'a list list; Rust returns Vec<Vec<T>> with explicit Clone bound on T.extend to combine result vectors; OCaml uses @ (list append) naturally.OCaml Approach
OCaml's idiomatic solution uses pattern matching and list comprehension style:
let rec subsets = function
| [] -> [[]]
| x :: rest ->
let without = subsets rest in
let with_x = List.map (fun s -> x :: s) without in
without @ with_x
OCaml lists are persistent and cheap to prepend, so x :: s costs O(1). The garbage collector manages all the shared list structure automatically.
Full Source
#![allow(clippy::all)]
// placeholderDeep Comparison
<!-- Comparison will be generated by Claude Code -->
Exercises
[1, 2, 3, 4] and verify there are exactly 16 (2⁴) subsets including the empty set.