[bitc-dev] Forward and extern declarations

Jonathan S. Shapiro shap at eros-os.org
Sun Jul 17 13:00:15 EDT 2005


On Sun, 2005-07-17 at 12:31 -0400, Swaroop Sridhar wrote:

> I am not super-impressed with option 2/3 [variant defunion/defstruct]
> because:
> i) It is less opaque -- it reveals whether a type is a union/structure.
> ii) What about type names created by deftype?
> iii) What about types created using fixint/ieeefloat type constructors?

The opaqueness isn't really a goal here, so I'm not very worried about
that.

Your point iii is really the same as point ii, because you need to give
a type name in order to use DEF, and that requires DEFTYPE.

I don't have a good answer concerning DEFTYPE. At this point, many of
the original motivations for DEFTYPE are gone, and I will be trying to
get rid of it if I can, but until we are sure that will work, I'm not
going to alter DEFTYPE.

> > MarkM and I also considered EXTERN and FORWARD, but neither quite works
> > out well.
> >
> 
> Is this because 'extern' is somewhat odd within the provider? Otherwise, 
> I thought extern (or defextern) was indicative of the behavior of these 
> declarations.

Neither captures all of the cases. EXTERN does not suggest a forward
declaration, and it *does* suggest a declaration that is visible outside
the compilation unit -- which is not always the intention in BitC.

Conversely, FORWARD does not really make sense in interfaces. You need
both keywords to capture the intention, and we would prefer to have one
for this purpose.

>  >   (def (list 'a) :ref) ; list is an opaque reference type
>  >   (def a : int32) ; a is an externally defined variable
> 
> I think these two forms are insufficient for purposes of custom opaque 
> declarations.

Then DECLARE wouldn't work either -- the above forms are the same as the
current DECLARE forms, except that a keyword has been substituted.

> For example:
> 
> (deftype i64 (fixint 32 32 #t))
> (defunion ilist:ref Nil (Cons i64 ilist))
> 
> Now, if I want to expose the shape of ilist but NOT i64, there is NO way 
> of doing it.
> 
> I cannot write:
> (declare i64:ref) because it is NOT a reference type.

I am not understanding your example. You would write:

  (def ilist:ref)

If your goal is to be able to write in the interface:

  (defunion ilist:ref Nil (Cons i64 ilist))

without disclosing the type of i64, then indeed you cannot do that
unless i64 is a ref type and has previously been declared as such.

This is not a syntactic deficiency. It is a reflection of the underlying
requirements of separate compilation. The problem is that if i64 is a
value type and it is not disclosed, then the compiler cannot know how to
copy values of type i64 in any module where the shape of i64 is not
disclosed.

> So we may have to re-introduce
>     (def (list 'a) :val) ; list is an opaque value type
> 
> with the condition that the type is incomplete, and only references can 
> be taken to it.

I realized today that we need to do this anyway, but not for the reason
you wrote above. Consider:

  (defstruct a ... fld : (ref b))
  (defstruct b ...)

where we intend that the value constructors (a ...) and (b ...) should
construct value types rather than reference types. The above declaration
is conceptually fine, but is not permitted by our current syntax. The
only way to repair this would be to permit:

  (defstruct b : val)
  (defstruct a ... fld : (ref b))
  (defstruct b ...)

and impose the requirement that a :val declaration introduces an
incomplete type.


shap



More information about the bitc-dev mailing list