One Good Throw Deserves a Function
The satisfying part of a yo-yo combination is the join. A straight throw settles into a sleeper; the spinning yo-yo lands on a string segment; the mount becomes the starting point for whatever comes next. Eventually, ideally, everything comes back to your hand.
Function composition gives code that same continuity. Each function accepts the previous function’s result. Small operations become a larger operation that you can name, reuse, and combine again.
For today’s experiment, I’m writing a tiny choreography printer. Its strings describe moves; they don’t model spin, tension, or whether my imaginary fingers have tied themselves together.
(define (compose f g)
(lambda (x) (f (g x))))
(define (step name)
(lambda (routine)
(string-append routine " -> " name)))
(define sleeper (step "sleeper"))
(define mount (step "trapeze"))
(define finish (step "return"))
(define combo
(compose finish (compose mount sleeper)))
(display (combo "throw"))
(newline)
Read that composition from the inside outward: sleeper first, then mount, then return. Scheme makes the machinery wonderfully visible: compose returns a function, and that function connects two others.
Java lets the same routine read in performance order. Save this as Main.java:
import java.util.function.Function;
public class Main {
static Function<String, String> step(String name) {
return routine -> routine + " -> " + name;
}
public static void main(String[] args) {
Function<String, String> combo = step("sleeper")
.andThen(step("trapeze"))
.andThen(step("return"));
System.out.println(combo.apply("throw"));
}
}
Both print:
throw -> sleeper -> trapeze -> return
Order matters. Swap the mount and return and you still have valid code, but a rather questionable routine. Matching input and output types makes functions connectable; it doesn’t guarantee that their meaning makes sense.
That’s also where the analogy earns its keep. A real combination needs suitable string tension and enough spin remaining at each join. Our printer checks neither. Composition organizes the sequence cleanly, while leaving those harder questions for a richer model. Even this modest version lets me build a favourite combination once and perform it with a single call.