Jonathan S. Shapiro wrote:
On Fri, 2005-06-10 at 09:13 -0400, Swaroop Sridhar wrote:
Jonathan S. Shapiro wrote:
> On Fri, 2005-06-10 at 00:22 -0400, Swaroop Sridhar wrote:
>
>
>> That is,
>>
>> (module list
>> (defunion (lst 'a) Nil (Cons 'a))
>> (append ...)
>>
>> (export lst append)
>> )
>>
If the importer of the module should not be able to pattern match the
type, then why is the type being exported?
My original intention was to export only the interface (name) of the
type lst, and not its shape. This facilitates instantiation of the
object but not examination. It also gives a name which two modules can
use to create assignment-compatible [**] objects.
However, I think this is the wrong approach.
The way to do this is :
(export (type t) f1:(fn t t) f2: t) --- (1)
where the t is abstract, and its shape is not disclosed.
And,
(export lst)
will export the lst type in totality.
... there is
currently no mechanism if somebody really wants to export lst
transparently. However, I feel that we should fix that issue rather than
make everything transparent. Am I missing something?
Why doesn't
(export lst Nil Cons)
suffice?
This is a very strange and probably should NOT be done.
If this is supported, somebody very clever will write:
(export lst Nil)
Because of the otherwise clause of case, the imported module can find
out that there are more legs in the union even though they are not
exported. However, since the otherwise clause is not optional, this will
not lead to a situation in which properly working code will start
throwing an exception simply because the module implementing the union
added another leg to it.
But, somebody even clever will write:
(export Nil)
without exporting lst, and there is no way to type it.
Record-fields and Variant-Constructors are NOT first-class objects, and
SHOULD NOT be independently exported.
> The problem, however, is that we then have no way to state the type of
> "alst".
This is very simple. The type of alst in the importer will be the
abstract type alst::t (unifies only with other alst::t) [**]
This is why I had initially asked for
(export ident:type ident:type ident:type ...)
Then the list module can write
(export alst:t)
I am still not understanding why the :type is helpful. It seems to me
that this can be completely automated.
Consider:
(module lst
(export + - *)
)
In the importing module, the types will be
+: lst::t1
-: lst::t2
*: lst::t3
all three (t1, t2, t3) of which are incompatible.
However,
(export (type t) +:(fn t -> t) -:(fn t -> t) *:(fn t -> t)) --- (2)
will fix this issue.
[**] This brings about another problem with BitC imposing restrictions
on ref and restricted-ref (3.4.1 and 3.4.2) that these type constructors
should not be applied to reference types.
Consider:
(import alst)
(let alstref ((ref alst)) 0)
If this fails to typecheck because of the above restriction, the type of
alst is no longer fully abstract, and the importer will know that alst
is of some reference type.
I think we should have 2 kinds of exports...
If we need two kinds of exports, things have become too complicated and
we need to rethink.
If we do export as in (1) and (2), two kinds of exports are no longer
necessary.
This is now on the border of ML like signatures.
Not really. The flaw in ML signatures is that the types of *internal*
items also get exported. By "internal", I mean "things that are not part
of the function/value type, but are local to its implementation."
I should have been clear. What I meant is that our export statement will
now be as expressive as ML's signature.
In fact, now that I see it,
(export (type t) +:(fn t t) -:(fn t t) *:(fn t t))
is no different from Ocaml's
sig
type t;
+: t -> t;
-: t -> t;
*: t -> t;
end;;
Ocaml's signatures are NOT transparent.
Swaroop.
_______________________________________________
bitc-dev mailing list
[email protected]
http://www.coyotos.org/mailman/listinfo/bitc-dev