Maybe we can get the best of both worlds. Let's do the following.
We can implement this in Scheme via a macro:
(extend-syntax (proc-by-value-result) [(proc-by-value-result (id ...) body ...) (with ([(newvar ...) (map (lambda (x) (gensym)) '(id ...))]) (lambda (newvar ...) (let ([id (box (^ newvar))] ...) (let ([result (begin body ...)]) (:= newvar (^ id)) ... result))))])
This differs from the macro for proc-by-value only in the assignments to the input parameters at the end. Try a few calls to expand to be sure you understand what is going on. Here's an example.
Try some similar calls of your own.(expand '(proc-by-value-result (x y) (+ (^ foo) (* (^ x) (^ y)))))
Here is the factorial program done by value-result.
Run some experiments to see if aliasing is a problem here. How does this fac-by-val-result return its computed value to the caller?(define fac-by-val-result (proc-by-value-result (x acc) (while (> (^ x) 0) (:= acc (* (^ x) (^ acc))) (:= x (1- (^ x))))))