bad behavior of Call-by-value(-result)

Return-Path: <oles@watson.ibm.com>
Date: Wed, 20 Nov 91 12:42:50 EST

I composed the following note for the types mailing list.  Before
submitting it, I sent it to John Reynolds for his comments, which, with
his permission, I am attaching at the end.

-- Frank Oles

Given the recent discussion of CBN vs. CBV, I thought I'd contribute my
own example of why call-by-value-result is badly behaved.  (I think that
when people talk about call-by-value in relation to imperative languages,
they are really thinking of call-by-value-result.  I could be wrong.)

Consider 4 procedures
                  p1n, p1vr, p2n, and p2vr.
in a language like ALGOL W, in which one has call-by-name, call-by-value,
call-by-result, and call-by-value-result.  (See pp. 168-172 of "The Craft
of Programming" by John Reynolds if the terms are unfamiliar.  Basically,
a formal parameter called by value is the same as one declared to be an
expression.  If you want to pass a variable as a parameter to a proper
procedure by value, and if you want that variable to be affected by the
execution of the procedure, then it should be passed by value-result.)

For i=1,2,  pin and pivr have the same bodies.
In p1n and p2n, x is passed by name.
In p1vr and p2vr, x is passed by value-result.
The body of p2n is obtained from p1n by changing an occurence of x to y.

procedure p1n (x: integer_var, y:integer_exp)

procedure p1vr (x: integer_var_value_result, y:integer_exp)

procedure p2n (x: integer_var, y:integer_exp)

procedure p2vr (x: integer_var_value_result, y:integer_exp)

Suppose z has been declared to be an integer variable, and z has just
been set to 0.  Consider the calls
  p1n(z,z)  ,
  p2n(z,z)  ,
  p1vr(z,z) ,
  p2vr(z,z) .

Since in passing from p1n to p2n, and from p1vr to p2vr, we only changed
x to y, and in the calls identical actual parameters are supplied for
both x and y, one would expect the effect of executing
    p1n(z,z) to be the same as p2n(z,z)
    p1vr(z,z) to be the same as p2vr(z,z) .

Well, it is true that both p1n(z,z) and p2n(z,z) both set z to 2.

However, p1vr(z,z) sets z to 2, whereas p2vr(z,z) sets z to 1.

-- Frank Oles


Dear Frank --
  Your examples are certainly correct, and they do show that
call by value-result can behave strangely in Algol W or Forsythe.
On the other hand the current CBV-CBN controversy that is
roaring through the type mailing list (at least as much of it
as I've had time to look at) seems to center on languages
like Scheme and ML when it discusses imperative features.
I don't know whether your examples can be translated into
such languages.
  The point is that Algol-like and Scheme-like languages differ
in the way that imperative features are imbedded in the underlying
functional sublanguage, and that this difference is more
fundamental than the distinction between call by name and
call by value.  Even though call by name is certainly superior
for Algol-like languages and probably superior for purely
functional languages, it may be inferior for Scheme-like
  --John Reynolds