[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Unspecified values

There are good reasons not to specify (in the Standard) the value
returned by mutators.  Individual dialects/implementations can specify
the value(s) returned if they wish.

Besides the already mentioned ontological reasons for not returning a
"canonical unspecified object" (there is no uninteresting positive
integer), there are other reasons that have not been posted recently:

Semantic reasons:

Some people believe that the "right" thing for mutators is to return
no values.  Assuming that we adopt some multiple values mechanism in
the future, this may be the "natural" thing to do.  Specifying the
value in the meantime will only make people depend on it, and will
make it hard to make this change.  Leaving the value unspecified, any
"portable" program that depends on the value is "in error", and thus
we don't have to support it.  Correct programs won't depend on the
value, and thus the change from one value to no values won't affect
portable programs at all.

Some dialects have consistent values to return for mutating
operations, but there is no agreement among the various dialects.  For
example, some dialects specify that the return value is the new value
being stored (since it has to be computed anyway).  Some specify that
the return value is the previous contents (so that mutators can be
used as atomic "swapping" operations).  Specifying the value in the
standard will force these dialects into non compliance or into
introducing a parallel set of operations which differ only in the
returned value.  Leaving the return value unspecified allows
dialects/implementations to experiment with minor language design

Implementation reasons:

For implementations of many dialects, in which the value returned is
in fact not specified, specifying the return value (even if it is
specified to be an arbitrary, otherwise useless, value) would cause
compilers to generate more/worse code in many cases.  The compiler
must issue code to return the "canonical unspecified value" whenever
it can't prove that the value won't be used.  In my experience this
happens in a large fraction (if not most) of the cases when side
effecting operations are used.  Since the return value should not be
used anyway, why not leave what is returned to the compiler's
convenience?  Why go to extra work to return some canonical object
which is not meant to be used?  The only guarantee that the compiler
must make is that the return value has to be a valid object (so that
your garbage collector won't become confused if the value is "saved").

For debugging reasons, the "right" value to be returned would be some
context object specifying which procedure/expression was producing
this object, what the environment of the procedure (parameters and
free variables) was like at the time of the construction of this
context object, and what the continuation was at this time as well.
Thus if such an object was ever found while debugging, the "culprit"
could be pinpointed easily.  Clearly this is too expensive to do, and
I doubt that returning a canonical object would provide nearly as much
information (think of the case where the result is consed into a data
structure, and is only found to be "unspecified" ten years later when
the structure is accessed).