Re: CamlIDL - stub code generator and COM binding for OCaml

From: Andrew Martin (amartin@ibmoto.com)
Date: Tue Mar 09 1999 - 19:54:33 MET


Date: Tue, 09 Mar 1999 12:54:33 -0600
From: Andrew Martin <amartin@ibmoto.com>
To: Xavier Leroy <Xavier.Leroy@inria.fr>
Subject: Re: CamlIDL - stub code generator and COM binding for OCaml

How about the following change to the Ocaml language with two orthogonal
extensions to the use of the "open" keyword:

1) allow open to be used locally and

2) allow open t where t is a type expression as well as open M where M is a
module
expression.

In detail:

1) Allow open to be used locally, in a way that parallels the use of "let" --
(in a way, they both introduce bindings into the current environment), so that
in
addition to being able to say "open Foo" in a global context, you would also be

permitted to say "open Foo in <e>" which would limit the scope of the bindings
introduced by open Foo the expression <e> Thus, if M is a module exporting
symbols a, b, and c, I could pass a, b, and c as arguments to a function f by
writing
(open M in (f a b c))

2) A struct type introduces new bindings into a name-space of field
identifiers. For example, the declaration

type t1 = {a:int; b:int}

introduces two new bindings for "a" and "b" respectively into a name-space of
field identifiers. If I now write

type t2 = {a:char; b:char}

I introduce new bindings for "a" and "b" that eclipse the bindings introduced
by the declaration of t1.

2) Suppose, I allow one to write

open t1 in <e>

which re-introduces the bindings provided by t1 in the name-space of
field-identifiers. Thus, I can now write
   let x = (open t1 in {a=4; b=5}) in ....
   or,
   let (aa,bb) = (open t1 in (x.a,x.b))
   or,
   open t1 in (x.a <- 5)

Similarly, any type-constructors associated with t1 would be re-introduced into
the environment so that one could write
type t1 = A | B | C of int
type t2 = A | B | C of char

let x = open t1 in if true then A else C 3

Just a thought,
Andy

Xavier Leroy wrote:

> > I have one concern about the handling of structs. Actually, it's more of a
> > concern with Ocaml than with idl, but idl makes the problem more apparent.
> >
> > How can one deal with two struct types whose members have the same names.
> > In Ocaml, for example:
> >
> > type foo = {a:int; b:int}
> > type goo ={a:char; b:char}
> >
> > How can I now create an object of type foo?
>
> Currently, you can't, and I agree this is a serious problem with
> CamlIDL-generated code. (There's also the symmetrical problem of how
> do you now access the fields of an object of type foo.)
>
> > It would be nice if I could write
> > let x = ({a=4; b=5;}:foo) or
> > let x = {foo.a=4; foo.b=4} or even
> > let (x:foo) = {a=4; b=4}
>
> Solutions 1 and 3 could be made to work by having a special type
> inference rule for record construction when a known record type is
> expected by the context. OCaml already does a similar hack for
> typing printf format strings. However, it's a hack, and it has fairly
> bad properties (e.g. the results of type inference become dependent on
> the order in which the type-checker works.)
>
> For access, you'd have to say something like (x : foo).a.
>
> The second solution could be made to work for record construction, but is
> syntactically ambiguous for field access: does x.foo.a means "field a
> of field foo of x", or "field foo.a of x" ?
>
> > However, if one is defining a caml interface for existing C code,
> > the problem is much worse, since the C code will have been written
> > without regard for the need to avoid reusing the same field name in
> > different struct types.
>
> Right. The problem could also be attacked at the level of CamlIDL by,
> for instance,
>
> - adding an attribute "mlname" to struct fields to specify the name of
> the label in the Caml code, e.g.
>
> struct s { [mlname(s_a) int a; [mlname(s_b)] int b; };
> struct u { [mlname(u_a) int a; [mlname(u_b)] int b; };
>
> However, adding all those names becomes tedious. Maybe CamlIDL could
> use some heuristics to find suitably unique Caml label names
> (e.g. if all struct field names are unique in the whole interface,
> use them, otherwise prefix them by the struct or typedef name).
>
> - putting sub-modules in the generated .ml and .mli files.
> For instance, non-object interfaces in the IDL source could be
> translated to sub-modules:
>
> interface I1 { struct s1 { int a; int b; }; }
> interface I2 { struct s2 { int a; int b; }; }
>
> would become
>
> module I1: sig type struct_s1 = { a :int; b : int } end
> module I2: sig type struct_s2 = { a :int; b : int } end
>
> Any other ideas?
>
> - Xavier Leroy

--
Andrew K. Martin, Ph.D.
Motorola Inc., Somerset Design Center
Networking and Computer Systems Group

phone: (512) 424-8325 6200 Bridgepoint Parkway, Building 4, fax : (512) 424-8846 Mail Drop OE70 email: amartin@ibmoto.com Austin, TX 78730



This archive was generated by hypermail 2b29 : Sun Jan 02 2000 - 11:58:20 MET