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)
>> )
>>
>> Can the importer of this module also do a Cons independent of the append interface?
>
>
>
> Yes, this is a mess. I think the answer must be either
>
>   a) no, because Cons has not been exported, or
>   b) yes, because exporting a union type necessarily implies
>      exporting all of its constructors. This is a special case.
>
> My current thought is that (b) is the correct behavior. It is not useful
> in this example to export a list that I cannot pattern match.


I thought you would say (a). Because, the point is that the importer of the list module should NOT be able to independently pattern match the list, but should use other functions of the list module like
delete(ith element), find, sort, etc.

For me, the only reason to go into (b) would be, because 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?


>
>
>> Also, if I have
>> (module list
>>
>>     (defunion (lst 'a) Nil (Cons 'a))
>>     (append ...)
>>
>>     (define alst Nil)
>>
>>     (export    alst) )
>>
>> Does the recipient also receive the type lst automatically?
>
>
>
> I am not sure. Part of me believes that the answer should be yes,
> because "alst" is of type "(lst 'a)". However, the other part of me
> believes that these are two separate issues, and that "lst" should not
> be implicitly exported. This serves to render the type opaque. An opaque
> type is not always what you want, but it is sometimes useful.
>
> 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)

So that the types in the importer will refer to the same t above, and error messages will probably be more readable (than compiler auto-generating names for these abstract types)

Just to note: Even in C, if a value is exported in the interface, all of its component types are not automatically exported. But, the way the export is handled should be similar to somebody giving you a opaque pointer to alst, rather than somebody giving you alst and not declaring its type, and thus causing compilation to fail.


>
> As a general rule, I tend to favor solutions in which things are not
> implicitly exported, but I'm not sure what to do here.
>
> Proposal?
>

I think we should have 2 kinds of exports:

(export a b c d) ; or (opaque-export a b c d), and

(transparent-export a b c d)

With the understanding that:
i) For a value, transparent-export will also export its type (if it has not already been exported).
ii) For a type, it will expose its shape

It should be noted that this transparency is not deep. That is, in the following weighted list (list with an additional member weight of type int)

(module weighted-list
    (deftype (wlst 'a) Nil (Cons of 'a int (wlst 'a)))
    (transparent-export wlst) ) )

will not export the type (int) of weight. Only wlst and its arguments are exported. That is, the importer who does

(import w weighted-list)

sees

(w::wlst 'a): w::Nil | w::Cons of 'a w::t (w::wlst 'a)

For convenience, we might also add (deep-transparent-export a, b, c, d), depth obviously restricted to the visibility of the defining module itself.

This is now on the border of ML like signatures.


[**]Now I have another issue. Because of the way BitC does import, if some body imports the module :

>>(module list
>>
>>    (defunion (lst 'a) Nil (Cons 'a))
>>    (append ...)
>>
>>    (define alst Nil)
>>
>>    (export    alst) )

TWICE, as in

ex:
(import l1 list)
(import l2 list)

This will create
l1::alst : l1::t and
l2::alst : l2::t

One possibility is to make l1::t an l2::t compatible. Other possibility is to keep them different, and now, the situation is very interesting because I have one value alst with 2 alias names and 2 incompatible but equally powerful types.

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

Reply via email to