[comp.lang.misc] call-by-name

gateley@mips.csc.ti.com (John Gateley) (12/05/88)

Some misc. commments on Call-by-name parameter passing, in reply to
several articles by Mark VandeWettering, Clay Phipps, and others.

Mark VandeWettering:
>	Call by name is very difficult to implement *in languages with
>	side effects*  In functional languages, call by name can be
>	effectively and efficiently implemented.  Call by name is very
>	popular, and has been refined into "lazy evaluation"....

It is not difficult to implement call-by-name in a language which has
first class functions (such as lisp or scheme), and if the macro system
is good enough, the syntactic sugar can be added too! To define a
function which uses "call-by-name", each invocation of the function has
to convert each of the arguments to functions of no arguments. In lisp,
if foo is supposed to be call by name, you type (foo (lambda () arg) ...)
instead of (foo arg ...).

This method, however, is not powerful enough to support side-effecting
call-by-name parameters (without restrictions)
(define foo (a b)
  (set! a b))
(foo c[x] d)
In this (Scheme) example, if a and b are call-by-name, it is not clear
what the assignment to a should cause to happen: should it change the
local value of a, or should it change the (more global) value of c[x].
Both behaviors are useful, but if changing c[x] is what is desired,
then something similar to lisp's SETF needs to be used: foo will get passed
both a function for C[x], and a function which sets C[X].

In article <2070@garth.UUCP> phipps@garth.UUCP (Clay Phipps) writes:
>The fact that a language feature is enough of a challenge to understanding
>that it can be used as the basis of a test question is "evidence" to me
>that the feature may be more of a liability than an asset.

Complex tools may be used to solve complex problems. Just because, for example,
first class procedures are more complex than most languages allow, I would
not like to be restricted from using them. A language feature becomes a
liability (in my opinion of course) when it can not be applied to problems
very well. Call-by-name in the algol-68 language is difficult to use and
understand. The usage above (doing call-by-name using functions) is not
difficult to use, and applies well to lots of problem.


Someone else said:
"Call-by-name is not used in any other languages."

It is available in lisp, and any language with first class functions, though
not under that name, and without the exact syntax.

John Gateley
gateley@tilde.csc.ti.com

new@udel.EDU (Darren New) (12/06/88)

In article <64961@ti-csl.CSNET> gateley@tilde.UUCP (John Gateley) writes:
>In lisp,
>if foo is supposed to be call by name, you type (foo (lambda () arg) ...)
>instead of (foo arg ...).
>
>This method, however, is not powerful enough to support side-effecting
>call-by-name parameters (without restrictions)
>(define foo (a b)
>  (set! a b))
>(foo c[x] d)
>In this (Scheme) example, if a and b are call-by-name, it is not clear
>what the assignment to a should cause to happen: should it change the
>local value of a, or should it change the (more global) value of c[x].
>Both behaviors are useful, but if changing c[x] is what is desired,
>then something similar to lisp's SETF needs to be used: foo will get passed
>both a function for C[x], and a function which sets C[X].
>
>Someone else said:
>"Call-by-name is not used in any other languages."
>
>It is available in lisp, and any language with first class functions, though
>not under that name, and without the exact syntax.
>
>John Gateley
>gateley@tilde.csc.ti.com

I'm not sure about Scheme, but in LISP, something like the first expression is
actually "call by text". The difference is this:

(foo (lambda () (a[i])) as a call to (define foo (x) (let (i 3) x))
will return a[3] in LISP (if my syntax is right). In Algol-60, the i used
in the called function would be the i in the calling function. i.e.,
function foo (a)
var i : integer;
begin i := 3; return a; end;
function bar()
var i : integer;
    a : array[0..5] of integer;
begin a[3] := 3; a[5] := 5; return foo(a[i]); end;
{Again, forgive the syntax. It's been a while...}

In the Algol-ish example, bar returns 5 (a[5]). In the
LISP-ish version, foo will return a[3]. This is because
LISP is call-by-text (i.e., it is as if the text of the
actual parameter is substituted in for the formal
parameter in the body.)
This is what "function" is for in LISP - it binds the
environment to the argument. I'm not sure whether this
gives call-by-name or not.

                                  - Darren New
                                    Grad CIS student
                                    U. of Delaware

ok@quintus.uucp (Richard A. O'Keefe) (12/06/88)

In article <64961@ti-csl.CSNET> gateley@tilde.UUCP (John Gateley) writes:
>Call-by-name in the algol-68 language is difficult to use and
>understand.

In fact call-by-name in Algol 68 is _impossible_ to use;
Algol 68 hasn't got it!
Algol 68 lets you pass anonymous procedures as parameters instead.

jbs@fenchurch.mit.edu (Jeff Siegal) (12/06/88)

Correct.  In traditional Lisp, variable bindings are resolved
dynamically, and functions can not be directly used to implement call-
by-name.  In Scheme, and Common Lisp, this is not the case.  Instead,
variable bindings are resolved in the scope where the function was
created; prodedures of no arguments can be used to implement
call-by-name.

Jeff Siegal