Call by name is actually a closure based mechanism under the hood. It's like lazy evaluation, but with side effects allowed:
(let ((0 42))
(a #(1 2 3))
(foo (aref a (incf i))))
If foo is call by name, then it receives a thunk (basically a lexical closure) for the argument. The aref expression is then evaluated inside foo whenever foo refers to the corresponding argument. (Unfortunately, repeating the incf side effect).
We could simulate this with: (foo (lambda () (aref a (incf i)))
with foo using (funcall arg) to get the argument's value.Call by need, described below that, seems exactly like the insertion of delay and force. The call-by-need argument expression is basically wrapped in an implicit delay, and callee refers to the argument value using implicit force. delay and force are just additional wrapping around a closure to add a flag to squash multiple evaluations.
I just remembered I implemented some macros to simulate call by name in the TXR solution to the "Man or boy test" task on Rosetta Code:
https://rosettacode.org/wiki/Man_or_boy_test#TXR
With these macros, Knuth's test is expressed exactly in the original form (modulo the Algol being cast into S-exp syntax).
Call by name isn't just lambda with funcall (as might be wrongly inferred from my comments in the other reply), because it supports assignment. If we pass a variable A with call by name, the caller can assign to it. This all works with the given macros, and it probably more or less corresponds to the Algol mechanisms.
(The task description is "Imitate Knuth's example in Algol 60 in another language, as far as possible." so the solutions which don't actually implement a call-by-name syntax and semantics don't go as far as this solution.)