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

Re: small integers



    I think I have consistently said that I favor an overflow error when it is a
    type error, that is, when it can be shown that if a bignum were created from 
    the overflow it would cause a type error before the next observable 
    side-effect.
    
That much was clear.  What wasn't clear to me is whether that means "if and
ONLY if".  In other words, are you still opposed to providing a fixnum-only
switch, or fixnum-only operations, to those who want to operate in that
style.  Reading between the lines, I'll assume that you are.

    I think (but I'm not sure about this part) that an overflow in the middle of
    a complex arithmetic expression can often be shown either to cause an overflow
    at the end (and thus we can reason backwards that it is a type error) 

Yes, but the key word here is "often".  In some cases, the constraint on
the type of the intermediate values is obvious, in some cases the user and
the compiler both have to work pretty hard to satisfy themselves that the
constraint holds, and in some cases it's impossible to get the constraint
you want on an intermediate result without sticking a THE in the middle of
your arithmetic code.

    or be
    handled by using increased precision for the intermediate results in the
    arithmetic expression, without going beyond the precision the machine 
    supports.

This is more efficient that going all the way to bignums, but less
efficient than fixnum-only code.  If you really want that double-precision
operation, fine, but if it's just in there as defensive medicine because
the compiler couldn't *quite* prove that no bignum will appear, then you've
got a language that is less efficient than it should be.  In any case, it
requires a very smart compiler to do this kind of analysis in general.  For
people writing portable code, they have to worry what is going to happen on
the stupidest Dylan compiler that is in general use, not the smartest.

I think we're actually not so far apart.  I'm happy to agree that "correct"
integer arithmetic should be the default.  And I'm willing to agree that,
under the proper circumstances, we can omit overflow errors and signal
errors only on violations of user-specified types.

The "proper circumstance" is that there should be an easy, compact way for
programmers to directly declare the types of all the intermediate results
in some long chain of calculations -- for example, that they are all of
type <fixnum> or are integers within some particular range.  We should not
force users to do this by putting THE statements all through the code,
since this is a big pain and it makes the code nearly unreadable.  Nor
should we require users to come up with some clever, subtle, implicit way of
constraining the intermediate-value types by makign statements about the
ultimate inputs and outputs.

Perhaps a RESTRICT declaration would be the way to go.  (RESTRICT <integer>
<fixnum>) is a type declaration that affects a region of code: a whole
module, part of a module, a single function, or perhaps a block within a
function.  It says that, for the region of code in question, the programmer
is declaring that any <integer> will also be a <fixnum>.  One could
restrict any type A to be a B, as long as B is a subtype of A.  Dave
Touretzky proposed something like this for Common Lisp long ago, but the
idea never got much consideration -- a mistake in my view.

As long as I can make some such blanket declaration of the types I'm using,
then I'm willing to describe everything in terms of types and not overflow
policy.  Admittedly, this is a small extra wart on the current Dylan
definition, but I believe that Common Lisp is paid a very high price for
not including such a wart.

It's a separate question whether we should allow an unsafe compilation
policy that just believes such declarations and omits the type-tests.  I
think we should, but that's because I like languages that encourage good
programming style by making it easy to do the right things; I dislike
languages, like Ada and Pascal, that try to make it hard to do the wrong
thing.  Such unsafe policies should be used very carefully -- if you get it
wrong, Bob Kerns wills end you to the lowest level of hell -- but there are
special situations in which I'm willing to take the chance.  It's OK with
me if nothing like this "unsafe" policy appears in the Dylan spec, as long
as implementations are allowed to include such a policy as a non-standard
extension.

-- Scott