Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

[Caml-list] recursive modules redux, & interface files

12 views
Skip to first unread message

Chris Hecker

unread,
Mar 18, 2001, 6:09:25 PM3/18/01
to caml...@inria.fr

Two questions/problems:

1. So, I understand that doing recursive types across modules is hard (but I'd say very important for decoupling large software), but is it true that I can't even call across modules recursively? Even with mli files to resolve the types? I find that incredibly hard to believe, but I can't get it to work and it seems the docs say it's impossible as well (so why am I posting about it, you ask? Disbelief that it's not possible, I guess. :).

What is the point of separate mli files if they can't be used to declare a callable interface separate from the implementation? Is this just a small feature that needs to be added to the linker (defer binding unseen modules until all the object files have been seen), or is there something really subtle going on? Since everything compiles and type checks fine, and the subtleties that I don't understand in ocaml usually have to do with the type checker, I'm having trouble seeing how this could be that hard. Example below. Am I missing something?

2. Also, on a related note, why do the interface file and the implementation file (or equivalently, I believe, the signature and structure) both have to have all the concrete types duplicated? I can see the value of having interfaces that hide some implementation stuff and abstract types, but if I've got a big fully-specified variant type in a .mli file, it's annoying and error prone (yes, I know the compiler will catch it) to have to retype the whole thing into the ml file (which I have to do if I want to hide anything else in the ml file, meaning I can't just have an ml without an mli). Is this something the "include" keyword takes care of? Heck, "#include<foo.mli>" would be an improvement over duplicating all the types. :) One of the things I hate about C++ and is having to type function declarations/definitions multiple times.

Thanks,
Chris

---------
Example for Question 1:

--- t1.mli ---
val foo: int -> int
--- t1.ml ---
let foo x = if x = 1 then T2.bar x else x
--- t2.mli ---
val bar: int -> int
--- t2.ml ---
let bar x = if x = 2 then T1.foo (x-1) else x
--- main.ml ---
let _ = print_int (T2.bar 2)

-------------------
To unsubscribe, mail caml-lis...@inria.fr. Archives: http://caml.inria.fr

Brian Rogoff

unread,
Mar 18, 2001, 7:03:10 PM3/18/01
to caml...@inria.fr
On Sun, 18 Mar 2001, Chris Hecker wrote:
> Two questions/problems:

Just one answer/solution I'm afraid, but I also give a grotesque
workaround...

> 2. Also, on a related note, why do the interface file and the
> implementation file (or equivalently, I believe, the signature and
> structure) both have to have all the concrete types duplicated? I can
> see the value of having interfaces that hide some implementation stuff
> and abstract types, but if I've got a big fully-specified variant type
> in a .mli file, it's annoying and error prone (yes, I know the compiler
> will catch it) to have to retype the whole thing into the ml file
> (which I have to do if I want to hide anything else in the ml file, meaning I
> can't just have an ml without an mli). Is this something the
> "include" keyword takes care of?

No, but if you are finding this really onerous then you can use "open" by
creating a "pure" mli file with your gignatic variant type and opening it
in the mli and ml file where it is needed. Does that help?

-- Brian

PS : There are some ways to get around the fact that the linker requires
ordering, either by putting the mutually recursive functions in the
same module (I assume you know this) or by breaking the cycle with
an indirection (first rule of programming: any problem can be solved
with another level of indirection :-). In this case, the indirection
can be provided by passing in functions to foo and bar. Yeah, it's
ugly and all that but it is a workaround.

(* t1.mli *)
val foo : (int -> int) -> int -> int
(* t2.mli *)
val bar: (int -> int) -> int -> int
(* t1.ml *)
let foo f x = if x = 1 then f x else x
(* t2.ml *)
let bar f x = if x = 2 then f (x-1) else x
(* main.ml *)
let rec foo_aux x = T2.bar bar_aux x
and bar_aux x = T1.foo foo_aux x

let _ = print_int (T2.bar bar_aux 2)

Chris Hecker

unread,
Mar 19, 2001, 6:43:27 AM3/19/01
to John Max Skaller, caml...@inria.fr

> Because types in a given implementation may or may not be present
>in the interface.

Right, that's fine, but I only want to have them once, whereever they are. So, if it's a private type, it's in the ml file, and if it's public it's in the mli file (assuming I want one, if I don't then everything's public). How does having them duplicated buy me anything but trouble?

Chris

John Max Skaller

unread,
Mar 20, 2001, 1:20:32 PM3/20/01
to Chris Hecker, caml...@inria.fr
Chris Hecker wrote:
>
> > Because types in a given implementation may or may not be present
> >in the interface.
>
> Right, that's fine, but I only want to have them once, whereever they are. So, if it's a private type, it's in the ml file, and if it's public it's in the mli file (assuming I want one, if I don't then everything's public). How does having them duplicated buy me anything but trouble?
>
> Chris

In C++, a function is either extern or static.
There are only two options. [And non-local classes are _always_ extern]
This is not so in Ocaml: you may wish to provide access to a component
such as a function with a type more constrained than the actual
implementation.
For example:

(* twoint.mli *)
val twoint: int -> int * int

(* twoint.ml *)
let twoint x = (x,x)

Here, the implementation is actually polymorphic, it will work
for more than ints, but clients of the module 'twoint' cannot
use this function to make a pair of floats.

Here is another example:

(* abstr.mli *)
type t
val get: t -> int
val make: int -> t

(* abstr.ml *)
type t = int * int
let get x = fst x
let make x = (x,x+1)


Here, the type t is implemented as a pair of ints.
But the implementation is hidden from the client of the module.
Note that the type 't' itself is not hidden.

--
John (Max) Skaller, mailto:ska...@maxtal.com.au
10/1 Toxteth Rd Glebe NSW 2037 Australia voice: 61-2-9660-0850
checkout Vyper http://Vyper.sourceforge.net
download Interscript http://Interscript.sourceforge.net

Chris Hecker

unread,
Mar 20, 2001, 11:16:59 PM3/20/01
to John Max Skaller, Chris Hecker, caml...@inria.fr

> There are only two options. [And non-local classes are _always_ extern]
> This is not so in Ocaml: you may wish to provide access to a component
> such as a function with a type more constrained than the actual
> implementation.

Yes yes yes, I know this. I'm saying I understand why I need to type
stuff if there's a difference betwen the .ml and .mli versions (hiding
stuff, restricting stuff, abstracting stuff), and that's fine. I'm
asking why I need to retype stuff if it's identical. Check out some
of the source code in the compiler, or any ocaml project I've seen
(the ICFP winners, whatever). There are tons of really huge variants
that are just duplicated in mli and ml. That seems bad, for the same
reason that typing a C++ function declaration 2 times is bad.

Chris

Patrick M Doane

unread,
Mar 21, 2001, 12:23:36 AM3/21/01
to Chris Hecker, caml...@inria.fr
I agree that checking interface/implementation of modules could be
improved.

For projects that I've worked on that have huge variant types, I have
typically placed the variants in a module by themselves with no .mli file.
This technique hasn't worked too well for me in practice and is still
annoying for the smaller variants.

A reasonable modification to the language would allow a module expression
to not include type definitions when they are defined in the module type
and include their type information.

This would mean that

module X : sig type t = int end = struct end

would be accepted, but

module X : sig type t end = struct end

would be rejected because the abstract field 't' is required but missing.


Would this proposal address all the issues you had in mind?

Patrick Doane

Chris Hecker

unread,
Mar 21, 2001, 4:29:23 AM3/21/01
to Patrick M Doane, caml...@inria.fr

> This would mean that
> module X : sig type t = int end = struct end
> would be accepted, but
> module X : sig type t end = struct end
> would be rejected because the abstract field 't' is required but missing.
> Would this proposal address all the issues you had in mind?

Yep, that's what I had in mind!

Xavier Leroy

unread,
Mar 21, 2001, 1:42:47 PM3/21/01
to Chris Hecker, caml...@inria.fr
> 1. So, I understand that doing recursive types across modules is
> hard (but I'd say very important for decoupling large software), but
> is it true that I can't even call across modules recursively? Even
> with mli files to resolve the types? I find that incredibly hard to
> believe, but I can't get it to work and it seems the docs say it's
> impossible as well (so why am I posting about it, you ask?
> Disbelief that it's not possible, I guess. :).

You're right that cross-module recursion even between functions is not
supported, and you're right that this is not because of typing
difficulties -- the type-checking of such recursions is easy.

This is because value components of modules can be the result of
arbitrary computations, and the only way to ensure that these
computations succeed is by making sure they occur sequentially.
Consider for instance:

A.mli val x : int B.mli val y : int
A.ml let x = B.y + 1 B.ml let y = A.x * 3

We don't know how to evaluate these definitions correctly -- indeed,
there is no integer solution to this recursive definition.

Other languages avoid this problem in one of two ways. C and C-like
languages only allow global identifiers to be defined as functions or
compile-time constants, but not results of arbitrary computations.
Haskell and other lazy languages rely on lazy evaluation to perform
on-demand initialization (i.e. compute the definition the first time
it's needed), and aborting computation if a dynamic dependency cycle
is detected (as in the example above).

Java goes pretty much the Haskell way, relying on dynamic class
loading to lazily evaluate static field definitions; originally, it
raised an exception on discovering a dynamic dependency cycle;
nowadays, I think it just pre-initializes static fields to 0 or null,
then compute the initial values based on this (so that in the example
above you'd get x = 1 and y = 3 if the program refers to B.y first,
and y = 0 and x = 1 if the program refers to A.x first :-).

The Haskell solution is semantically cleanest, but lazy evaluation
of module components entails a performance penalty and some increase
in code size (the compiler must emit "am I initialized already?" tests
on every module value access). (The semantics of Java class
initialization entail similar penalties, although they partially hide
them by relying on JIT compilation -- blech.)

A possible approach for Caml would be to have a link-time analysis
that detects cross-module value recursions that involve only function
definitions, and allow these (because they are safe -- like in C!).
Fabrice Le Fessant posted a patch to OCaml a while ago that does
pretty much this. I'm still hoping more general, principled solutions
exist, but they sure are hard to design!

> 2. Also, on a related note, why do the interface file and the
> implementation file (or equivalently, I believe, the signature and
> structure) both have to have all the concrete types duplicated? I can
> see the value of having interfaces that hide some implementation stuff
> and abstract types, but if I've got a big fully-specified variant type
> in a .mli file, it's annoying and error prone (yes, I know the
> compiler will catch it) to have to retype the whole thing into the ml
> file (which I have to do if I want to hide anything else in the ml
> file, meaning I can't just have an ml without an mli).

Yes, it's annoying, and it's more or less a consequence of the
ideology behind the ML module system: that structures define things,
and that signatures can later be ascribed to these structures to hide
or abstract some of these things. With this ideology, every type that
is declared in a signature -- even if it's a concrete declaration that
includes as much information as a type definition! -- must be matched
by a type definition in the corresponding structure. It's just very
principled and logical -- just a bit inconvenient at times :-)

Another way to think about it is that every structure (or
implementation file) must "stand on its own" and make sense without
the signature (or interface file) that will be ascribed to it later
on. It makes sense when the signature is not known when the structure
is defined, e.g.

module M = struct type t = A | B ... end
(* 5000 lines later: *)
module M' = (M : sig type t = A | B ... end)

It becomes practically inconvenient when the signature is known at the
time of the structure definition:

module M : sig type t = A | B ... end =
struct type t = A | B ... end

Which is the case with interface and implementation files.

In this case, one could envision an automatic completion of the
structure / implementation file so that concrete type specifications
from the signature do not need to be implemented in the structure.
Doing this right is not obvious, though. First, it's not enough to
say that a concrete type spec does not need to be matched in the
structure. This would type-check

module M : sig type t = A | B end = struct end

but not

module M : sig type t = A | B val v : t end = struct let v = A end

In other terms, the unmatched concrete type specs in the signature
need to be somehow reintroduced in the structure definition, so that
other parts of the structure may refer to them. While I think it can
be done in most practical cases, it's a bit of a kludge and I'm not
sure how to do this in all cases.

Is the practical value of this kludge enough to forget that it's a
kludge? Can't we live with the current duplication of concrete type
definitions in the name of systematic, principled module systems?
I really don't know.

Best,

- Xavier Leroy

Patrick M Doane

unread,
Mar 21, 2001, 7:04:29 PM3/21/01
to John Prevost, Chris Hecker, caml...@inria.fr
Hi John,

It seems to me that this would be perfectly legal. It is accepted by the
current Ocaml language, and by the extension I proposed unless there is
something I'm missing. Is this the behavior you're expecting?

Patrick

On 21 Mar 2001, John Prevost wrote:

> >>>>> "pd" == Patrick M Doane <pat...@watson.org> writes:
>
> pd> This would mean that
>
> pd> module X : sig type t = int end = struct end
>
> pd> would be accepted, but
>
> pd> module X : sig type t end = struct end
>
> pd> would be rejected because the abstract field 't' is required
> pd> but missing.
>
> What about "module X : sig type t end = struct type t end", where
> values of the type can't actually be constructed? (Except possibly by
> C code.)
>
> John.

Patrick M Doane

unread,
Mar 21, 2001, 7:05:13 PM3/21/01
to John Max Skaller, caml...@inria.fr
I don't see that it makes much of a difference. Besides, the reason it
hasn't worked well for me is that inevitably I want to add some
functions to the module that has the variant type. For example, pretty
printers. The next compromise is to continue the path without a .mli file
until I don't want some of these utilities to be exported. In the end,
I'm back to the source of the problem, having to duplicate a large variant
type.

On Thu, 22 Mar 2001, John Max Skaller wrote:

> Patrick M Doane wrote:
>
> > For projects that I've worked on that have huge variant types, I have
> > typically placed the variants in a module by themselves with no .mli file.
> > This technique hasn't worked too well for me in practice and is still
> > annoying for the smaller variants.
>

> Try placing them in a .mli file instead (no ml file).


>
> --
> John (Max) Skaller, mailto:ska...@maxtal.com.au
> 10/1 Toxteth Rd Glebe NSW 2037 Australia voice: 61-2-9660-0850
> checkout Vyper http://Vyper.sourceforge.net
> download Interscript http://Interscript.sourceforge.net
>

-------------------

Brian Rogoff

unread,
Mar 21, 2001, 7:24:46 PM3/21/01
to Patrick M Doane, John Max Skaller, caml...@inria.fr
On Wed, 21 Mar 2001, Patrick M Doane wrote:
> I don't see that it makes much of a difference. Besides, the reason it
> hasn't worked well for me is that inevitably I want to add some
> functions to the module that has the variant type. For example, pretty
> printers. The next compromise is to continue the path without a .mli file
> until I don't want some of these utilities to be exported. In the end,
> I'm back to the source of the problem, having to duplicate a large variant
> type.

What's the problem with the hack I suggested earlier: put the huge variant
(and other duplicated types) in a "pure" .mli file (I hate using .ml for
that) and "open"ing it where you need it, once in the .mli file and once in the
.ml file? This way you reduce the duplication to two lines.

I know some people are open-phobes, but I find this use of open to be
acceptable.

-- Brian

Patrick M Doane

unread,
Mar 21, 2001, 7:25:15 PM3/21/01
to Xavier Leroy, Chris Hecker, caml...@inria.fr
Hi Xavier,

Your example demonstrates that a proposal for such an extension
should be more explicit about how it should work. I had a particular
implementation in mind from my post yesterday:

For every module definition M that has a signature S
For every type definition t in S that contains optional
type-information and is not defined in M
Add the type definition of t to M (preserving the order from S)

Proceed with the usual algorithms for type checking, matching
structures, etc.

I think this should work properly. Anything I might have missed? You seem
to elude to special cases that are not immediately obvious.

I agree that it becomes kludgy to remove the separation that currently
exists between structures and signatures. However, as a programmer
maintaining the duplicate types also seems kludgy . After all, the
compiler has the information available, why doesn't it use it?

This seems to be a case where a compromise between theory and practice
should be explored.

Patrick


On Wed, 21 Mar 2001, Xavier Leroy wrote:

> It becomes practically inconvenient when the signature is known at the
> time of the structure definition:
>
> module M : sig type t = A | B ... end =
> struct type t = A | B ... end
>
> Which is the case with interface and implementation files.
>
> In this case, one could envision an automatic completion of the
> structure / implementation file so that concrete type specifications
> from the signature do not need to be implemented in the structure.
> Doing this right is not obvious, though. First, it's not enough to
> say that a concrete type spec does not need to be matched in the
> structure. This would type-check
>
> module M : sig type t = A | B end = struct end
>
> but not
>
> module M : sig type t = A | B val v : t end = struct let v = A end
>
> In other terms, the unmatched concrete type specs in the signature
> need to be somehow reintroduced in the structure definition, so that
> other parts of the structure may refer to them. While I think it can
> be done in most practical cases, it's a bit of a kludge and I'm not
> sure how to do this in all cases.
>
> Is the practical value of this kludge enough to forget that it's a
> kludge? Can't we live with the current duplication of concrete type
> definitions in the name of systematic, principled module systems?
> I really don't know.

-------------------

John Prevost

unread,
Mar 22, 2001, 3:19:33 AM3/22/01
to Patrick M Doane, Chris Hecker, caml...@inria.fr
>>>>> "pd" == Patrick M Doane <pat...@watson.org> writes:

pd> This would mean that

pd> module X : sig type t = int end = struct end

pd> would be accepted, but

pd> module X : sig type t end = struct end

pd> would be rejected because the abstract field 't' is required
pd> but missing.

What about "module X : sig type t end = struct type t end", where
values of the type can't actually be constructed? (Except possibly by
C code.)

John.

John Max Skaller

unread,
Mar 22, 2001, 3:19:33 AM3/22/01
to Patrick M Doane, Chris Hecker, caml...@inria.fr
Patrick M Doane wrote:

> For projects that I've worked on that have huge variant types, I have
> typically placed the variants in a module by themselves with no .mli file.
> This technique hasn't worked too well for me in practice and is still
> annoying for the smaller variants.

Try placing them in a .mli file instead (no ml file).

--
John (Max) Skaller, mailto:ska...@maxtal.com.au
10/1 Toxteth Rd Glebe NSW 2037 Australia voice: 61-2-9660-0850
checkout Vyper http://Vyper.sourceforge.net
download Interscript http://Interscript.sourceforge.net

John Max Skaller

unread,
Mar 22, 2001, 3:19:44 AM3/22/01
to Chris Hecker, caml...@inria.fr
Chris Hecker wrote:
>
> > There are only two options. [And non-local classes are _always_ extern]
> > This is not so in Ocaml: you may wish to provide access to a component
> > such as a function with a type more constrained than the actual
> > implementation.
>
> Yes yes yes, I know this. I'm saying I understand why I need to type
> stuff if there's a difference betwen the .ml and .mli versions (hiding
> stuff, restricting stuff, abstracting stuff), and that's fine. I'm
> asking why I need to retype stuff if it's identical.

You don't. There is a tool:

ocamlc -i fred.ml > fred.mli

which will generate the mli file for you. (Use the -i option on the
compiler).

--
John (Max) Skaller, mailto:ska...@maxtal.com.au
10/1 Toxteth Rd Glebe NSW 2037 Australia voice: 61-2-9660-0850
checkout Vyper http://Vyper.sourceforge.net
download Interscript http://Interscript.sourceforge.net

John Max Skaller

unread,
Mar 22, 2001, 3:19:34 AM3/22/01
to Chris Hecker, caml...@inria.fr
Chris Hecker wrote:
>
> > There are only two options. [And non-local classes are _always_ extern]
> > This is not so in Ocaml: you may wish to provide access to a component
> > such as a function with a type more constrained than the actual
> > implementation.
>
> Yes yes yes, I know this. I'm saying I understand why I need to type
> stuff if there's a difference betwen the .ml and .mli versions (hiding
> stuff, restricting stuff, abstracting stuff), and that's fine. I'm
> asking why I need to retype stuff if it's identical.

