The ZINC machine (Leroy, 1990) fixed a real cost in the CAM: naive currying builds an intermediate closure for every argument, so f a b c allocates three times. ZINC's trick is to push all the arguments first and apply the function once — a multi-argument call costs one step, not one-per-argument, and closures are built only when a function is genuinely partially applied. This “push/enter with a mark on the stack” — the GRAB step, where the entered function itself matches its arity — is why OCaml's bytecode is fast. The ZINC experiment became Caml Light and then OCaml's bytecode runtime — the Z-in-C machine.
A curried call add 2 3 then * 4. The demo pushes arguments and applies once, avoiding a per-argument closure: live demo
“Currying means one closure per argument.” — ZINC pushes every argument first and applies once, so a full call is a single step and closures appear only when you actually stop short. Curried syntax, uncurried cost. cited
Push all the arguments, apply once, and build a closure only when a call really stops short. Curried on the surface, flat underneath — the reason ML bytecode is quick. Leroy 1990
On the canonical compiler, add 2 3 = 5, then * 4 = 20 — a two-argument call applied at once: