[comp.lang.scheme] Jinx's order of evaluation proposal

ziggy@hx.lcs.mit.edu (Michael R. Blair) (04/11/91)

In the ongoing to-specify-or-not-to-specify-order-of-arg-eval debate,
Jinx has offered the following and asks if anyone objects:

jinx> All the even numbered arguments are evaluated first from right to
jinx> left, and then the odd numbered arguments are evaluated from left
jinx> to right.

I object strenuously to this. The reason: it would still be possible for me
to inadvertently supply to a procedure call two arguments which interfere
(one affecting the value of the other) in an unanticipated way which I did
not intend yet not detect it when testing my code.

I think the only well-reasoned way to avoid this is by one the following:

 [1] Tell the user that the order of evaluation of arguments is as
     Jinx has suggested but with the additional behavior that:

     a. For each argument, we consider the position of the argument
        within the argument list as viewed left-to-right, the leftmost
        argument being at position 1 (by definition of ``position''...
        this is *not* ``index'': ``index'' starts at 0).

     b. Consider the number of arguments in the application. Call it A.

     c. Arguments are evaluated as follows:

           All the even numbered arguments are arg-evaluated first from right
           to left, and then the odd numbered arguments are arg-evaluated from
           left to right.

     d. Arg-evaluation is like normal evaluation except that it considers the
        position of the argument being evaluated as well as the number of argu-
        ments A, as follows:

        i) When an even numbered argument at position P is arg-evaluated, it is
           evaluated A+P-1 times and the value of the A-P+1th evaluation is
           returned.

        ii) When an odd numbered argument at position P is arg-evaluated, it is
            evaluated A+P+1 times and the value of the (1 + (A mod P))th eval-
	    uation is returned.

     This has the advantage of evaluating arguments multiple times (of course,
     side-effect free arguments need be evaluated only once... whether or not
     a side-effect has occurred can be run-time checked to decide if further
     evaluation is needed) in a deterministic fashion, but one that is
     sufficiently non-obvious that programmers are quite unlikely to not detect
     an inadvertent mutational argument. It is also sufficiently computationally
     straightforward that proofs of program correctness would not increase in
     obtuseness to any appreciable degree.

 [2] An alternative is to specify left-to-right evaluation but where all writes
     to the store incurred by this evaluation will be postponed until all
     arguments have been evaluated and where only the last write to a location
     will take effect.

 [3] Specify that no argument in a given argument list may incur a write effect
     on any location which another arguments reads or writes. Make implementa-
     tions signal a runtime error when this restriction is not observed. The
     inefficiency this may impose on an implementation is far outweighed by the
     convenience it affords the naive user in being able to perform arbitrary
     mutation within an argument list without regard to the semantic consequence
     since the implementation will detect any possible problems.

 [4] Require that arguments be only variable references, not calls to other
     procedures. This simple syntactic restriction obviates the entire issue.

 [5] Introduce a new special form (as Mark Day suggested):

     (WITH-ARGUMENT-EVALUATION-ORDER (1 3 2 5 4)
       (foo (zap x) (baz (bar x)) (zorch x) (+ x 1)))

     which explicitly declares the argument evaluation order for the application
     in question. In the above, FOO is evaluated first followed, in turn, by
     (baz (bar x)) then (zap x) then (+ x 1) then (zorch x). Note that any one
     of these arguments could itself have used WITH-ARGUMENT-EVALUATION-ORDER.

 [6] Prescribe a standard text string hash function and specify that a stable
     sort be performed on the hashed textual appearance of each argument. This
     sort specifies the order in which the arguments are to be evaluated.

I hope you find some of these suggestions intriquing so that we can continue
this very fascinating discussion of the virtues of specifying an evaluation
order so that I can some day reap all the benefits of a prescribed evaluation
order. After all, using LET* just to get the side effects right before a
procedure call is very distracting... it makes me stop and think about the
side-effects that will be incurred when what I really want to think about is
the single computation event that the application as a whole represents.


 -zorchy
-- 
zorchy@flame.athena.mit.edu    a.k.a. Reginald Zorakowski

``To err is human. I am human. Draw your own conclusion, bub.''