BTW: you DON'T actually need an .mli file. Try it.
It is only needed when there IS a constraint on 'everything public'.

--
John (Max) Skaller, mailto:ska...@maxtal.com.au
10/1 Toxteth Rd Glebe NSW 2037 Australia voice: 61-2-9660-0850
checkout Vyper http://Vyper.sourceforge.net
download Interscript http://Interscript.sourceforge.net

Francois Pottier

unread,
Mar 22, 2001, 4:16:37 AM3/22/01
to Patrick M Doane, caml...@inria.fr

On Wed, Mar 21, 2001 at 07:03:55PM -0500, Patrick M Doane wrote:
>
> I'm back to the source of the problem, having to duplicate a large vari=
ant
> type.

I think you have missed the point of John's (or was it Brian's?) suggesti=
on,
which is to place large type (or module type) definitions in a separate .=
mli
(or .ml) file, then refer to it from your .mli *and* your .ml file. This =
has
the unfortunate consequence of breaking every module into three files (sh=
ared
definitions, interface, and implementations), making the program structur=
e
somewhat more cryptic. But it usually works well.

Regarding your suggestion,

> For every module definition M that has a signature S
> For every type definition t in S that contains optional
> type-information and is not defined in M
> Add the type definition of t to M (preserving the order from S)

^^^^^^^^^^^^^^^^^^^^

I think the problematic part is in the ordering. The order in which bindi=
ngs
appear may be different in M and S, to start with. So, where do we insert=
the
definition, and (assuming we know where) what do we do if some names refe=
rred
to by the definition aren't yet defined in M at that point?

--
François Pottier
Francois...@inria.fr
http://pauillac.inria.fr/~fpottier/
-------------------
To unsubscribe, mail caml-lis...@inria.fr. Archives: http://caml.i=
nria.fr

Judicael Courant

unread,
Mar 22, 2001, 5:28:49 AM3/22/01
to Brian Rogoff, caml...@inria.fr
Brian Rogoff a écrit :
>
[...]
> What's the problem with the hack I suggested earlier: put the huge vari=
ant
> (and other duplicated types) in a "pure" .mli file (I hate using .ml fo=
r
> that) and "open"ing it where you need it, once in the .mli file and onc=

e in the
> .ml file? This way you reduce the duplication to two lines.
>
> I know some people are open-phobes, but I find this use of open to be
> acceptable.
>

As for open-phobes, somebody gave me a good solution a few days ago: you
can locally define a module with a very short name.

Example : put your type in my_beautiful_type.mli with constructors Node,
Leaf, ..., and where you need it do

module T = My_beautiful_type

then you can use it with a small overhead of 2 chars per use of a
constructor of My_beautiful_type: T.Node, T.Leaf, ...

This is quite elegant IMHO as it makes your code very clear.

As an aside, if you consider applying the same treatment for exceptions
(also duplicated), you need to put them in a .ml file (not a .mli) as a
.cmo is needed for linking (an exception actually creates at run-time a
fresh exception identifier).

Judicaël
--
Judicael...@lri.fr, http://www.lri.fr/~jcourant/
(+33) (0)1 69 15 64 85
"Montre moi des morceaux de ton monde, et je te montrerai le mien"
Tim, matricule #929, condamné à mort.
http://rozenn.picard.free.fr/tim.html
-------------------
To unsubscribe, mail caml-lis...@inria.fr. Archives: http://caml.i=
nria.fr

John Max Skaller

