Efficiency analysis of multiple-value =/THEN FOR clauses. The For Loops issue writeup [Version 3, June 16th 1993] contains a sample for statement and the equivalent expression. Based on that expansion, the expression: for (x = init() then step(x), until done(x)) body(x) end behaves the same as: begin local for-body-1(x) if (~done(x)) for-body-2(x) end if end for-body-1, for-body-2(x) body(x); for-body-1(step(x)) end for-body-2; for-body-1(init()) end If we are to allow multiple-value =/THEN FOR clauses, the init() and step() forms cannot be evaluated in function argument positions, because doing so would throw away all the values except the first. To pick off all the values, we need to evaluate the init() and step() forms using LET. Specifically: for ((x, y, z) = init() then step(x, y, z), until done(x, y, z)) body(x, y, z) end should behave the same as: begin local for-body-1(x, y, z) if (~done(x, y, z)) for-body-2(x, y, z) end if end for-body-1, for-body-2(x, y, z) body(x, y, z); let (t1, t2, t3) = step(x, y, z); for-body-1(t1, t2, t3) end for-body-2; let (t1, t2, t3) = init(); for-body-1(t1, t2, t3) end Therefore, the question at hand is really whether: let (t1, t2, t3) = expr(); func(t1, t2, t3) is intrinsically slower than: func(expr()) Obviously, there is going to be the extra cost of passing three arguments instead of just one. But beyond that, there is no extra cost because the argument expressions have to be fully evaluated before the function can be invoked anyway. It doesn't matter if the compile has to internally generate the temporary variable to store the arguments in as they are evaluated, or if the FOR expansion generates the temporaries. The same amount of work has to be done either way.