[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