unread,
Mar 22, 2001, 6:11:49 AM3/22/01
to Chris Hecker, caml...@inria.fr
Chris Hecker wrote:
>
> Two questions/problems:
>
> 1. So, I understand that doing recursive types across modules is hard (but I'd say very important for decoupling large software), but is it true that I can't even call across modules recursively?

Yes. More precisely, you cannot forward reference any symbol,
however you _can_ call forward by passing a function backward as an
argument.
[This sucks though]

> 2. Also, on a related note, why do the interface file and the implementation file (or equivalently, I believe, the signature and structure) both have to have all the concrete types duplicated?

Because types in a given implementation may or may not be present
in the interface.

IF you have a file containing ONLY types, then there is no need
to have an .ml file for it. If you have even one val (function, class),
you need the .ml file.


--
John (Max) Skaller, mailto:ska...@maxtal.com.au
10/1 Toxteth Rd Glebe NSW 2037 Australia voice: 61-2-9660-0850
checkout Vyper http://Vyper.sourceforge.net
download Interscript http://Interscript.sourceforge.net

Olivier Andrieu

unread,
Mar 22, 2001, 6:18:04 AM3/22/01
to caml...@inria.fr
Judicael Courant [Thursday 22 March 2001] :

> Brian Rogoff a écrit :
> >
> [...]
> > What's the problem with the hack I suggested earlier: put the
> > huge variant (and other duplicated types) in a "pure" .mli file
> > (I hate using .ml for that) and "open"ing it where you need it,
> > once in the .mli file and once in the .ml file? This way you

> > reduce the duplication to two lines.
> >
> > I know some people are open-phobes, but I find this use of open
> > to be acceptable.
> >
>
> As for open-phobes, somebody gave me a good solution a few days
> ago: you can locally define a module with a very short name.

There's something I've been wondering about type definitions :

In type definitions, you can specify type equation and representation.
- when none is specified, the defined type is abstract ;
- when an equation is given, you get an alias of an already existing
type ;
- with a representation, a new variant or record is defined.

But it is possible to use both, so that you get an alias of an already
defined variant and record but with the fields or constructors attached t=
o
the new type.

It don't really see the point of such a definition : now the type
representation is in 4 different places, and the only gain I see is
that you don't have to prefix the fields names with a module
path. That's no big deal since you can redefine the module with a short
name (one letter).

So, is this form of type definitions actually used, does it have another
purpose besides this namespace issue ?

Olivier

Dave Berry

unread,
Mar 22, 2001, 6:58:30 AM3/22/01
to Markus Mottl, John Max Skaller, Chris Hecker, caml...@inria.fr
Pardon me if this is a dumb question, but what is the difference between
"include" and "open"?

-----Original Message-----
From: Markus Mottl [mailto:mo...@miss.wu-wien.ac.at]
Sent: Thursday, March 22, 2001 11:41
To: John Max Skaller
Cc: Chris Hecker; caml...@inria.fr
Subject: Re: [Caml-list] recursive modules redux, & interface files

If you want even more hardcore moduling, you might be interested in
trying
out the new "include"-keyword for structures (my favourite new language
extension! Thanks!) with the tricks above. You can do tremendous things
with it, like overriding specific functions of modules at runtime, etc.,
with hardly any effort.

-------------------
To unsubscribe, mail caml-lis...@inria.fr. Archives: http://caml.inria.fr

Markus Mottl

unread,
Mar 22, 2001, 7:03:20 AM3/22/01
to Dave Berry, John Max Skaller, Chris Hecker, caml...@inria.fr
On Thu, 22 Mar 2001, Dave Berry wrote:
> Pardon me if this is a dumb question, but what is the difference between
> "include" and "open"?

"include" reexports the definitions of the included module, whereas
"open" only makes them visible within the current module.

Regards,
Markus Mottl

--
Markus Mottl, mo...@miss.wu-wien.ac.at, http://miss.wu-wien.ac.at/~mottl

Hendrik Tews

unread,
Mar 22, 2001, 7:03:57 AM3/22/01
to caml...@inria.fr
Hi,

I would like to vote for solutions that work for the common case
when writing large programs, even if they are hacks, considered
from a theoretical point of view.

Xavier Leroy writes:

[cross module recursion]



A.mli val x : int B.mli val y : int
A.ml let x = B.y + 1 B.ml let y = A.x * 3

We don't know how to evaluate these definitions correctly -- indeed,
there is no integer solution to this recursive definition.

I think that in this case the theoretical cleaness is overrated.
Cross module recursion of functions is soo useful, that it
should be made to work --- even if the solution seems stupid with
respect to the example above.

[duplications in signatures and structures]

Is the practical value of this kludge enough to forget that it's a
kludge?

Sure.

Can't we live with the current duplication of concrete type
definitions in the name of systematic, principled module systems?

No, at least I cannot. Also here I would suggest to have a
solution that works for the common case. What about changing
include, such that including a signature into a structure
includes all types and all exceptions?


Bye,

Hendrik

Markus Mottl

unread,
Mar 22, 2001, 8:03:58 AM3/22/01
to Hendrik Tews, OCAML
Hendrik Tews schrieb am Thursday, den 22. March 2001:
> I would like to vote for solutions that work for the common case
> when writing large programs, even if they are hacks, considered
> from a theoretical point of view.

I am not so fond of sacrificing theoretical beauty: it usually seems
to be the case that there are working solutions that are also elegant -
it's only a matter of thinking about them long enough. You might speed
up development a bit by allowing hacks if you cannot immediately find
a sound solution, but IMHO it is hardly ever a good idea in the long run.

> I think that in this case the theoretical cleaness is overrated.

In general? Probably not. If there is a problem with expressiveness or
else, it seems to be better to first try harder to find a solution with
the existing system before crying for a hacky extension. And if this
doesn't work, let's try to find a more expressive theory rather than
abandoning theory completely.

> Cross module recursion of functions is soo useful, that it
> should be made to work --- even if the solution seems stupid with
> respect to the example above.

Nearly everytime I had thought "now I need recursive modules", I found
other, even elegant ways to do it. If we really want them, please
let's don't put aside theory but take existing clean solutions (e.g.
see Claudio Russo's thesis).

> [duplications in signatures and structures]
>
> Is the practical value of this kludge enough to forget that it's a
> kludge?
>
> Sure.

The solution to put the whole signature into a separate .ml-file requires
hardly any work and solves this problem neatly. Why introduce a kludge
if there are reasonable ways to do it?

> No, at least I cannot.

Do you have examples where the current system is just too awkward to use?

> Also here I would suggest to have a
> solution that works for the common case. What about changing
> include, such that including a signature into a structure
> includes all types and all exceptions?

But you can do this (and I do it regularly) by putting the signature stuff
into a separate module (or .ml-file): then you can "include" things in
your structures to your hearts delight (thanks to the new way of using
"include" with structures).

Regards,
Markus Mottl

Markus Mottl

unread,
Mar 22, 2001, 6:43:00 AM3/22/01
to John Max Skaller, Chris Hecker, caml...@inria.fr
On Mon, 19 Mar 2001, John Max Skaller wrote:
> Yes. More precisely, you cannot forward reference any symbol,
> however you _can_ call forward by passing a function backward as an
> argument.
> [This sucks though]

Note that you can always use local modules + functors so as not having
to pass around functions backwards, e.g.:

module MakeM (Spec : sig val f : int -> int end) = struct
open Spec

let foo x = f x
let bar x y = f x + f y
end

let bla g =
let module Spec = struct let f = g end in
let module M = MakeM (Spec) in
print_int (M.foo 42 + M.bar 1 2)

let _ = bla succ

Put the functions that should be "backwards parameterized" into functor
"MakeM". Then generate its specifcation "Spec" at runtime in some function
"bla" (here: "f" should be some function "g" passed at runtime) and apply
the functor "MakeM" to the specification "Spec". Now you can access the
"backwards parameterized" functions using the qualified module path "M."

If you feel annoyed by the fully qualified path, just write another
local module, in which you can "open" module "M" and provide some "start"
function in this new module to continue execution.

If you want even more hardcore moduling, you might be interested in trying
out the new "include"-keyword for structures (my favourite new language
extension! Thanks!) with the tricks above. You can do tremendous things
with it, like overriding specific functions of modules at runtime, etc.,
with hardly any effort.

The only remaining question here is: how efficiently can OCaml handle
local modules and local functor applications? I haven't measured it,
but I guess that this could be expensive.

Regards,
Markus Mottl

Brian Rogoff

unread,
Mar 22, 2001, 12:00:09 PM3/22/01
to Markus Mottl, Hendrik Tews, OCAML
On Thu, 22 Mar 2001, Markus Mottl wrote:
> Hendrik Tews schrieb am Thursday, den 22. March 2001:
> > I would like to vote for solutions that work for the common case
> > when writing large programs, even if they are hacks, considered
> > from a theoretical point of view.
>
> I am not so fond of sacrificing theoretical beauty: it usually seems
> to be the case that there are working solutions that are also elegant -
> it's only a matter of thinking about them long enough. You might speed
> up development a bit by allowing hacks if you cannot immediately find
> a sound solution, but IMHO it is hardly ever a good idea in the long run.

I agree with this general principle, and to be honest, I haven't found in
my own programming a compelling case where module spanning mutually
recursive function definitions were an issue. Is it possible to produce a
reasonably sized example, Hendrik (or Chris)? I'm annoyed by the inability
to have a mutually recursive *type* definition and functor instantiation,
and that problem can be solved with recursive modules (Claudio Russo says
it works in a development version of Mosml), but I haven't had this
problem with functions yet.

As an aside, Claudio mentioned that it would be easy to extend OCaml to
support this feature: are there any plans to do so? If not, maybe I'll
push for it when the Consortium is set up.

> > Cross module recursion of functions is soo useful, that it
> > should be made to work --- even if the solution seems stupid with
> > respect to the example above.

I agree that the workaround is a tiny bit ugly, but I'm not convinced that
the problem is so great that it justifies any kind of new kludge. Convince
me! My mind is open (or include'ed :)

> Nearly everytime I had thought "now I need recursive modules", I found
> other, even elegant ways to do it.

How about the case I mention above? I think that there are a few cases
where some extensions are necessary, however...

> If we really want them, please let's don't put aside theory but take
> existing clean solutions (e.g. see Claudio Russo's thesis).

Yes. Let's have the extensions be clean, well founded ones. Even some
people in industry realize that this is the right way to go. :-)

I've snipped the module inclusion stuff because I think that while the
need for a workaround is unfortunate, I think that there are bigger fish
to fry.

-- Brian

Brian Rogoff

unread,
Mar 22, 2001, 12:16:46 PM3/22/01
to Judicael Courant, caml...@inria.fr
On Thu, 22 Mar 2001, Judicael Courant wrote:
> Brian Rogoff a écrit :
> >
> [...]
> > What's the problem with the hack I suggested earlier: put the huge vari=
ant
> > (and other duplicated types) in a "pure" .mli file (I hate using .ml fo=
r
> > that) and "open"ing it where you need it, once in the .mli file and onc=
e in the
> > .ml file? This way you reduce the duplication to two lines.
> >
> > I know some people are open-phobes, but I find this use of open to be
> > acceptable.
> >
>
> As for open-phobes, somebody gave me a good solution a few days ago: you
> can locally define a module with a very short name.
>
> Example : put your type in my_beautiful_type.mli with constructors Node,
> Leaf, ..., and where you need it do
>
> module T = My_beautiful_type
>
> then you can use it with a small overhead of 2 chars per use of a
> constructor of My_beautiful_type: T.Node, T.Leaf, ...
>
> This is quite elegant IMHO as it makes your code very clear.

Oh yes, this is the common solution in Ada-land for "use-phobes" (their
analogue of open-phobes :) to long package names. They have it a little
better in that "use" can be in any declarative region so it makes it
easier to find which module things come from. It is possible to do this
in OCaml with the local module feature but I don't see it as much in code=

I've read.

> As an aside, if you consider applying the same treatment for exceptions
> (also duplicated), you need to put them in a .ml file (not a .mli) as a
> .cmo is needed for linking (an exception actually creates at run-time a
> fresh exception identifier).

Excellent point. However, I don't tend to define that many exceptions, far
fewer than the size of variant types (which easily get tens of
constructors even for a single type) so that duplication doesn't bother me
as much as for types. Still, I should perhaps rethink my aversion to using
a ".ml" as the file holding the duplicated info.

This entire discussion has the seeds of a few more FAQ entries. Is our
esteemed erstwhile moderator going to do it, or should I take a stab and
then mail it along?

-- Brian

-------------------
To unsubscribe, mail caml-lis...@inria.fr. Archives: http://caml.inria.fr

Daniel de Rauglaudre

unread,
Mar 22, 2001, 12:15:01 PM3/22/01
to caml...@inria.fr
Hi everybody,

My usual hack for mutually recursive functions in different modules:

File foo.ml:
let g_ref = ref (fun _ -> failwith "Bar.g not yet defined")
let g x = !g_ref x
let f ... = .... g ...

File bar.ml:
let g .... = .... Foo.f ...
Foo.g_ref := g

By extending the language using Camlp4, by the constructions "forward" and
"define_forward" doing the right thing, you could have:

File foo.ml:
forward g
let f ... = .... g ...

File bar.ml:
let g .... = .... Foo.f ...
define_forward g

--
Daniel de RAUGLAUDRE
daniel.de_...@inria.fr
http://cristal.inria.fr/~ddr/

Dave Berry

unread,
Mar 22, 2001, 1:07:51 PM3/22/01
to Hendrik Tews, caml...@inria.fr
To be more general, perhaps specifications could be interleaved with
declarations in modules. In addition to including entire structures,
this would let you specify the type of a function separately from it's
implementation:

val map: ('a -> 'b) -> 'a list -> 'b list
let rec map f l =
match ...

This is one aspect I like about Haskell's syntax. I find it clearer
than the current:

let rec map (f: 'a -> 'b) (l: 'a list) =
match ...

I prefer Hendrik's suggestion of explicitly including a signature to the
earlier suggestion of automatically including types from a signature
constraint. If you automatically include types from a signature
constraint, the signature stops being a constraint, and you might match
signatures that you never intended to.

I assume Hendrik is considering the case where an interface already
exists, and you're writing the implementation. Another case is where
you're writing a module without an explicit interface, but you want to
constrain just some of the external view. Using specifications in the
module itself might help here too:

type coleur = Rouge | Vert | Bleu
(both type and implementation exported)

type animal
type animal = Chien | Chat | Oiseau
(only the type is visible outside the module)

I've no idea how easy or hard it would be to incorporate this into
either the semantics or the implementation of the language. But from a
pragmatic point of view, it seems a relatively clean change.

Dave.


-----Original Message-----
From: Hendrik Tews [mailto:te...@tcs.inf.tu-dresden.de]
Sent: Thursday, March 22, 2001 12:03
To: caml...@inria.fr
Subject: Re: [Caml-list] recursive modules redux, & interface files

What about changing
include, such that including a signature into a structure
includes all types and all exceptions?

-------------------

Manuel Fahndrich

unread,
Mar 22, 2001, 2:17:53 PM3/22/01
to Olivier Andrieu, caml...@inria.fr
Yes, the reason it is needed is to be able to export from a module both
a type sharing constraint, and at the same time the concrete type
representation.

module type I = sig
module M : J

type t = M.s = { foo : int }
end

Such a description gives you two pieces of information. M.s = t and =
also
the representation of this type.

Regards,

Manuel

-----Original Message-----
From: Olivier Andrieu [mailto:and...@oxygene.ijm.jussieu.fr]
Sent: Thursday, March 22, 2001 3:17 AM
To: caml...@inria.fr

Subject: Re: [Caml-list] about typedefs... (was: duplication
implementation/interface)

Judicael Courant [Thursday 22 March 2001] :

> Brian Rogoff a écrit :
> >
> [...]
> > What's the problem with the hack I suggested earlier: put the

> > huge variant (and other duplicated types) in a "pure" .mli file
> > (I hate using .ml for that) and "open"ing it where you need it,
> > once in the .mli file and once in the .ml file? This way you


> > reduce the duplication to two lines.
> >
> > I know some people are open-phobes, but I find this use of open
> > to be acceptable.
> >
>
> As for open-phobes, somebody gave me a good solution a few days
> ago: you can locally define a module with a very short name.

There's something I've been wondering about type definitions :

In type definitions, you can specify type equation and representation.
- when none is specified, the defined type is abstract ;
- when an equation is given, you get an alias of an already existing
type ;
- with a representation, a new variant or record is defined.

But it is possible to use both, so that you get an alias of an already
defined variant and record but with the fields or constructors attached

to
the new type.

It don't really see the point of such a definition : now the type
representation is in 4 different places, and the only gain I see is
that you don't have to prefix the fields names with a module
path. That's no big deal since you can redefine the module with a short
name (one letter).

So, is this form of type definitions actually used, does it have another
purpose besides this namespace issue ?

Olivier

Tom Hirschowitz

unread,
Mar 23, 2001, 3:11:58 AM3/23/01
to Dave Berry, caml...@inria.fr
> I prefer Hendrik's suggestion of explicitly including a signature to th=

e
> earlier suggestion of automatically including types from a signature
> constraint. If you automatically include types from a signature
> constraint, the signature stops being a constraint, and you might match=

> signatures that you never intended to.

> I assume Hendrik is considering the case where an interface already

> exists, and you're writing the implementation. =


Just curious, but how would you treat this?

module type TEN = =

sig =

module PLAYER : sig type t = Andre | Pete | Ivan | Cedric val name =
:
t -> string end
exception Not_Ex_No1 of PLAYER.t
type u = PLAYER.t -> PLAYER.t
end

module Ten = =

struct =

includesig TEN
...
end

Reject?

Friendly, =


Tom

Dave Berry a écrit :
> =

> To be more general, perhaps specifications could be interleaved with
> declarations in modules. In addition to including entire structures,
> this would let you specify the type of a function separately from it's
> implementation:

> =

> val map: ('a -> 'b) -> 'a list -> 'b list
> let rec map f l =
> match ...

> =

> This is one aspect I like about Haskell's syntax. I find it clearer
> than the current:

> =

> let rec map (f: 'a -> 'b) (l: 'a list) =
> match ...

> =

> =

> type coleur = Rouge | Vert | Bleu
> (both type and implementation exported)

> =

> type animal
> type animal = Chien | Chat | Oiseau
> (only the type is visible outside the module)

> =

> I've no idea how easy or hard it would be to incorporate this into

> either the semantics or the implementation of the language. But from a=

> pragmatic point of view, it seems a relatively clean change.

> =

> Dave.
> =

> -----Original Message-----
> From: Hendrik Tews [mailto:te...@tcs.inf.tu-dresden.de]
> Sent: Thursday, March 22, 2001 12:03
> To: caml...@inria.fr
> Subject: Re: [Caml-list] recursive modules redux, & interface files
> =

> What about changing
> include, such that including a signature into a structure
> includes all types and all exceptions?

> =

> -------------------
> To unsubscribe, mail caml-lis...@inria.fr. Archives: http://caml=
.inria.fr

Fabrice Le Fessant

unread,
Mar 23, 2001, 7:21:00 AM3/23/01
to Tom.Hir...@inria.fr, Dave Berry, caml...@inria.fr

Why don't you use classes ? You can define classes with "virtual"
methods for the functions you will not define immediatly, and then
define them in another module. Later, you can create a class which
inherit from both classes, thus binding correctly all variables.

Isn't "late binding" the only interest of objects ? :)

Of course, this only works for functions. For types, you should use
a separate module. Some time ago, I wrote a patch to ocaml to allow
C-like linking under some conditions. I can update it to 3.01 if you
are interested.

- Fabrice

Dave Berry

unread,
Mar 23, 2001, 9:39:38 AM3/23/01
to Tom.Hir...@inria.fr, caml...@inria.fr
I'd say that the module Ten would have to include a declaration of the
sub-module PLAYER.

To be honest, I don't know whether there are counter-examples to the
suggestion. It may be unsound or impractical. I was just following a
single line of thought; I'm sure the idea would require lots more work
before it could be adopted, or it might not work at all.


-----Original Message-----
From: Tom Hirschowitz [mailto:Tom.Hir...@inria.fr]
Sent: Friday, March 23, 2001 7:55
To: Dave Berry; caml...@inria.fr
Subject: Re: [Caml-list] recursive modules redux, & interface files

Just curious, but how would you treat this?

module type TEN =
sig

module PLAYER : sig type t = Andre | Pete | Ivan | Cedric val name =
:
t -> string end
exception Not_Ex_No1 of PLAYER.t
type u = PLAYER.t -> PLAYER.t
end

module Ten =
struct
includesig TEN
...
end

Reject?

Friendly,

Tom

Dave Berry a écrit :
>

> To be more general, perhaps specifications could be interleaved with
> declarations in modules. In addition to including entire structures,
> this would let you specify the type of a function separately from it's
> implementation:
>

> val map: ('a -> 'b) -> 'a list -> 'b list
> let rec map f l =
> match ...
>

> This is one aspect I like about Haskell's syntax. I find it clearer
> than the current:
>

> let rec map (f: 'a -> 'b) (l: 'a list) =
> match ...
>
>

> type coleur = Rouge | Vert | Bleu
> (both type and implementation exported)
>

> type animal
> type animal = Chien | Chat | Oiseau
> (only the type is visible outside the module)
>

> I've no idea how easy or hard it would be to incorporate this into
> either the semantics or the implementation of the language. But from
a

> pragmatic point of view, it seems a relatively clean change.
>

> Dave.


>
> -----Original Message-----
> From: Hendrik Tews [mailto:te...@tcs.inf.tu-dresden.de]
> Sent: Thursday, March 22, 2001 12:03
> To: caml...@inria.fr
> Subject: Re: [Caml-list] recursive modules redux, & interface files
>

> What about changing
> include, such that including a signature into a structure
> includes all types and all exceptions?
>

Fergus Henderson

unread,
Mar 23, 2001, 12:32:36 PM3/23/01
to Brian Rogoff, Markus Mottl, Hendrik Tews, OCAML
On 22-Mar-2001, Brian Rogoff <b...@best.com> wrote:
>
> I haven't found in
> my own programming a compelling case where module spanning mutually
> recursive function definitions were an issue. Is it possible to produce a
> reasonably sized example, Hendrik (or Chris)?

In the Mercury compiler, we have made significant use of module spanning
mutually recursive procedures. For example, the code generator
is split among several modules, roughly for each language construct
(e.g. ite_gen handles code generation for if-then-elses,
switch_gen handles code generation for switches, etc.),
and since if-then-elses can contain switches (and vice versa),
the procedures in these modules are mutually recursive.

--
Fergus Henderson <f...@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.

Brian Rogoff

unread,
Mar 23, 2001, 1:06:36 PM3/23/01
to Fergus Henderson, Markus Mottl, Hendrik Tews, OCAML
On Sat, 24 Mar 2001, Fergus Henderson wrote:
> On 22-Mar-2001, Brian Rogoff <b...@best.com> wrote:
> > I haven't found in
> > my own programming a compelling case where module spanning mutually
> > recursive function definitions were an issue. Is it possible to produce a
> > reasonably sized example, Hendrik (or Chris)?
>
> In the Mercury compiler, we have made significant use of module spanning
> mutually recursive procedures. For example, the code generator
> is split among several modules, roughly for each language construct
> (e.g. ite_gen handles code generation for if-then-elses,
> switch_gen handles code generation for switches, etc.),
> and since if-then-elses can contain switches (and vice versa),
> the procedures in these modules are mutually recursive.

Interesting. A similar example occurred in a discussion in comp.lang.ml
between Matthias Blume and Greg Morrissett (concerning datatypes not
functions) where MB argued as an SML/NJ maintainer that such recurrences
were best placed in the same module and GM thought it best that they be
split even though recursive. Clearly I lean towards MB's view on this
though I take it that there are other schools of thought.

What is your criteria for splitting the functions into different modules?

-- Brian

Mattias Waldau

unread,
Mar 23, 2001, 3:37:38 PM3/23/01
to OCAML
Something we should think about also for Ocaml

http://www.jelovic.com/articles/why_people_arent_using_haskell.htm

"What can be done about this? First and foremost the Haskell community must
make a standard distribution of Haskell that contains enough libraries to be
useful. That should include a regular expression library, an Internet
protocol library, a library for dealing with standard internet data and
encoding, a crypto library, a multimedia library and a GUI library.

Next, the Haskell community must step out of its research circles and start
publicizing Haskell to the practicing programmers. Write articles in DDJ and
similar publications. Publish real-world programs written in Haskell."

Most of this is also relevant for Ocaml, for example there are
crypto libraries and XML-support (for example PXP, which require wlex, which
is a hazzle).

I stumbled over Ocaml, thanks to Mercury and ICFP-contest.

/mattias

Don Syme

unread,
Mar 23, 2001, 5:52:57 PM3/23/01
to Xavier Leroy, Chris Hecker, caml...@inria.fr
> A possible approach for Caml would be to have a link-time analysis
> that detects cross-module value recursions that involve only function
> definitions, and allow these (because they are safe -- like in C!).
> Fabrice Le Fessant posted a patch to OCaml a while ago that does
> pretty much this. I'm still hoping more general, principled solutions
> exist, but they sure are hard to design!


Isn't it feasible to annotate elements of signatures with something that
indicates that an identifier really is bound to a value, rather than a
module?? i.e.

foo.mli:

value f : int -> int (* must be bound to a lambda expression or an
identifier in foo.ml *)
value x : int list (* must be bound to a cons-cell or an identifier
in foo.ml *)
expr g : int -> int (* may be a computation *)

(The current "val" would be interpreted as "expr". "value" could also be
replaced by "const" or "val rec" or "rec" or whatever)

I know this is revealing part of how foo.mli is implemented, but that is
really the point: allow the programmer to reveal more when necessary to
prove that things are safe. I guess you'd have to generalize this to
functors, etc., (the subsumption relation between signatures would allow
"values" to be used as "expressions", but not vice-versa).

Hasn't there been some work done one such "phase distinction" rules?
Was that by Harper et al.?

However, this would not solve the problem:

A.mli val x : int B.mli val y : int

A.ml let x = B.y B.ml let y = A.x

Perhaps disallowing identifiers on the r.h.s. (as in "let rec") is the
right thing to do, even if a bit of pain when just rebinding function
values.

Cheers,
Don

Arturo Borquez

unread,
Mar 23, 2001, 10:20:48 PM3/23/01
to mattias...@abc.se, caml...@inria.fr
On Fri, 23 March 2001, "Mattias Waldau" wrote:

>
> Something we should think about also for Ocaml
>
> http://www.jelovic.com/articles/why_people_arent_using_haskell.htm
>
> "What can be done about this? First and foremost the Haskell community must
> make a standard distribution of Haskell that contains enough libraries to be
> useful. That should include a regular expression library, an Internet
> protocol library, a library for dealing with standard internet data and
> encoding, a crypto library, a multimedia library and a GUI library.
>
> Next, the Haskell community must step out of its research circles and start
> publicizing Haskell to the practicing programmers. Write articles in DDJ and
> similar publications. Publish real-world programs written in Haskell."
>
> Most of this is also relevant for Ocaml, for example there are
> crypto libraries and XML-support (for example PXP, which require wlex, which
> is a hazzle).
>

Hi Mattias:
As I am part of the 'real world programmers' from the begining I have being trying to put OCaml to work in trivial but 'real world apps' with great success. I must recognize that I am not so skilled in the language to participate in the theoric-forum, but yet I have coded some apps (server services) to my company to show the reliability of OCaml, and we are all agree that is a great language. But a great language to be successful and honour the great effort done by the authors must be promoted actively outside the research environment. I believe that lots of programmers not use OCaml because they are unaware about its existence. How to do it? The strategy and decision is to be made by INRIA and/or Caml Consortuim. Personaly I would like to see OCaml world wide spreaded playing in the 'great leages'.


Find the best deals on the web at AltaVista Shopping!
http://www.shopping.altavista.com

Vijay Chakravarthy

unread,
Mar 24, 2001, 2:59:49 AM3/24/01
to mattias...@abc.se, Arturo Borquez, caml...@inria.fr
We are also trying to use Ocaml out here, mainly for prototyping purposes
(at least thats the way I'll introduce it to the rest of the org.)
Once they find that rewriting the prototypes in java takes 10 times the
effort.....
The main difficulties we have faced have been --
a) Education - Out here even for people skilled in scheme and some other
functional languages, it is challenging to learn ocaml. My
team found it easier to learn erlang, for example. However, people love the
strong type checking, and the fact that if it compiles its
likely to run correctly... The english translation of the horse book should
help.
b) As I mentioned in a previous message, support for Windows is weak. Many
of us use Linux for development, but our sales team,
which would show off the demos and prototypes, has windows laptops.
Therefore the need to show off web apps on windows.
Difficulties in building important packages (like pxp) on windows, plus the
need to write even simple things like web servers, and
database interfaces etc is a painful situation. With some difficulty we
could compile many of the packages, but its not as smooth
as it should be. Also fork based web server/services (such as in the geneweb
distribution) will not work on windows. A select based
single threaded web server would be really useful (By web server I am not
referring necessarily to a full fledged web server, but rather
services that are accessible through a http interface)
c) Package availability is fragmented. I have a good idea of various
packages etc, but to a newcomer, there is no single place to
track down code examples. Plus larger packages like Ensemble, Geneweb etc
contain modules that would be useful in general, but
that is visible only when one peruses the source code of such packages.

On the other hand, the language and the libraries are excellent. Plus
functional programming languages are IDEAL for the type
of work we do, which is in the enterprise software space. Things like bills
of materials, available to promise engines etc are quite
entertaining to deal with in the context of functional languages, and
especially ocaml.

Vijay

BTW, I dont know if this is the right place for this, but are there any
people interested in ocaml programming out here in the
San Francisco area? Or alternatively, if there are people on this list
skilled in ocaml and interested in some sort of remote contract
programming arrangement, please send me email.

Brian Rogoff

unread,
Mar 24, 2001, 1:44:09 PM3/24/01
to Vijay Chakravarthy, mattias...@abc.se, Arturo Borquez, caml...@inria.fr
On Sat, 24 Mar 2001, Vijay Chakravarthy wrote:
> We are also trying to use Ocaml out here, mainly for prototyping purposes
> (at least thats the way I'll introduce it to the rest of the org.)
> Once they find that rewriting the prototypes in java takes 10 times the
> effort.....

And runs at one tenth the speed :-). I laughed at this since one of my
Caml-hating colleagues recently suggested to my manager (who reads
this list :) that we rewrite some Java code in a low level language like C
or OCaml (!) for speed.

> The main difficulties we have faced have been --
> a) Education - Out here even for people skilled in scheme and some other
> functional languages, it is challenging to learn ocaml.

What have the issues been? I hate to mention this again (and again, ...) but
I find that beginners and non-experts stumble over syntax a lot. Now, it is
clear that Daniel De Rauglaudre is too shy and modest to mention his Revised
syntax available with CamlP4. If your people have syntax problems (they do
go away with familiarity IME) then check it out.

> My team found it easier to learn erlang, for example. However, people
> love the strong type checking, and the fact that if it compiles its
> likely to run correctly... The english translation of the horse book should
> help.

Yes, how is that coming? I hope that ugly horse can get replaced by a
beautiful dromedary.

> b) As I mentioned in a previous message, support for Windows is weak. Many

This might be the kind of thing that the Consortium can help with. If
enough members want Windows they can kick in for an extensive thin binding
to Windows services.

> c) Package availability is fragmented. I have a good idea of various
> packages etc, but to a newcomer, there is no single place to
> track down code examples. Plus larger packages like Ensemble, Geneweb etc
> contain modules that would be useful in general, but
> that is visible only when one peruses the source code of such packages.

Two issues there. First is that some tool like findlib or the Python distutils
should be part of the toolset. Second is that a big library structure like
the SML Basis library would be helpful.

> On the other hand, the language and the libraries are excellent.

Agreed.

> Plus functional programming languages are IDEAL for the type
> of work we do, which is in the enterprise software space.

I would have said that it's ideal for VLSI design software (any other EDA
hackers out there?) so maybe it's just ideal for everything?

