[m-dev.] interfacing with C# (was: Existentially quantified types.)
Fergus Henderson
fjh at cs.mu.OZ.AU
Sun Feb 25 03:33:00 AEDT 2001
On 22-Feb-2001, Ralph Becket <rbeck at microsoft.com> wrote:
> Yesterday there was a discussion here about how C# classes might be
> made accessible to Haskell under the .NET framework. Several suggestions
> were made, most requiring serious extentions to the Haskell type
> system.
>
> It seems to me that typeclasses and existentially quantified types
> are sufficient to the task.
Here's some notes that I wrote (in November) on how to do that for
Mercury.
- Mercury calling arbitrary .net component:
- need interface tool to convert .net metadata to Mercury interface
layer
- this interface layer will need to be an actual layer of code, due to
differences in parameter passing. E.g.
namespace nnn {
-- base class
class Foo {
-- constructor
Foo() { ... /* unspecified */ ... }
-- ordinary method
public int foo_method(float) {
... /* unspecified */ ...
}
}
-- derived class
class Bar : Foo {
}
-- struct
struct Baz {
-- constructor
Baz() { ... /* unspecified */ ... }
-- ordinary method
public int baz_method(float) {
... /* unspecified */ ...
}
public static Foo return_foo() {
... /* unspecified */ ...
}
}
}
will map to
:- module nnn.
:- interface.
:- module foo.
:- interface.
% For each class, we generate an abstract type,
% an abstract type class, an instance
% declaration for that type class and type,
% and additional instance declarations for any
% base classes that this type implements.
:- type foo.
:- typeclass foo(T).
:- instance system.object(foo).
:- instance foo(foo).
% foo(T) is an *abstract* typeclass; this means
% that there is no way to declare Mercury types
% to be an instance of this type class, so
% cross-language inheritance in that direction
% (.net base class, Mercury derived class) is
% not allowed.
% ordinary method
% Note that the argument has type
% `ref(Foo) <= foo(Foo)'.
% The `Foo <= foo(Foo)' instead of `foo' allows
% passing values of derived classes,
% and the `ref(Foo)' instead of `Foo' allows
% null references, object identity, and
% (together with the io__state pair)
% destructive update of the argument object's
% fields.
:- pred (foo_method(ref(Foo)::in, float::in, int::out,
io__state::di, io__state::uo) <= foo(Foo))
is det. % (or cc_multi?)
:- pred (foo_method2(Foo::in, float::in, int::out,
io__state::di, io__state::uo)
<= (foo(Foo), ptr(Foo)).
is det. % (or cc_multi?)
% constructor
% Note that this is guaranteed to never
% return null. Nevertheless we still map it
% to something that returns ref(foo), since
% the object returned has object identity.
:- pred foo(ref(foo)::out, io__state::uo,
io__state::uo) is det.
:- end_module foo.
%----------%
:- module bar.
:- interface.
:- type bar.
:- typeclass bar(T).
:- instance foo(bar).
:- instance bar(bar).
:- end_module bar.
%----------%
:- module baz.
:- interface.
:- type baz.
% constructor
:- pred baz(baz::out, io__state::uo, io__state::uo)
is det.
% ordinary method
% note
:- pred baz_method(baz::in, float::in, int::out,
io__state::di, io__state::uo)
is det. % (or cc_multi?)
:- some [Foo]
pred (return_foo(ref(Foo)::out, io__state::di,
io__state::uo) <= foo(Foo))
is det. % (or cc_multi?)
:- end_module baz.
:- implementation.
...
:- end_module nnn.
Note that if you round-tripped this would map to something
different than the original, e.g. because the Foo object
parameter in foo_method would have type `Object' rather than
`Foo', and because it would be a static method with an explicit
parameter rather than an instance method, etc. So we will
generate a layer of interfacing glue code. This can be done
automatically from the meta-data. (We could avoid the need to
generate a layer of interfacing code by inserting extra pragmas
in the generated Mercury interface and treating calls to procedures
marked with such pragmas specially.)
--
Fergus Henderson <fjh at cs.mu.oz.au> | "I have always known that the pursuit
| of excellence is a lethal habit"
WWW: <http://www.cs.mu.oz.au/~fjh> | -- the last words of T. S. Garp.
--------------------------------------------------------------------------
mercury-developers mailing list
Post messages to: mercury-developers at cs.mu.oz.au
Administrative Queries: owner-mercury-developers at cs.mu.oz.au
Subscriptions: mercury-developers-request at cs.mu.oz.au
--------------------------------------------------------------------------
More information about the developers
mailing list