First impression is that this proposal is an attempt to reinvent Ada packages. "Statefull interface" also contradict other usages of word "interface". "Stateful" is an implementation property. I was not happy with stateful modules either, but I'm still waiting for memory model specification before I can comment on the issue.

On issue 1: Ada has separate keywords for importing other package and using names without qualification.

Constantine

Jonathan S. Shapiro wrote:

This is a request for comments -- if we are about to mess this up we
want to know!

As I have thought more carefully about the current BitC module
mechanism, I have become increasingly unhappy with it. There is nothing
wrong with modules per se, but the module mechanism isn't really
achieving what I was trying to achieve. What we needed was interfaces,
not modules.

Since "interface" is a term used in many ways, let me state what I mean:
an interface is a contract between one or more *clients* and an
implementation. It describes the attributes of the implementation that
the client is entitled to rely on.

So here is a proposal for how I think we should do interfaces in BitC.

First, an interface is a compilation unit. One interface, one input
file. This restriction is imposed so that the compiler will be able to
successfully resolve IMPORT statements.

An interface is introduced by either the INTERFACE or STATEFUL-INTERFACE
top-level form, and has the format:

 (INTERFACE ident
   if-decl ... if-decl)

Where "ident" is a namespace identifier.

An if-decl can be any of the the following:

 1. A DECLARE form, as described in my previous email
 2. A type definition (DEFUNION, DEFSTRUCT, DEFTYPE)
 3. A constant definition

If the interface is not stateful, then all of the declarations must be
deeply non-mutating.

A client makes use of an interface by means of one of the following
declarations:

 (IMPORT if-name)
 (STATEFUL-IMPORT if-name)

with the meaning that following this declaration the identifier
"if-name" will act as a namespace identifier. "if-name" must match the
identifier given in the interface. Compatibility is required to achieve
statefup import.; the IMPORT statement will not import stateful
interfaces.

The implementation of an interface proceeds by first using one of the
declarations above, and additionally declaring

 (PROVIDES if-name)

The PROVIDES form indicates that the compilation unit defines one or
more of the types or symbols that is declared in the interface.

For example:

 ;; Interface declaration:
 (interface list
   (defunion (list 'a):ref nil (cons 'a (list 'a)))

   (declare length : (fn (list 'a) int32)))

 ;; Provider:
 (import list)
 (provide list)

 (define (length x)
   (case x ((nil 0)
           ((cons a b) (+ 1 (length b)))))

 ;; Client:
 (import list)

 (define mylist (list::cons 3 list::nil))


OPEN ISSUES

There are two problems with this specification:

1. It is somewhat awkward that the names published by an interface
cannot be imported for unqualified use -- especially for commonly used
types like list. It is possible to use DEFINE to achieve *nearly* the
same result, but not quite. Consider:

 (stateful-interface if
   (declare x : (mutable int32)))

 ;; client:
 (stateful-import if)
 (define x if::x)

The intention here is to define a local alias for "x", but the actual
effect is to create a copy.

I think that we ultimately will need to resolve this, but for the moment
I want to work without it and gain experience to determine how such
aliases should work.

2. Note that in contrast to the previous module import, interface import
does NOT provide any means to rename the interface, and does NOT provide
any means to re-export an interface. The namespace of interfaces is a
global scope, and name collisions are possible. This is intentional,
because it makes type names unambiguous for printing purposes. We will
probably need a way to deal with this at some point.

3. There is a problem with declaring opaque value types. For example:

 (interface if
   (declare x : val)
   (declare instance : x))

This is a declaration that "x" is a value type of arity zero, and that
"instance" is an instance of this value type. Now consider some piece of
code like:

 (f instance)

where we are attempting to pass "instance" to some function. This is
only useful if "f" will eventually call some other function for which
the type is translucent, but that is not a problem. The immediate
problem is that the caller does not know the SIZE of "instance", and
therefore cannot form a proper call frame for it. More generally, the
caller does not know the copy or explicit free semantics of "instance".

So there is a general problem hiding here in the declaration of opaque
value types that we will ultimately need to solve. My intuition for the
moment is that we simply should not support opaque value types in
interfaces for now.


shap

_______________________________________________
bitc-dev mailing list
[email protected]
http://www.coyotos.org/mailman/listinfo/bitc-dev


_______________________________________________
bitc-dev mailing list
[email protected]
http://www.coyotos.org/mailman/listinfo/bitc-dev

Reply via email to