> BTW, I dont know if this is the right place for this, but are there any
> people interested in ocaml programming out here in the
> San Francisco area?

Santa Clara (which hasn't had any blackouts!) area but there was an
attempt at a NoCal OCaml users meeting. Maybe the participants can tell
you how it went. It's great to hear that the number of industrial OCaml
programmers is growing!

-- Brian

Vijay Chakravarthy

unread,
Mar 24, 2001, 4:51:23 PM3/24/01
to Brian Rogoff, mattias...@abc.se, Arturo Borquez, caml...@inria.fr

----- Original Message -----
From: "Brian Rogoff" <b...@best.com>
To: "Vijay Chakravarthy" <vchakr...@verticalnet.com>
Cc: <mattias...@abc.se>; "Arturo Borquez" <abor...@altavista.com>;
<caml...@inria.fr>
Sent: Saturday, March 24, 2001 10:38 AM
Subject: Re: [Caml-list] Why People Aren't Using OCAML? (was Haskell)

> On Sat, 24 Mar 2001, Vijay Chakravarthy wrote:
> > We are also trying to use Ocaml out here, mainly for prototyping
purposes
> > (at least thats the way I'll introduce it to the rest of the org.)
> > Once they find that rewriting the prototypes in java takes 10 times the
> > effort.....
>
> And runs at one tenth the speed :-). I laughed at this since one of my
> Caml-hating colleagues recently suggested to my manager (who reads
> this list :) that we rewrite some Java code in a low level language like C
> or OCaml (!) for speed.
>
> > The main difficulties we have faced have been --
> > a) Education - Out here even for people skilled in scheme and some other
> > functional languages, it is challenging to learn ocaml.
>
> What have the issues been? I hate to mention this again (and again, ...)
but
> I find that beginners and non-experts stumble over syntax a lot. Now, it
is
> clear that Daniel De Rauglaudre is too shy and modest to mention his
Revised
> syntax available with CamlP4. If your people have syntax problems (they do
> go away with familiarity IME) then check it out.
>

