🪢 Rope

Balanced binary tree of strings for efficient text editing

Overview

A rope is a binary tree where leaves hold short strings and internal nodes cache the total length of their left subtree. This gives O(log n) concatenation, insertion, and deletion instead of the O(n) copies required by flat strings. Ropes are the backbone of modern text editors like VS Code, Xi, and Lapce.

This implementation includes automatic balancing (Fibonacci-based rebalancing), line-aware indexing, and a full functional API.

Concepts Demonstrated

How It Works

(* Tree structure *)
type t =
  | Leaf of string            (* up to max_leaf chars *)
  | Node of { left; right;
              weight;         (* length of left subtree *)
              len; depth }

(* Build a rope from a string *)
let r = Rope.of_string "Hello, world!"

(* O(1) concatenation — just creates a new root node *)
let r2 = Rope.concat r (Rope.of_string " Goodbye!")

(* O(log n) character access *)
let ch = Rope.index r2 7      (* → 'w' *)

(* O(log n) insert at position *)
let r3 = Rope.insert r2 5 " beautiful"

(* O(log n) delete range *)
let r4 = Rope.delete r3 0 6   (* remove "Hello," *)

Key Functions

FunctionComplexityDescription
of_string sO(n)Build balanced rope from string
to_string rO(n)Flatten rope to string
concat a bO(1)Concatenate two ropes
length rO(1)Total character count
index r iO(log n)Character at position i
substring r i lenO(log n + len)Extract substring
insert r i sO(log n)Insert string at position
delete r i lenO(log n)Delete range
split r iO(log n)Split into two ropes at position
balance rO(n)Rebalance using Fibonacci thresholds
is_balanced rO(1)Check balance invariant
lines rO(n)Split into lines
iter f rO(n)Apply f to each character
fold f init rO(n)Left fold over characters
map f rO(n)Map function over characters

Why Not Just Use Strings?

OperationFlat StringRope
ConcatenationO(n + m) — full copyO(1) — new node
Insert at positionO(n) — shift + copyO(log n) — split + concat
Delete rangeO(n) — shift + copyO(log n) — split + concat
Character accessO(1) — direct indexO(log n) — tree walk
Memory on editFull copyShared structure

For documents longer than a few KB, ropes dramatically reduce the cost of editing operations. The O(log n) access trade-off is rarely noticeable since editors typically access characters sequentially.

When to Use