[Top][All Lists]

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

Re: (+ (values 1 2)) should be 1

From: Mark H Weaver
Subject: Re: (+ (values 1 2)) should be 1
Date: Tue, 24 May 2011 20:25:59 -0400
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/23.3 (gnu/linux)

Hans Aberg <address@hidden> writes:
> Right, but as the result is unspecified according to the standard, the
> Guile manual suggests that the value SCM_UNSPECIFIED as an
> interpretation of that. I merely say that I think it would be a good
> idea.

Although Guile often returns SCM_UNSPECIFIED when the standards say the
value would be unspecified, it does not do this in _every_ case.  To do
so would be very inefficient in some cases, would violate the standards
in other cases, and is in general impossible.

For example, the R5RS says that the result of (eq? '(a) '(a)) is
unspecified.  That's because some implementations are clever enough to
combine the two '(a) immutable list literals into a single object, in
which case #t is returned.  Other implementations make two distinct
copies of '(a), in which case #f is returned.  Of course, efficiency
requires that `eq?' be implemented as a simple pointer comparison.  The
"unspecified" cases are there to allow `eq?' to be implemented

The R5RS gives these examples:

  (eq? 2 2)        ==>  _unspecified_
  (eq? #\A #\A)    ==>  _unspecified_

and also says:

  `Eq?''s behavior on numbers and characters is
  implementation-dependent, but it will always return either true or
  false, [...]

If we were to make (eq? 2 2) return SCM_UNSPECIFIED, we would violate
the requirement above.

Whether `eqv?' should return SCM_UNSPECIFIED when applied to procedures
is undecidable.  The R5RS requires that the result is true when the
procedures' location tags are equal (i.e. when they have the same
identity), and requires that the result is false when the procedures
would "behave differently (return different value(s) or have different
side effects) for some arguments".  The results in all other cases are
unspecified.  The R5RS gives the following example:

  (eqv? (lambda (x) x)
        (lambda (y) y))  ==>  _unspecified_

Here we would need to determine whether two distinct procedures are
equivalent in the sense of always returning the same values and
producing the same side effects.  For such procedures, we should return
SCM_UNSPECIFIED.  Unfortunately, this is undecidable in the general
case.  If we could decide this, we could also decide the halting

Having said all this, one could still make the case that we should
attempt to return SCM_UNSPECIFIED from expressions whose values are
unspecified by the standards whenever _practical_.  However, doing this
would prevent us from implementing extensions to many aspects of the

For example, within string literals, the R5RS "does not specify the
effect of a backslash within a string that is not followed by a
doublequote or backslash."  If we were to follow your suggestion, we
should make "foo\n" return SCM_UNSPECIFIED.  In other words, we would be
unable to add our own implementation-specific backslash escapes.

Let's always keep in mind these two common rationales for unspecified
behavior in language specifications:

* to allow more efficient implementation
* to allow extensions to the standard


reply via email to

[Prev in Thread] Current Thread [Next in Thread]