I personally dont have problems with the syntax, but I have found that
people take a little bit of time
getting used to the syntax. The simplest way to fix this is not CamlP4
(IMHO), but rather to provide a
lot of examples showing people how to do things they would commonly do. The
three liner Markus posted
in c.l.f for an echo server, for example, helps get buy-in when trying to
convince people this is a cool language,
and that happens primarily through the use of examples. I also understand
that there are a lot of examples
scattered around, but it would be nice to collect all of them in an easy to
look at manner. I believe that
Fredrick Lundh's python ematter book is a good role model in this area.


> > My team found it easier to learn erlang, for example. However, people
> > love the strong type checking, and the fact that if it compiles its
> > likely to run correctly... The english translation of the horse book
should
> > help.
>
> Yes, how is that coming? I hope that ugly horse can get replaced by a
> beautiful dromedary.
>
> > b) As I mentioned in a previous message, support for Windows is weak.
Many
>
> This might be the kind of thing that the Consortium can help with. If
> enough members want Windows they can kick in for an extensive thin binding
> to Windows services.
>

Its not that we need binding to Windows services. All that is required is
that the various packages
are as easy to make and use on windows (without installing cygwin). This is
mostly true, except for
some critical packages like findlib, dbm, etc. A dbm interface on windows to
Sleepycats berkeley db
would be great.


> > c) Package availability is fragmented. I have a good idea of various
> > packages etc, but to a newcomer, there is no single place to
> > track down code examples. Plus larger packages like Ensemble, Geneweb
etc
> > contain modules that would be useful in general, but
> > that is visible only when one peruses the source code of such packages.
>
> Two issues there. First is that some tool like findlib or the Python
distutils
> should be part of the toolset. Second is that a big library structure like
> the SML Basis library would be helpful.
>
> > On the other hand, the language and the libraries are excellent.
>
> Agreed.
>
> > Plus functional programming languages are IDEAL for the type
> > of work we do, which is in the enterprise software space.
>
> I would have said that it's ideal for VLSI design software (any other EDA
> hackers out there?) so maybe it's just ideal for everything?
>
> > BTW, I dont know if this is the right place for this, but are there any
> > people interested in ocaml programming out here in the
> > San Francisco area?
>
> Santa Clara (which hasn't had any blackouts!) area but there was an
> attempt at a NoCal OCaml users meeting. Maybe the participants can tell
> you how it went. It's great to hear that the number of industrial OCaml
> programmers is growing!
>
> -- Brian

Actually, we have two offices, one in SFO, the other in Palo Alto (right
next to Xerox Parc).

Vijay

Dennis Gang Chen

unread,
Mar 25, 2001, 7:44:54 PM3/25/01
to Brian Rogoff, caml...@inria.fr

> I would have said that it's ideal for VLSI design software (any other EDA
> hackers out there?) so maybe it's just ideal for everything?

I would like to hear more about using ocaml in VLSI design and
verification. For simulation and formal verification of chips, speed is crucial.

Cheers.

--
==================================================================
-- Dennis Gang Chen
-- Senior Software Engineer, CAD Tools
-- EDA Solutions and Products Strategic
-- Global Software Group (GSG)
--
-- email: Dennis...@motorola.com
-- office: +61-8-8203 3560 fax: +61-8-8203 3501
-- addr: 2, Second Avenue, Mawson Lakes, Adelaide, 5095. Australia
==================================================================

Fergus Henderson

unread,
Mar 25, 2001, 9:38:20 PM3/25/01
to Brian Rogoff, OCAML

Our criteria are pretty informal: each module should consist of closely
related code, preferably with a single purpose that can be summed up
in a concise title, e.g. "code generation for if-then-elses".

In this case, I think the code was originally in a single module,
but was split into sub-modules when it became too large.
Here's the line counts of the relevant modules:

768 call_gen.m
1296 code_gen.m
67 commit_gen.m
324 disj_gen.m
360 ite_gen.m
283 par_conj_gen.m
1254 pragma_c_gen.m
313 switch_gen.m
897 unify_gen.m
245 dense_switch.m
549 lookup_switch.m
246 string_switch.m
1100 tag_switch.m
584 middle_rec.m
----
8286

Generally we prefer to make modules in the range of about 200-2000
lines of code each. If a module gets much larger than that, then
it tends to get a bit unwieldy, and recompilation times start to become
inconvenient, so we prefer to split up modules that get larger than that.
8000 lines is definitely way too big.

--
Fergus Henderson <f...@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.

Brian Rogoff

unread,
Mar 25, 2001, 10:09:05 PM3/25/01
to Dennis Gang Chen, caml...@inria.fr
On Mon, 26 Mar 2001, Dennis Gang Chen wrote:
> > I would have said that it's ideal for VLSI design software (any other EDA
> > hackers out there?) so maybe it's just ideal for everything?
>
> I would like to hear more about using ocaml in VLSI design and
> verification. For simulation and formal verification of chips, speed is crucial.

Well, I work in the subfield called VLSI Physical Design, so simulation
here means SPICE, and the verification isn't formal. However, I do have
a little bit of experience in the whole ASIC/RTL and behavioral modeling
so I'll toss in my two cents.

