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