[R6RS] Low-impact proposal: Evaluation order directive

Anton van Straaten anton
Wed May 25 07:23:17 EDT 2005

Against all prudence, I have whipped up a simple (?) proposal which 
shouldn't consume much brain-bandwidth.  If something similar has 
already been considered, or if there other reasons this isn't 
appropriate, I'll drop it.

I've read chunks of the archives, all of the wiki, and the December 
vote.  I was pleased to see the (eventually?) unanimous result of the 
vote on evaluation order.  This proposal doesn't affect that vote.

(Note: this turned into quite an essay, which could certainly be edited 
down if I had more time, but the overall idea should be clear after the
next few paragraphs.)

Evaluation order directive

It would be useful for Scheme to have a standard directive which 
specifies the order of evaluation required by a piece of code.  This 
ought most likely to be a module- or file-level directive.  The exact 
form which this directive would take are left open, for the moment.

If an implementation supports the evaluation order specified by the 
directive, it would be required to evaluate the code in question using 
the specified order.

The directive would *not* place any requirements on implementations to 
support a particular evaluation order.  However, implementations would 
be required to reject any program which specifies an evaluation order 
which is not supported by that implementation.

This would allow code which depends on, say, left-to-right evaluation to 
declare that fact.  An implementation which doesn't support L2R 
evaluation would be required to refuse to compile or run such code.

The directive would also allow code to explicitly assert that it is 
believed to be independent of any particular evaluation order.  Such 
code would, of course, be accepted by any implementation, regardless of 
an implementation's supported evaluation order(s).

Programs would not be required to specify an order of evaluation.  If no 
order is specified, an unspecified order of evaluation would be used. (I 
claim that the semi-tautological nature of the latter sentence 
demonstrates the logical consistency of this proposal.)

Of course, an implementation which does not guarantee any fixed 
evaluation order would be required to refuse to compile or run any code 
which  specifies a particular order.  Such an implementation should only 
accept code which either has no order directive, or code which uses the 
directive to explicitly specify that it is order-independent.

Mixing Orders

One technical concern with this proposal is the question of what happens 
in an implementation which supports multiple alternative orders of 
evaluation, in the case where different pieces of code (modules or 
whatever) specify different evaluation orders.

Implementations are permitted to refuse to support the possibility of 
mixed evaluation orders, except in the one special case of mixing a 
specified order with an unspecified order.  In that case, it is 
permissible for all code to be evaluated under the specified order.  An 
implementation may nevertheless optionally choose to use other orders 
when evaluating the unspecified-order code.

Implementations are permitted to support the coexistence of multiple 
different evaluation orders, if they so choose.


This directive would allow some problems with code portability in Scheme 
to be corrected.  It would also allow ambiguity to be reduced.  (I say 
"allow", because use of the directive is optional.)

Currently, code written to depend on a particular implementation's 
evaluation order does so silently.  This results in potential problems 
for human readers of the code, in determining the intent of the author. 
It also results in potential problems when porting code between 

Code which uses this directive would be prevented from inadvertently 
being run under an implementation which does not support the required 
evaluation order.  This rules out one class of portability problems for 
any code which makes use of the directive.  This goes some way towards 
addressing one of the major safety-related objections of those in favor 
of fixing a single evaluation order for all Scheme implementations.

Furthermore, the presence of this directive will help to correct 
problems, both real and perceived, created by what currently amounts to 
an *inconsistent, invisible assertion*.

Scheme code which is intended to be portable necessarily does not rely 
on a fixed evaluation order; whereas code intended for certain 
implementations may rely on a particular order (usually L2R).  This is 
the inconsistency aspect -- different code is written with different 
semantics in mind, with no explicit indication of the assumed semantics.

Even worse, particularly from the perspective of user comprehension of 
this issue, is the closely related "invisible assertion" aspect: the 
idea that the programmer may have deliberately depended on a particular 
semantics, and thus be implicitly communicating information by e.g. the 
choice of binding constructs, without any overt indication that this is 
the case.

Many people understandably have difficulty reasoning about code which 
depends on invisible assertions, especially inconsistent ones.  Others, 
again understandably, find them distasteful.  Allowing these assertions 
to be made explicit is likely to improve understanding of this issue, 
and help to clarify future discussions.

In fact, all this proposal does is make explicit something which is 
already implicit in all Scheme programs.  Support for explicitness is 
necessary in this case, because the implicit information is not the same 
for all Scheme implementations, or even for all programs intended for 
the same implementation.

One final motivating factor is that Scheme is an unusual language in 
terms of the variety of application domains in which it is used.  These 
include programming language theory, scientific computing, and 
commercial computing, each of which is a very diverse category in its 
own right.  Scheme is also a multiparadigmatic language which supports a 
sequential imperative style as well as functional style.

Given this extreme diversity of application, having some flexibility on 
the issue of evaluation order is advantageous, even important.  It means 
that one group of users doesn't necessarily have to suffer because of 
the needs of another very different group.

As Oleg Kiselyov has previously pointed out on c.l.s., there is 
precedent for this sort of behavior, in the Mercury language.  Mercury's 
approach goes further than this proposal, but along similar lines:


The third-last paragraph on that page ("This compromise allows Mercury 
to be used in several different ways. ...") summarizes the motivation 
for Mercury.  The relevance to Scheme should be clear.

(Note that Mercury guarantees the availability of numerous evaluation 
modes, whereas this proposal only allows particular evaluation orders to 
be specified, and requires that implementations either use the specified 
order, or refuse to run the code.)

Possible Downside

The presence of this directive could create greater pressure from users 
to have implementations support specific evaluation orders.

In practice, it seems likely that the only order for which such pressure 
would arise is left to right (or else operands left to right, followed 
by operator).  For implementations which currently implement some other 
order, or no fixed order, such pressure may be considered undesirable.

OTOH, if that's what users actually want, the directive allows their 
desires to be satisfied, if the implementor is willing.  Support for 
alternative orders, including unspecified order, can nevertheless be 
retained, if the implementor is inclined to support multiple orders.


Implementation of this proposal will have a positive effect on the way 
evaluation order is used and understood in Scheme.  It will achieve 
progress in a controversial area, in a way that addresses concerns on 
both sides of the issue.  It allows implementors to retain maximum 
flexibility and control over evaluation order, yet should require little 
mandatory effort.

Let the "sharp indrawn breath through the front teeth"[*] begin!

-- Anton


More information about the R6RS mailing list