People write simulation models in all kinds of languages, including Perl
and Java, so speed is not always of the essence. For those cases where it
is, people often write in C (I worked at Denali for a while and I wrote
some of their models) since Verilog and VHDL simulators sometimes aren't
quite good enough. Where would OCaml fit in there? Well, I've often
thought that the FFTW approach of just spitting out optimized C would be
workable, and since most people acknowledge that MLs are really good for
writing compilers, how about a Verilog (or VHDL if you're European :) RTL
to C compiler? I had started on a Verilog front end for other reasons but
since migrating to physical design it's not as important. Incidentally, in
the ASIC flows I've worked on a Verilog front end would have *lots* of
uses, flattening hierarchy, scan chain insertion, etc. Anyone interested
in working on such a tool?

For formal verification I suspect you're asking about fast BDDs, a topic
that has come up a few times on this list. I suspect that for very
demanding problems you'll want the BDD library in C so as to minimize the
overhead. I'd be delighted to find that a "pure OCaml" BDD library was
competitive to a well optimized C one, but I doubt that will be true. In
any case, you can just link with one of the available C libraries. I'm
surprised that no one has made a publically available binding to Cudd or
some other C library. Maybe I'll do that one day if someone else doesn't
beat me to it. Once you have such a library available, I think that other
tools (say a symbolic model checking tool) could be coded up far more
easily in OCaml than in many other languages, and the performance
bottleneck will have been addressed.

From the physical design standpoint, I just find it easier to express
complex algorithms in ML than other languages I've used, for all the
old reasons. I suppose for things like linear programming OCaml isn't
(yet :) ideal but the problems I work on are not huge, think leaf cell
synthesis scale rather than whole chip (for now!).

Anyways Dennis, if you're interested in pursuing any of those things I
mention, please contact me. One constraint is that I'd like to make source
available so that other EDA people get sucked into the OCaml vortex. There
are too many in-house point tools that die because they never get out. I've
noticed quite a few postings from people in the industry (I post from my
ISP but I work at Artisan) so I know there are some more of us out there.
Come on guys, do you want to hack on Perl for the rest of your careers?
Let's make OCaml the EDA language of choice!

-- Brian

Christophe Raffalli

unread,
Mar 26, 2001, 5:06:07 AM3/26/01
to caml...@inria.fr

I read a french revue called login which regularly publish series of art=
icle
introducing a new language (like Rebol at the moment). Someone at INRIA c=
ould
contact them (or other journal). Surely this would spread OCaml in the
programming community ?

The same could be done in other country ?

--
Christophe Raffalli
Université de Savoie
Batiment Le Chablais, bureau 21
73376 Le Bourget-du-Lac Cedex

tél: (33) 4 79 75 81 03
fax: (33) 4 79 75 87 42
mail: Christoph...@univ-savoie.fr
www: http://www.lama.univ-savoie.fr/~RAFFALLI
-------------------
To unsubscribe, mail caml-lis...@inria.fr. Archives: http://caml.i=
nria.fr

David Mentre

unread,
Mar 26, 2001, 5:07:28 AM3/26/01
to Brian Rogoff, Dennis Gang Chen, caml...@inria.fr, Thomas.C...@irisa.fr
Brian Rogoff <b...@best.com> writes:

> I'm surprised that no one has made a publically available binding to
> Cudd or some other C library.

While not put yet on a web site, Thomas Colcombet and myself have made a
binding for CMU bddlib. If you want (or anybody else) this code, please
just ask us.

Maybe should we put it on a web site. Thomas?

BTW, what is this Cudd library? Is it available under GPL or BSD like
license?

There is also a bdd module in caml-light (found in the Hump):
ftp://ftp.lri.fr/LRI/soft/archi/Softwares/8,5/robdd.tar.gz


Best regards,
d.
--
David....@inria.fr -- http://www.irisa.fr/prive/dmentre/
Opinions expressed here are only mine.

Xavier Leroy

unread,
Mar 26, 2001, 7:46:48 AM3/26/01
to Christophe Raffalli, caml...@inria.fr
I must confess some irritation, mixed with amusement, towards this
Jelovic op-ed piece and similar well-meaning but basically clueless
piece of advice that flourishes on the Web, on Usenet, and in computer
magazines. It's basically "motherhood and apple pie" advice:
brush your teeth after every meal; have lots of libraries;
say "please" and "thank you"; make self-contained distros; do your
homework well before the due date; write a DDJ paper; etc. Yeah,
sure; tell me something I didn't know.

The Jelovic piece is particularly clueless, e.g. it talks about
"an Internet protocol library" (what is "the Internet protocol"?
TCP/IP sockets? which one of the thousand protocols that run the Internet?)
and "a library for dealing with standard internet data and encoding"
(pray define "standard internet data" -- streams of bytes?).

Notice also the .htm extension, the <lastname>.com vanity domain, and
the other pieces present on his Web site (e.g. "Some Facts About
Exercice", and "People One Can Learn From", containing names of people
I don't see what one can learn from except that one can make a
living writing boring C++ columns in computer rags), and my built-in
bogometer hits 100%.

OK, now that I've left off some steam, let's come back to Christophe's
comment:

> I read a french revue called login which regularly publish series of article
> introducing a new language (like Rebol at the moment). Someone at INRIA could


> contact them (or other journal). Surely this would spread OCaml in the
> programming community ?
> The same could be done in other country ?

Sure. Great idea. DDJ, Login:, WSJ, USA Today, The Sun, Le Parisien, Il
Corriere della Sera, Cambio 16, it doesn't matter -- the more
articles, the better. Do I take it that you're volunteering writing
something for Login: ? Excellent! Thanks a lot!

I'm not just joking: anyone is most welcome to write some Caml
introductory material for their favorite magazine or Webzine
(Freshmeat, Linux News, Slashdot, etc). That's actually an excellent
way to contribute to the Caml effort.

But don't expect "someone at INRIA" to do this for you. The
"someones at INRIA" have already plenty of things to do, thank you,
such as maintaining and developing Caml. The little time they have
left for writing, they put into dry and boring academic papers that
actually have some scientific content and actually count towards their
academic career. Besides, there are so many publication outlets, each
with so few potentially interested readers, that a highly parallel
effort is the only way to go.

"Ask not what your country can do for you..."

- Xavier "JFK" Leroy

-------------------
To unsubscribe, mail caml-lis...@inria.fr. Archives: http://caml.inria.fr

Brian Rogoff

unread,
Mar 26, 2001, 10:47:41 AM3/26/01
to David Mentre, Dennis Gang Chen, caml...@inria.fr, Thomas.C...@irisa.fr
Hi David,
Cudd or CUDD I think stands for the "Colorado University Decision
Diagram" package. It supports BDDs (or ROBDDs if you want to be that way)
ADDs, and zero suppressed BDDs. It was written by Fabio Somenzi at
Colorado U. You can find it here

http://vlsi.Colorado.EDU/~fabio/

Yes, sure I'd like your binding, and please make it web available.

Here's a snippet from the cudd.h file concerning copyright

Copyright [This file was created at the University of Colorado at
Boulder. The University of Colorado at Boulder makes no warranty
about the suitability of this software for any purpose. It is
presented on an AS IS basis.]

I'm not a lawyer, and I don't play one on the Internet, so perhaps a
mail to Dr. Somenzi for clarification is in order. (PS: please don't reply
to the list guessing what this copyright means if you are not a lawyer
familiar with this aspect of US and international law :-|)

-- Brian

David Gurr

unread,
Mar 26, 2001, 6:14:02 PM3/26/01
to Xavier...@inria.fr, caml...@inria.fr

> From: Xavier Leroy <Xavier...@inria.fr>

>
> I must confess some irritation, mixed with amusement, towards this
> Jelovic op-ed piece and similar well-meaning but basically clueless
> piece of advice that flourishes on the Web, on Usenet, and in computer
> magazines.

My summary of this type of advice is "Make the easy easier and
make the hard harder". If you want to turn Ocaml into the next
visual basic, it is excellent advice. If you want to turn
Ocaml into the next Ocaml, then I think it is best that you
and the "someones at INRIA" keep doing what you all have been doing.
I vote for the latter.

-David Gurr

PS I do appreciate the "dry and boring academic papers".

Chris Hecker

unread,
Mar 26, 2001, 10:47:28 PM3/26/01
to Vijay Chakravarthy, mattias...@abc.se, Arturo Borquez, caml...@inria.fr

I just gave a talk at the Game Developers Conference (www.gdconf.com) on "modern" language features, most of which are associated with functional programming (although the misnomer "modern" is a little odd, since they're almost all in Lisp, and ML's 20 years old :). I don't have the feedback forms on the talk yet, so I don't know how useful people found it, but it filled up completely and they were turning people away, which for a 9am talk at a game conference strongly implies people are interested in alternative languages!

I'll put the slides up on my website soon, although I doubt anybody on this list will learn anything from them. OCaml has all the features I talked about except 1) introspection/reflection and 2) template-style generics (as opposed to polymorphism-style generics).

>BTW, I dont know if this is the right place for this, but are there any
>people interested in ocaml programming out here in the
>San Francisco area?

I'm still planning on organizing the Bay Area OCaml Users Group, or at least a big dinner for anyone who's interested. I'll add your name to the list. Anybody else in the San Francisco Bay Area, USA, who isn't on my list mail me privately.

Chris

Hendrik Tews

unread,
Mar 27, 2001, 3:23:16 AM3/27/01
to OCAML
Hi,

Markus Mottl writes:
From: Markus Mottl <mo...@miss.wu-wien.ac.at>
Date: Thu, 22 Mar 2001 14:01:57 +0100


Subject: Re: [Caml-list] recursive modules redux, & interface files

Hendrik Tews schrieb am Thursday, den 22. March 2001:
> I would like to vote for solutions that work for the common case
> when writing large programs, even if they are hacks, considered
> from a theoretical point of view.

I am not so fond of sacrificing theoretical beauty: it usually seems
to be the case that there are working solutions that are also elegant -
it's only a matter of thinking about them long enough. You might speed
up development a bit by allowing hacks if you cannot immediately find
a sound solution, but IMHO it is hardly ever a good idea in the long run.

[As an aside: In principle I do not agree that usually there
exist elegant solutions. This would imply that for most problems
there are elegant solutions, whereas the attribute elegant can
only apply to a small subset of all solutions (unless everything
is elegant).
]

But for the main problem of mutual recursion: I would also
appreciate a theoretically nice solution. But ocaml and its
predecessors have been around now for long time, so it seems that
it is not that easy to find a good solution for mutal recursion
between modules. So instead of waiting another three years I
would prefer a solution now, even if it is intermediate and not
so clean.

If there is a problem with expressiveness or
else, it seems to be better to first try harder to find a solution with
the existing system before crying for a hacky extension. And if this
doesn't work, let's try to find a more expressive theory rather than
abandoning theory completely.

I agree, don't let's abandoning theory. But let's make a few
compromises, where a good solution is not available in the near
future.

Nearly everytime I had thought "now I need recursive modules", I found
other, even elegant ways to do it.

I know, with some effort you can put every system in a linear
structure and avoid module spanning recursion. But I do not want
to restructure the whole project, only because I need some
recursive functions. The more important point is that in a
project with several people the overall complexity of the system
structure must stay below a certain limit. If you create a system
structure that is above this limit, then the project will fail.


> [duplications in signatures and structures]

The solution to put the whole signature into a separate .ml-file requires
hardly any work and solves this problem neatly. Why introduce a kludge
if there are reasonable ways to do it?

I have the same argument here. Keeping three files instead of two
is more complex. As a programmer you have to pay for this
complexity and it doesn't buy you anything. The result is that
people do not write interfaces because they do not like the
additional effort it requires.


Bye,

Hendrik

Hendrik Tews

unread,
Mar 27, 2001, 3:51:10 AM3/27/01
to caml...@inria.fr
Hi,

Tom Hirschowitz writes:
Date: Fri, 23 Mar 2001 08:54:43 +0100


Subject: Re: [Caml-list] recursive modules redux, & interface files

Just curious, but how would you treat this?

module type TEN =

sig

module PLAYER : sig
type t = Andre | Pete | Ivan | Cedric

val name : t -> string

end
exception Not_Ex_No1 of PLAYER.t
type u = PLAYER.t -> PLAYER.t
end

module Ten =

struct

includesig TEN
...
end

Reject?

Probably. I think we need a solution for the case where a big
variant type is defined in an .ml file and is exported in the
associated .mli file.

The module language of ocaml is great. But I know only a few
people that are acquainted with it. If you can built expressions
like the above, then you surely find a way with several functor
applications that avoids any duplications.

Bye,

Hendrik

wes...@ilt.fhg.de

unread,
Mar 27, 2001, 3:59:16 AM3/27/01
to caml...@inria.fr
>
> I just gave a talk at the Game Developers Conference (www.gdconf.com) on "modern" language features, most of which are associated with functional programming (although the misnomer "modern" is a little odd, since they're almost all in Lisp, and ML's 20 ye
> ars old :). I don't have the feedback forms on the talk yet, so I don't know how useful people found it, but it filled up completely and they were turning people away, which for a 9am talk at a game conference strongly implies people are interested in al
> ternative languages!
>
> I'll put the slides up on my website soon, although I doubt anybody on this list will learn anything from them. OCaml has all the features I talked about except 1) introspection/reflection and 2) template-style generics (as opposed to polymorphism-style
> generics).
>

Don't you hope that at least occasionally there will be an OCaml/funtional language
beginner on this list, somebody like me?

The original question was:

Why People Aren't Using OCaml?

