[bitc-dev] 'declare' forms and Incompleteness

Swaroop Sridhar swaroop.sridhar at gmail.com
Tue Jul 12 19:04:24 EDT 2005


Consider the following 2 declare forms:

1) (declare value:type) and
2) (declare type:ref)

Should the value defined in (1) and the type defined in (2) be 
considered complete or incomplete at the point of declaration?

Let us consider each case.

1) (declare value:type)

Clearly, considering the value to be complete is wrong.
Because, if this is done, one can write:

(declare a:int32)
(define a a) ; !!!

This would not have been possible without the declare because of 
incompleteness restriction.

However, if we say that the value is incomplete, then the declare form 
virtually looses value as an 'extern' declarator. And, one cannot even write

(interface abc
   (declare a:int32)
)

(module efg
   (import abc)
   (define f (lambda (x) a))
)

2) (declare type:ref)

If the type is complete, then one can write:

(declare a:ref)
(deftype b (deref a)) ; don't know a (and a's size) yet!

So, probably the right thing to do is to make it incomplete.

Stepping back, I think that the declare statement probably is mixing two 
distinct purposes - namely:
i) (somewhat opaque) Interface Specification
ii) Forward declaration.
And, it is probably better to keep them separate.

So one proposal would be
- An interface can contain ONLY declare forms
- All declared forms are complete in the modules that IMPORT an
   interface.
- All modules that satisfy some of the definitions of an interface,
   SHOULD NOT import this interface. That is, declare forms have
   NO effect on these modules, except that there will be an error
   if types are incompatible with the interface specification. The
   unification of the definition with the declaration will be done
   AFTER completely typing the definition.
- There are NO forward declaration. Use rec-types and letrec for
   mutually recursive definitions.

Obviously, the downside to this proposal is that circular dependencies 
among interfaces cannot be safely permitted (This is similar to ML's 
modules. They also tend to force a hierarchical structure, and flat 
cyclic structures are not supported).

If circular dependencies are permitted, I think this will be similar to 
C interfaces where one can write:

b.c
----

extern int b;
int a;

void A() { a = b; }

a.c
----

extern int a;
int b;

void B() { b = a;}

We can also probably take a middle ground, and say that only incomplete 
forward type declarations are permitted (and can be used in a circular 
fashion), but not value declarations.

Swaroop.


More information about the bitc-dev mailing list