Email list hosting service & mailing list manager


Re: meta-comment on typing Per Bothner 06 Oct 2005 05:38 UTC

John.Cowan wrote:
>>* Once one has optional type declarations, the need for type-specific
>>arithmetic primitives is reduced or eliminated.
>
> How far down the call chain is the type inference to be done; in other
> words, do these declarations only affect calls that are statically
> within the lambda where they appear?

Since it *optional* static typing, I'm assuming that the specific
operations are "consistent" in the sense of the following example:

If (and (fixnum? x) (fixnum? y))
then: (eqv? (+ x y) (fx+ x y))

In that case the use of fx+ rather than + is basically compiler hint
that the operands are expected (required) to be fixnums.  Then:
   (fx+ x y)
is equivalent to:
   (let ((x_f :: <fixnum>) (y_f :: <fixnum>))
     (+ x_f y_f))
and the fx+ operation is unneeded: The same effect *and efficiency*
can be achieved with suitable type declarations and/or type inference.

Obviously one would have a cast operator as a shorthand.  Kawa has:
   (as <TYPE> <expr>)
which is equivalent to:
   (let ((tmp :: <TYPE> <expr>)) tmp)
In Kawa <TYPE> is actually an identifier that evaluates to a Type value,
and (as ...) is a function that is specially optimized by the compiler.
However, I don't think R6RS should not go that far, but could just
define (as <TYPE> <expr>) as a special form.

To answer your actual (I think) question: Type declarations are local
and apply lexically, just as in C, Java - and Common Lisp.

Note we don't need (for this purpose, at least) a fancy type system
with higher-order types.  Just simple types corresponding to the
various type predicates: E.g. corresponding to (procedure? x)
we'd have a plain <procedure> type specifier.
--
	--Per Bothner
xxxxxx@bothner.com   http://per.bothner.com/