I think one reason is that almost all programmers have to deal with C in one way
or the other. That means that C is one of the first languages everybody has to
learn. There has been a campain promoting object oriented programming over
the last decade. The message was: If you want to write good, maintainable
software use an object oriented language. The "natural" choice for C programmers
is then C++ and Java. I guess most programmers don't even have an idea
what functional programming is. And for a programmer who has experience
with C++, Java and say Python there must be some really good reasons to
use any other language than these main stream languages (consider libraries,
IDE's, colleagues etc.).

What I missed when I started to look for alternatives to C++
(I still make silly mistakes that take a lot of time to eliminate),
Java (which I find cumbersome to use, all these cast's) and Python (to slow
for some applications) was a sound comparison of languages that not only
claimed that one can implement programs 10 times faster when using for
example OCaml (or Lisp or Haskell) compared to Java but that also gave
simple examples which a C++, Java programmer is able to comprehend without
having the need to learn OCaml and become experienced in using it.

One reason for me to learn Java and Python have been their huge libraries.
OCaml also has a good library (and a good documentation of it) but there
are quite a lot of things missing compared to Java and Python (please
don't understand this as critique).

Onother problem that I as a OCaml beginner had (and still have) is where
to use ";" and where not and some other problems with the syntax
(why not "if then else endif" instead of having to use "begin end"?). I think
that the hints in the OCaml documentation concerning this problems
could be more extensive to help beginners.

I just began to use OCaml for some small programs. I especially like the
toplevel which together with Emacs and Tuareg makes rapid prototyping
quite easy. But probably I still didn't grasp what the real advantages of
OCaml compared to C++, Java etc. are. So give me and other OCaml
beginners some more help to better understand what makes OCaml
superior compared to these main stream languages.

Rolf


-------------------------------------
Rolf Wester
wes...@ilt.fhg.de

Xavier Leroy

unread,
Mar 27, 2001, 4:02:13 AM3/27/01
to Don Syme, caml...@inria.fr
> Isn't it feasible to annotate elements of signatures with something that
> indicates that an identifier really is bound to a value, rather than a
> module?? i.e.

You probably meant "rather than a result of an arbitrary computation".
Yes, it can be done this way, and I believe such annotations in
signatures are necessary for a full treatment of recursion between
modules (the Holy Grail :-). However, they also pollute signatures
with "implementation details".

For more modest forms of recursion, e.g. cross-recursion between
compilation units, I was hoping this information could be propagated
behind the scene, without cluttering signatures, or just re-inferred and
checked at link-time. This is just a vague idea.

Cheers,

- Xavier Leroy

Don Syme

unread,
Mar 27, 2001, 10:16:51 AM3/27/01
to Xavier Leroy, caml...@inria.fr
> > Isn't it feasible to annotate elements of signatures with
> something that
> > indicates that an identifier really is bound to a value,
> rather than a
> > module?? i.e.
>
> You probably meant "rather than a result of an arbitrary computation".

Yes, sorry.

> Yes, it can be done this way, and I believe such annotations in
> signatures are necessary for a full treatment of recursion between
> modules (the Holy Grail :-). However, they also pollute signatures
> with "implementation details".

I'm not sure this "pollution" is really at that bad, is it? Users
always have the option of _not_ revealing the extra detail, though with
the result
that they can't do cross-module recursion (or at least they don't get a
guarantee
that all the runtime dynamic checks that verify that data is initialized
before use
succeed). And OCaml already have "external" in interfaces, which only
gives
added performance, not extra expressive power. Phase distinction
annotations seem
as least as useful in practice, and a whole lot simpler than the other
techniques
mentioned.... It seems a whole lot better than having users roll their
own "unsafe"
phase distinctions by hacking in "ref" indirections.... And if a
different, better
solution was found later, then, to use my suggested notation, you could
just revert
"value" to mean the same as "expr".

Cheers,
Don

Manuel Fahndrich

unread,
Mar 27, 2001, 12:08:19 PM3/27/01
to caml...@inria.fr
To add more fuel to this interesting conversation, I've recently come
across a nice analogy between recursive modules and the assume-guarantee
rules known from model checking. The assume-guarantee rule in model
checking allows models to be checked relatively independently. In
general, the AG rule takes on the form

AI | B <= BI
A | BI <= AI
------------------- [some side conditions]
A | B <= AI | BI

where A and B are two processes, and we want to check that the parallel
composition A | B conforms to some interface AI | BI. In general, it is
not the case that A <= AI and B <= BI, which would lead to the =
result.
Instead, some amount of information about the interactions between A and
B are needed. This is expressed in the preconditions AI | B <= BI, =
i.e.,
we check that B composed with the interface specification of A (AI)
conforms to BI, and similarly for A.

The side conditions depend on the particular domain being modeled. If
the models are synchronous and asynchronous logic circuits, then the
side conditions express that there cannot be any logical circularities
between module A and B, ie. mutually recursive definitions of wires that
do not involve at least one latch.

Now what does this have to do with recursive modules? May be by now this
is obvious, but let me say it anyway. In the context of recursive
modules, composition is linking, and conformance is interface checking.
If we have two modules A and B that are mutually recursive and we want
to ascribe interfaces AI and BI to these, it may be the case that we
cannot do that independently, that is we can only ascribe these
interfaces, given that we know we will link A with something conforming
to BI and link B with something conforming to AI, ie., we can use the
assume guarantee rule.
The notation AI | B <= BI then simply states that in order to verify
that B has interface BI, we also need to know the interfaces AI of
module A that will be linked with B.

What about the side conditions? It turns out that the side conditions of
an assume guarantee rule for modules is very similar to that of logical
circuits, namely, we cannot have any circular definitions of values that
do not involve a function abstraction (a delay).

module A = struct let (x:int) = B.y end
module B = struct let (y:int) = A.x end

contains such a circular definition, whereas

module A = struct let fx () = B.fy () end
module B = struct let fy () = A.fx () end

Thus the side conditions are concerned with correct initialization. This
is of course not new, Crary and Harper have given sufficient conditions
on recursive module definitions for these properties to be true, and I
suppose Claudio Russo has similar conditions, although I haven't read
his thesis yet.

Regards,

-Manuel Fahndrich

-----Original Message-----
From: Xavier Leroy [mailto:Xavier...@inria.fr]
Sent: Tuesday, March 27, 2001 1:01 AM
To: Don Syme
Cc: caml...@inria.fr
Subject: Re: [Caml-list] recursive modules redux, & interface files

> Isn't it feasible to annotate elements of signatures with something
that
> indicates that an identifier really is bound to a value, rather than a
> module?? i.e.

You probably meant "rather than a result of an arbitrary computation".

Yes, it can be done this way, and I believe such annotations in
signatures are necessary for a full treatment of recursion between
modules (the Holy Grail :-). However, they also pollute signatures
with "implementation details".

For more modest forms of recursion, e.g. cross-recursion between


compilation units, I was hoping this information could be propagated
behind the scene, without cluttering signatures, or just re-inferred and
checked at link-time. This is just a vague idea.

Cheers,

- Xavier Leroy

Brian Rogoff

unread,
Mar 27, 2001, 11:31:48 PM3/27/01
to John Max Skaller, caml...@inria.fr
On Wed, 28 Mar 2001, John Max Skaller wrote:
> Brian Rogoff wrote:
> > I agree with this general principle, and to be honest, I haven't found in

> > my own programming a compelling case where module spanning mutually
> > recursive function definitions were an issue. Is it possible to produce a
> > reasonably sized example, Hendrik (or Chris)?
>
> I have such an example. In the Vyper interpreter, there is a
> very large module which handles execution of ASTs, which contains
> almost all the interpretive code. It was not possible to break this
> module into further pieces because of the mutual recursion.

This seems simialr to Fergus Henderson's example in the Mercury compiler.
I thought his rationale was convincing (the file just got too big) and
I assume he and you considered various refactorings to keep from splitting
the module and decided against them. So even though there's practically no
better example of functions that belong in the same module as mutually
recursive ones, pragmatics suggests that you split them. None of the
compiler like programs I've worked on have become that big yet.

> [I actually _did_ do this, then undid it, because of the excessive
> number of extra arguments that had to be passed to make it work]

Yes, that can be a problem with the trick/hack of passing extra arguments.
Did you consider the trick Daniel showed using function references which
get initialized in the right order during the calls? I don't like
introducing references unnecessarily but it might be useful until there is
a cleaner solution.

-- Brian

Brian Rogoff

unread,
Mar 27, 2001, 11:39:53 PM3/27/01
to John Max Skaller, caml...@inria.fr
On Wed, 28 Mar 2001, John Max Skaller wrote:
> Brian Rogoff wrote:
> > > The main difficulties we have faced have been --
> > > a) Education - Out here even for people skilled in scheme and some other
> > > functional languages, it is challenging to learn ocaml.
> >
> > What have the issues been? I hate to mention this again (and again, ...) but
> > I find that beginners and non-experts stumble over syntax a lot.
>
> The main problem is that the Tutorial and Reference are weak.
> If the Ocaml Consortium gets off the ground, this ought to be one
> of it's first tasks (i.e., hire a tech writer, not a programmer!)

Can one of the translators comment on the status of the O'Reilly book
translation? Once that's available people can modify it as the language
changes.

> I am constantly stumbling over syntax: even when the underlying
> principles are clear, it is hard to find the right syntax, and it
> is even harder to comprehend which constructions are actually
> supported by the compiler. My main source of information is postings
> to this list.

The mailing list archive has been a great source of help to me too.

> > I would have said that it's ideal for VLSI design software (any other EDA
> > hackers out there?) so maybe it's just ideal for everything?
>

> No. It isn't so good for low level systems software, (use C or C++)

Sorry, I was trying to be funny. As usual, jokes are too much of a serious
business to be attempted by amateurs. I'll postfix all of my lame attempts
at humor with ":-)" in the future :-)

John Max Skaller

unread,
Mar 28, 2001, 2:51:21 AM3/28/01
to Brian Rogoff, Markus Mottl, Hendrik Tews, OCAML
Brian Rogoff wrote:

> I agree with this general principle, and to be honest, I haven't found in
> my own programming a compelling case where module spanning mutually
> recursive function definitions were an issue. Is it possible to produce a
> reasonably sized example, Hendrik (or Chris)?

I have such an example. In the Vyper interpreter, there is a
very large module which handles execution of ASTs, which contains
almost all the interpretive code. It was not possible to break this
module into further pieces because of the mutual recursion.

[I actually _did_ do this, then undid it, because of the excessive
number of extra arguments that had to be passed to make it work]

Vyper is an extension of Python, which does things like:

1. The expression x + y is addition of numbers if x and y are
numbers, otherwise, if x or y are objects of class type,
method calls.

2. The expression eval(string) evaluates string in the current context

which require mutual recursion across widely separates levels of
otherwise fairly logical layers. I used indirection for most of these
recursions (via a class object), but the lower level core execution
was best handled by putting all the routines in one module.

--
John (Max) Skaller, mailto:ska...@maxtal.com.au
10/1 Toxteth Rd Glebe NSW 2037 Australia voice: 61-2-9660-0850
checkout Vyper http://Vyper.sourceforge.net
download Interscript http://Interscript.sourceforge.net

John Max Skaller

unread,
Mar 28, 2001, 2:48:51 AM3/28/01
to Dave Berry, Markus Mottl, Chris Hecker, caml...@inria.fr
Dave Berry wrote:
>
> Pardon me if this is a dumb question, but what is the difference between
> "include" and "open"?

Open simply changes the way lookup is done: the 'environment;
in which definitions in a module are defined. It doesn't change the
interface of the module, or define anything in the module.

Include adds the definitions of one module as definitions
of another module, more or less saving a lot of typing.

(* o.ml *)
open List
let f = map
(* this module contains one symbol, 'f' *)

(* i.ml *)
include List
let f = map
(* this module contains 'map', as well as 'f',
indeed, everything in 'List' *)

(* client.ml *)
let _ = O.f .... (* OK *)
let _ = O.map .. (* error *)
let _ = I.f ... (* OK *)
let _ = I.map .. (* OK, synonym for List.map *)

In other words, O is a client of List, whereas I is an extension
of List.

BTW: include was already available for signatures, but not open.
Is this right? Can 'open' be made available for signatures?
[This would shorten .mli files a lot, make them more readable]

FabienFleutot

unread,
Mar 28, 2001, 2:49:52 AM3/28/01
to caml...@inria.fr
> > My team found it easier to learn erlang, for example. However, people
> > love the strong type checking, and the fact that if it compiles its
> > likely to run correctly... The english translation of the horse book
should
> > help.
>
> Yes, how is that coming? I hope that ugly horse can get replaced by a
> beautiful dromedary.

Unfortunately it won't happen: Perl users have allready `copyrigthed' this
animal...
Anyway, I'd be pleased to know: Why a horse?

John Max Skaller

unread,
Mar 28, 2001, 2:51:24 AM3/28/01
to Brian Rogoff, Vijay Chakravarthy, mattias...@abc.se, Arturo Borquez, caml...@inria.fr
Brian Rogoff wrote:

> > The main difficulties we have faced have been --
> > a) Education - Out here even for people skilled in scheme and some other
> > functional languages, it is challenging to learn ocaml.
>
> What have the issues been? I hate to mention this again (and again, ...) but
> I find that beginners and non-experts stumble over syntax a lot.

The main problem is that the Tutorial and Reference are weak.


If the Ocaml Consortium gets off the ground, this ought to be one
of it's first tasks (i.e., hire a tech writer, not a programmer!)

I am constantly stumbling over syntax: even when the underlying


principles are clear, it is hard to find the right syntax, and it
is even harder to comprehend which constructions are actually
supported by the compiler. My main source of information is postings
to this list.

> I would have said that it's ideal for VLSI design software (any other EDA


> hackers out there?) so maybe it's just ideal for everything?

No. It isn't so good for low level systems software, (use C or C++)
nor for integration tasks (use C). It should be much better than
Java for everything Java can do, if only library support were extended,
with some core support for security and internet.

--
John (Max) Skaller, mailto:ska...@maxtal.com.au
10/1 Toxteth Rd Glebe NSW 2037 Australia voice: 61-2-9660-0850
checkout Vyper http://Vyper.sourceforge.net
download Interscript http://Interscript.sourceforge.net

Joshua D. Guttman

unread,
Mar 28, 2001, 9:30:18 AM3/28/01
to Brian Rogoff, John Max Skaller, caml...@inria.fr, Joshua D. Guttman
Brian Rogoff <b...@best.com> writes:

> >
> > The main problem is that the Tutorial and Reference are weak.
> > If the Ocaml Consortium gets off the ground, this ought to be one

> > of its first tasks (i.e., hire a tech writer, not a programmer!)


>
> Can one of the translators comment on the status of the O'Reilly book
> translation? Once that's available people can modify it as the language
> changes.
>

Well, more than half of the chapters have been checked in in English.
All the remaining chapters have volunteers working on them.

Of course, there will still be a lot of work to do to revise them and
edit them for consistency.

It's a big job, translating a book. And this book is over 700 pages.
But when it's done, it should make an important difference in making
OCaml easier to learn for English speakers.

Joshua

--
Joshua D. Guttman <gut...@mitre.org>
MITRE, Mail Stop S119
202 Burlington Rd. Tel: +1 781 271 2654
Bedford, MA 01730-1420 USA Fax: +1 781 271 3816

William Chesters

unread,
Mar 28, 2001, 2:34:06 PM3/28/01
to caml...@inria.fr
John Max Skaller writes:
> I am constantly stumbling over syntax: even when the underlying
> principles are clear, it is hard to find the right syntax, and it
> is even harder to comprehend which constructions are actually
> supported by the compiler. My main source of information is postings
> to this list.

Strange, I never had that problem. Even coming back to ocaml
intermittently from C++ I don't have to worry too much about the
syntax of things ...

Xavier Leroy

unread,
Mar 29, 2001, 8:50:26 AM3/29/01
to FabienFleutot, caml...@inria.fr
> Unfortunately it won't happen: Perl users have allready
> `copyrigthed' this animal...
> Anyway, I'd be pleased to know: Why a horse?

The rumour I heard was that the O'Reilly graphic designer decided on a
horse "because it's the French camel". Why not, indeed.

You'll notice that the animal on the book cover is not one of those
fancy racing horses, but rather the kind of workhorses ("percheron"?)
that was used in European farms for centuries.

Maybe we should change the name of the language to "Objective
Percheron" to match the book cover :-)

- Xavier Leroy

Daniel de Rauglaudre

unread,
Mar 29, 2001, 9:08:34 AM3/29/01
to caml...@inria.fr
> Maybe we should change the name of the language to "Objective
> Percheron" to match the book cover :-)

I heard somebody telling that my software was written in OCalm
(sounds in French as "calm water"). Therefore I suggest: a whale.

--
Daniel de RAUGLAUDRE
daniel.de_...@inria.fr
http://cristal.inria.fr/~ddr/

Xavier Urbain

unread,
Mar 29, 2001, 9:16:33 AM3/29/01
to Daniel de Rauglaudre, caml...@inria.fr
On Thursday March 29, 2001, Daniel de Rauglaudre wrote:
> I heard somebody telling that my software was written in OCalm
> (sounds in French as "calm water"). Therefore I suggest: a whale.


Too much of an endangered specie as far as I am concerned... Let's be
more confident! (even if scorpions or ants [that are to last] are not
likely a good advertisement).


--

Xavier Urbain
---------------------------------------------------------------
L.R.I., Bât 490 mailto: Xavier...@lri.fr
Université de Paris-Sud phoneto: (33) 1 69 15 42 32
F-91405 Orsay cedex faxto: (33) 1 69 15 65 86

http://www.lri.fr/demons/urbain/introduction.fr.html
---------------------------------------------------------------
-------------------
To unsubscribe, mail caml-lis...@inria.fr. Archives: http://caml.i=
nria.fr

Toby Moth

unread,
Mar 29, 2001, 9:31:06 AM3/29/01
to Daniel de Rauglaudre, caml...@inria.fr

Or else we could retaliate with
a picture of an oyster with a big fat
Pe(a)rl inside.

-----Original Message-----
From: Daniel de Rauglaudre [mailto:daniel.de_...@inria.fr]
Sent: 29 March 2001 15:05
To: caml...@inria.fr
Subject: Re: [Caml-list] Why People Aren't Using OCAML? (was Haskell)


> Maybe we should change the name of the language to "Objective
> Percheron" to match the book cover :-)

I heard somebody telling that my software was written in OCalm

(sounds in French as "calm water"). Therefore I suggest: a whale.

--

-------------------
To unsubscribe, mail caml-lis...@inria.fr.  Archives: http://caml.inria.fr

Jean-Francois Monin

unread,
Mar 29, 2001, 9:40:29 AM3/29/01
to Xavier Leroy, FabienFleutot, caml...@inria.fr
> You'll notice that the animal on the book cover is not one of those
> fancy racing horses, but rather the kind of workhorses ("percheron"?)
> that was used in European farms for centuries.

Frankly, a racing horse would be more appropriate. Or a racing dog
(levrier, at least in french).

JF

Brian Rogoff

unread,
Mar 29, 2001, 11:22:04 AM3/29/01
to Jean-Francois Monin, caml...@inria.fr
On Thu, 29 Mar 2001, Jean-Francois Monin wrote:
> > You'll notice that the animal on the book cover is not one of those
> > fancy racing horses, but rather the kind of workhorses ("percheron"?)
> > that was used in European farms for centuries.
>
> Frankly, a racing horse would be more appropriate. Or a racing dog
> (levrier, at least in french).

In the interests of backwards compatibility, and to prevent any confusion,
I say stick with the camel. So what if Perl has "copyrighted" this? To
prevent confusion, and maybe to get more advertising by being
controversial, we could resurrect Joe Camel. I don't endorse tobacco,
but I think that the Joe Camel ads were really cool.

In the same way, I love the expression "ultra-puissant" used in the
O'Reilly book for describing Caml , even though as Joshua Guttman
correctly pointed out puissant looks and sounds a lot like "piss ant",
which means "insignificant" in that dialect of American English spoken by
those who reside south of the Mason-Dixon line. Well, I think that's what
it means, I'm a damned Yankee and proud of it :-).

-- Brian

Kevin Backhouse

unread,
Mar 30, 2001, 5:32:25 AM3/30/01
to caml...@inria.fr
Is there a parser combinator library for OCaml? I would like to write a
parser for Java and I gather that Java's grammar is LL(1). That might mean
that parser combinators are better suited than yacc.

thanks,

Kevin Backhouse

David Mentre

unread,
Apr 1, 2001, 4:08:21 PM4/1/01
to FabienFleutot, caml...@inria.fr
"FabienFleutot" <fleu...@esiee.fr> writes:

> Anyway, I'd be pleased to know: Why a horse?

Citing Pierre (Weis): "Bonne chance avec Caml: vous voyez que c'est un
``cheval'' solide puisqu'il court encore plus de 10 ans après !" (Good
luck with Caml: you can see that this is a strong horse because it can
still run 10 years after! [1]). So the strong horse on the cover.

d.

[1] I know, I know, my english is bad. :)


--
David....@inria.fr -- http://www.irisa.fr/prive/dmentre/
Opinions expressed here are only mine.

Joseph R. Kiniry

unread,
Apr 1, 2001, 4:31:01 PM4/1/01
to caml...@inria.fr, Chris Hecker, Vijay Chakravarthy, mattias...@abc.se, Arturo Borquez
I attended the GDC as well this past week. I saw your talk on the schedule
Chris but I'm afraid that I was unable to attend. I sent someone from my
company though and they had good things to say about topic, attendence, and
your rants. :)

Additionally, over the next two days, I ran into a number of folks that
asked me about the use of OCaml/ML in game development. The reason that
this came up is because my company in this space did an "objective"
language evaluation when it came to doing prototype development. This
process really sparked a lot of interest and, of course, my pushing for
OCaml came up.

We ended up building the prototype in Eiffel, CLOS, Objective-C, C++, Java,
and iTcl and we chose Java in the end. I've been happy with that choice,
but I was unhappy (at the time and today) that I couldn't convince the
other founders to give OCaml a try. Perhaps I'll have more luck with these
new ICFP results that Chris railed on about. Additionally, I'll just have
to secretly implement out prototype in OCaml as well to do a one year
post-mortum on language choice.

In any case, the point is that some forward-thinking communities that are
willing to try crazy things now and then for selective reasons (e.g.
performance), like the gaming development community, are buzzing a bit
about OCaml.

Of course, now the big (no, make that enormous) problem is one of platform.
99% of game development is performed in C++/C because those are the only
language supported on the top platforms (Windows, Playstation, Nintendo,
Sega, and Xbox). Who's interested in an OCaml port to the Playstation 2? :)

Best,
Joe Kiniry
--
Joseph R. Kiniry http://www.cs.caltech.edu/~kiniry/
California Institute of Technology ID 78860581 ICQ 4344804
Chief Scientist DALi, Inc. http://www.dalilab.com/


--On Monday, March 26, 2001 07:43:48 PM -0800 Chris Hecker <che...@d6.com>
wrote:

David Mentre

unread,
Apr 1, 2001, 5:05:40 PM4/1/01
to Brian Rogoff, Dennis Gang Chen, caml...@inria.fr, Thomas.C...@irisa.fr
Brian Rogoff <b...@best.com> writes:

> Yes, sure I'd like your binding, and please make it web available.

I intended to write a documentation but I had no time. So I've just put
all the sources in a tar file (under GPL license).

It is available at: http://www-rocq.inria.fr/~mentre/software/ocaml-bdd/

WARNING: there is no doc, no README, no information. Only the raw
binding. However it is very simple code and should work very
easily. There is however a very short doc at the beginning of
bdd_interface.c.

This code should be rock solid (I've used it heavily).

If you have problem using it, just ask me (or
Thomas.C...@irisa.fr).

Best regards,
d.


--
David....@inria.fr -- http://www.irisa.fr/prive/dmentre/
Opinions expressed here are only mine.

John Max Skaller

unread,
Apr 1, 2001, 5:11:52 PM4/1/01
to wes...@ilt.fhg.de, caml...@inria.fr
wes...@ilt.fhg.de wrote:

>But probably I still didn't grasp what the real advantages of
> OCaml compared to C++, Java etc. are. So give me and other OCaml
> beginners some more help to better understand what makes OCaml
> superior compared to these main stream languages.

Ocaml offers (at least :-) two advantages for elementary
use. The first is a proper concept of union. Here is an Ocaml union
and a use of it:

type node =
| Const of int
| Unary of char * node
| Binary of char * node * node

(* print expression tree in reverse polish *)
let rp nd = match nd with
| Const i -> print_int i
| Unary (op , arg) ->
rp arg ^ " " print_char op
| Binary (op, arg1, arg2) ->
rp arg1 ^ " " ^ rp arg2 ^ " " ^ print_char op

How would you do this in C/C++?

In C, you _ought_ to use:

struct node {
enum { Const_tag, Unary_tag, Binary_tag } tag;
union {
int Const;
struct { char op; node *arg; } Unary;
struct { char op; node *arg1; node *arg2; } Binary;
}
};

To use it, you need to write:

void rp(node *nd) {
switch (u.tag) {
case Const_tag: printf("%d",u.Const); break;
case Unary_tag:
rp(u.Unary.arg); printch(' '); printch(U.Unary.op);
break;
case Binary_tag:
rp(u.Binary.arg1); printch(' ');
rp(u.Binary.arg2); printch(' '); printch(U.Binary.op);
break;
}

You might leave out the break, and you might accidentally refer to the
wrong component: you can't make either of these mistakes in Ocaml.
Although not shown, you'd have problems destroying the structure
if you forgot a 'free': Ocaml collects garbage automatically.

The above is the 'correctest' solution in C. It won't work in C++,
however, because unions of constructible types are not allowed.
So you're forced to use inheritance and a dynamic cast, which is
very confusing because there is NO abstraction here, and NO
polymorphism.

The second advantage for elementary programming is that functions
are first class values. What this means is that you can define
a function in a scope, and pass the function to some other function,
and when you invoke it the scope is remembered. The thing you are
passing is sometimes called a function _closure_. Here is a simple
example:

let printit printer = printer () in
let f x =
let a = 1 in
let p () = print_int a in
printit p

Here, the printit function just invokes the printing routine 'printer',
which is 'p' in the function 'f'. In passing 'p', the value 'a' is not
forgotten. You can do the equivalent in C++ with functiods: but it
is VERY messy (and very hard to get the memory management right).
Closures are very powerful.

You do the 'moral equivalent' of the above in C++ using
classes .. using about 10 times the number of lines of code,
and probably destroying locality. Here is an example:

let p lst =
let a = 1 in
List.iter (fun x -> print_int (x+a)) lst

In C++:

struct printer {
int a;
printer(int aa) : a(aa) {}
void operator()(int x); { cout << x + a; }
}
void p (list<int> l) {
int a = 1;
for_each(lst.begin(), lst,end(), printer(a));
}

but you have to define the 'struct printer' outside
the 'p' routine, destroying locality. Just try
replacing a triply indexed loop with three invocations
of 'for_each' to see what I mean: STL is a great library,
which is basically useless because functions aren't first
class citizens.

[This particular example has significance to me: I gave up
writing a book on generic programming in C++ when I saw
just how long winded it was to code a triply nested loop
using 'for_each']

--
John (Max) Skaller, mailto:ska...@maxtal.com.au
10/1 Toxteth Rd Glebe NSW 2037 Australia voice: 61-2-9660-0850
checkout Vyper http://Vyper.sourceforge.net
download Interscript http://Interscript.sourceforge.net

John Max Skaller

unread,
Apr 5, 2001, 1:49:54 PM4/5/01
to Brian Rogoff, caml...@inria.fr
Brian Rogoff wrote:

> Did you consider the trick Daniel showed using function references which
> get initialized in the right order during the calls?

Yes, but it's also just too messy. Many of the workarounds are
probably OK for a few uses, but they don't really scale.
With a 'fat' module, we get the simplest, cleanest, code, even if the
module is rather large: interfaces are only useful if they help reduce
complexity.

The most scalable solution I found was to use classes to
'clump' related functions together, allowing a set of functions to
be passed as a single argument (a class object). This also allowed
some state to be put in the object instead of using a functional
closure.

--
John (Max) Skaller, mailto:ska...@maxtal.com.au
10/1 Toxteth Rd Glebe NSW 2037 Australia voice: 61-2-9660-0850
checkout Vyper http://Vyper.sourceforge.net
download Interscript http://Interscript.sourceforge.net

Daniel de Rauglaudre

unread,
Apr 8, 2001, 2:38:51 PM4/8/01
to caml...@inria.fr
Hello,

On Fri, Mar 30, 2001 at 11:27:55AM +0100, Kevin Backhouse wrote:

> Is there a parser combinator library for OCaml? I would like to write a
> parser for Java and I gather that Java's grammar is LL(1). That might mean
> that parser combinators are better suited than yacc.

No, there is not, but you may consider using Camlp4 and its grammars.

0 new messages