caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
* [Caml-list] Programming with modules
@ 2004-08-20 11:28 Erik de Castro Lopo
  2004-08-20 11:45 ` Richard Jones
  2004-08-20 14:47 ` Brian Hurt
  0 siblings, 2 replies; 11+ messages in thread
From: Erik de Castro Lopo @ 2004-08-20 11:28 UTC (permalink / raw)
  To: caml-list

Hi all,

Say I have a module (main.ml) and an interface (main.mli) which
defines a type maintype.

However, main.ml is getting a little large and I'd like to split 
some of the functionality out into another file, but still have
access to maintype in the new file. Unfortunately, Ocaml doesn't
allow mutual dependancies across acoss files.

Does anybody have any suggestions on how to get around this?

TIA,
Erik
-- 
+-----------------------------------------------------------+
  Erik de Castro Lopo  nospam@mega-nerd.com (Yes it's valid)
+-----------------------------------------------------------+
"Crap can work. Given enough thrust pigs will fly, but it's not necessary a
good idea."  -- Alexander Viro on linux-kernel mailing list

-------------------
To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [Caml-list] Programming with modules
  2004-08-20 11:28 [Caml-list] Programming with modules Erik de Castro Lopo
@ 2004-08-20 11:45 ` Richard Jones
  2004-08-20 11:59   ` Benjamin Geer
  2004-08-20 11:59   ` Erik de Castro Lopo
  2004-08-20 14:47 ` Brian Hurt
  1 sibling, 2 replies; 11+ messages in thread
From: Richard Jones @ 2004-08-20 11:45 UTC (permalink / raw)
  To: Erik de Castro Lopo; +Cc: caml-list

On Fri, Aug 20, 2004 at 09:28:18PM +1000, Erik de Castro Lopo wrote:
> Hi all,
> 
> Say I have a module (main.ml) and an interface (main.mli) which
> defines a type maintype.
> 
> However, main.ml is getting a little large and I'd like to split 
> some of the functionality out into another file, but still have
> access to maintype in the new file. Unfortunately, Ocaml doesn't
> allow mutual dependancies across acoss files.
> 
> Does anybody have any suggestions on how to get around this?

Preprocessing with /lib/cpp is possible:

-------------------------------------------------- main.ml
#include "main-part1.ml"
#include "main-part2.ml"

-------------------------------------------------- main-part1.ml
let v1 = 1

-------------------------------------------------- main-part2.ml
let v2 = v1 + 1;;
print_endline ("v2 = " ^ string_of_int v2);;



$ ocamlc -pp /lib/cpp main.ml
$ ./a.out 
v2 = 2

Rich.

-- 
Richard Jones. http://www.annexia.org/ http://www.j-london.com/
Merjis Ltd. http://www.merjis.com/ - improving website return on investment
C2LIB is a library of basic Perl/STL-like types for C. Vectors, hashes,
trees, string funcs, pool allocator: http://www.annexia.org/freeware/c2lib/

-------------------
To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [Caml-list] Programming with modules
  2004-08-20 11:45 ` Richard Jones
@ 2004-08-20 11:59   ` Benjamin Geer
  2004-08-20 11:59   ` Erik de Castro Lopo
  1 sibling, 0 replies; 11+ messages in thread
From: Benjamin Geer @ 2004-08-20 11:59 UTC (permalink / raw)
  To: Richard Jones; +Cc: Erik de Castro Lopo, caml-list

Richard Jones wrote:
> Preprocessing with /lib/cpp is possible:

Or you can use modules:

-------------------------------------------------- main.ml
type maintype = Mytypes.maintype ;;
let foo = Helper.foo ;;

-------------------------------------------------- mytypes.ml
type maintype = int list ;;

-------------------------------------------------- helper.ml
let foo x y = x + y ;;

Ben

-------------------
To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [Caml-list] Programming with modules
  2004-08-20 11:45 ` Richard Jones
  2004-08-20 11:59   ` Benjamin Geer
@ 2004-08-20 11:59   ` Erik de Castro Lopo
  2004-08-20 12:09     ` Richard Jones
  2004-08-27 16:29     ` Richard Jones
  1 sibling, 2 replies; 11+ messages in thread
From: Erik de Castro Lopo @ 2004-08-20 11:59 UTC (permalink / raw)
  To: caml-list; +Cc: Richard Jones

On Fri, 20 Aug 2004 12:45:52 +0100
Richard Jones <rich@annexia.org> wrote:

> Preprocessing with /lib/cpp is possible:
> 
> -------------------------------------------------- main.ml
> #include "main-part1.ml"
> #include "main-part2.ml"
> 
> -------------------------------------------------- main-part1.ml
> let v1 = 1
> 
> -------------------------------------------------- main-part2.ml
> let v2 = v1 + 1;;
> print_endline ("v2 = " ^ string_of_int v2);;
> 
> 
> 
> $ ocamlc -pp /lib/cpp main.ml

OK, I'm sure that will work for now, but I'm not sure if it
scales. What happens when my the line count of the files
hits 10,000 or 100,000 LOC?

Is there a solution that fits my original problem but still 
allows separate compilation?

Erik
-- 
+-----------------------------------------------------------+
  Erik de Castro Lopo  nospam@mega-nerd.com (Yes it's valid)
+-----------------------------------------------------------+
"This is like creating laws against blasphemy and then complaining that
unbelievers can't come up with any logical argument against the existence
of God"  -- www.infoanarchy.org on the Digital Millenium Copyright Act

-------------------
To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [Caml-list] Programming with modules
  2004-08-20 11:59   ` Erik de Castro Lopo
@ 2004-08-20 12:09     ` Richard Jones
  2004-08-27 16:29     ` Richard Jones
  1 sibling, 0 replies; 11+ messages in thread
From: Richard Jones @ 2004-08-20 12:09 UTC (permalink / raw)
  Cc: caml-list

On Fri, Aug 20, 2004 at 09:59:38PM +1000, Erik de Castro Lopo wrote:
> OK, I'm sure that will work for now, but I'm not sure if it
> scales. What happens when my the line count of the files
> hits 10,000 or 100,000 LOC?

Then it'll compile very slowly!

> Is there a solution that fits my original problem but still 
> allows separate compilation?

As Benjamin suggested, move the maintype into a separate module and
make other modules which depend on this.  Then bring all the submodule
definitions together with a single Main.

You'll end up with a polluted module namespace this way of course.

Rich.

-- 
Richard Jones. http://www.annexia.org/ http://www.j-london.com/
Merjis Ltd. http://www.merjis.com/ - improving website return on investment
MOD_CAML lets you run type-safe Objective CAML programs inside the Apache
webserver. http://www.merjis.com/developers/mod_caml/

-------------------
To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [Caml-list] Programming with modules
  2004-08-20 11:28 [Caml-list] Programming with modules Erik de Castro Lopo
  2004-08-20 11:45 ` Richard Jones
@ 2004-08-20 14:47 ` Brian Hurt
  2004-08-20 16:56   ` brogoff
  1 sibling, 1 reply; 11+ messages in thread
From: Brian Hurt @ 2004-08-20 14:47 UTC (permalink / raw)
  To: Erik de Castro Lopo; +Cc: caml-list

On Fri, 20 Aug 2004, Erik de Castro Lopo wrote:

> Hi all,
> 
> Say I have a module (main.ml) and an interface (main.mli) which
> defines a type maintype.
> 
> However, main.ml is getting a little large and I'd like to split 
> some of the functionality out into another file, but still have
> access to maintype in the new file. Unfortunately, Ocaml doesn't
> allow mutual dependancies across acoss files.
> 
> Does anybody have any suggestions on how to get around this?
> 

Push maintype down the module heirarchy- up to an including creating a 
special module which only contains maintype (and some supporting 
functions), which everything depends upon.

More generally, refactor your code.  Find hunks of code which are already 
mostly independent and consider how to make them more independent, so you 
can cut them out into their own modules.  Limit interactions between 
different parts of the code, and develop interfaces for those interactions 
which are necessary.  This actually leads to more maintainable code.

-- 
"Usenet is like a herd of performing elephants with diarrhea -- massive,
difficult to redirect, awe-inspiring, entertaining, and a source of
mind-boggling amounts of excrement when you least expect it."
                                - Gene Spafford 
Brian

-------------------
To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [Caml-list] Programming with modules
  2004-08-20 14:47 ` Brian Hurt
@ 2004-08-20 16:56   ` brogoff
  2004-08-21  1:28     ` skaller
  0 siblings, 1 reply; 11+ messages in thread
From: brogoff @ 2004-08-20 16:56 UTC (permalink / raw)
  To: Brian Hurt; +Cc: Erik de Castro Lopo, caml-list

On Fri, 20 Aug 2004, Brian Hurt wrote:
> On Fri, 20 Aug 2004, Erik de Castro Lopo wrote:
>
> > Hi all,
> >
> > Say I have a module (main.ml) and an interface (main.mli) which
> > defines a type maintype.
> >
> > However, main.ml is getting a little large and I'd like to split
> > some of the functionality out into another file, but still have
> > access to maintype in the new file. Unfortunately, Ocaml doesn't
> > allow mutual dependancies across acoss files.
> >
> > Does anybody have any suggestions on how to get around this?
> >

> More generally, refactor your code.  Find hunks of code which are already
> mostly independent and consider how to make them more independent, so you
> can cut them out into their own modules.  Limit interactions between
> different parts of the code, and develop interfaces for those interactions
> which are necessary.  This actually leads to more maintainable code.

This is very good advice, and I believe you'd get the same advice if you were
programming in Ada, which also has a module system with (parameterized) modules.
In Erik's case, it's the right thing to do. In general, if entities are mutually
dependent they belong in the same module.

There are a few cases where you really do want to support cross module
dependencies, but this seems to be hard to do in a satifactory way. The
issue is made worse IMO by the addition of OO, since class hierarchies,
at least the ones I've used, tend to have more cyclic dependencies.

Whatever became of the mixin approach?

-- Brian

-------------------
To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [Caml-list] Programming with modules
  2004-08-20 16:56   ` brogoff
@ 2004-08-21  1:28     ` skaller
  2004-08-21  1:57       ` [Caml-list] Programming with classes Jean-Baptiste Rouquier
  0 siblings, 1 reply; 11+ messages in thread
From: skaller @ 2004-08-21  1:28 UTC (permalink / raw)
  To: brogoff; +Cc: Brian Hurt, Erik de Castro Lopo, caml-list

On Sat, 2004-08-21 at 02:56, brogoff wrote:

> There are a few cases where you really do want to support cross module
> dependencies, but this seems to be hard to do in a satifactory way. The
> issue is made worse IMO by the addition of OO, since class hierarchies,
> at least the ones I've used, tend to have more cyclic dependencies.

Actually, I have not found that. If you follow
the following general technique, the problem
is eliminated, except from constructors.

First, you have to make a distinct class type for
each kind of object. These are all declared together
in a single mli file, recursively: I'll call
these the abstract class types.

Next, define your classes in an arbitrary order.
It is important that all variables including
arguments to methods use the abstract class types
for typing -- NEVER use the concrete class types
of the concrete classes you're defining.

This obviously ensures that the concrete classes are
independent of each other: in particular, the precise
concrete representation can be changed as you see fit,
provided of course it conforms to its abstract type.

There is a further step: constructors. Never export
class constructors. They must be wrapped in a normal
Ocaml function which returns an abstract class type.

Constructors are the *only* difficult thing to get
right -- all the rest of this mechanism is obvious
and should be done by rote. The reason constructors
are tricky is that sometimes a concrete class must be
constructed using other concrete classes.

In general, if you have a problem ordering the
concrete classes and constructors acyclically --
it is a strong indication your design is wrong.
OO simply isn't a general paradigm, its form
of abstraction is incapable of solving most
problems involving 'relationships' since relationships
are typically covariant.

-- 
John Skaller, mailto:skaller@users.sf.net
voice: 061-2-9660-0850, 
snail: PO BOX 401 Glebe NSW 2037 Australia
Checkout the Felix programming language http://felix.sf.net



-------------------
To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [Caml-list] Programming with classes
  2004-08-21  1:28     ` skaller
@ 2004-08-21  1:57       ` Jean-Baptiste Rouquier
  2004-08-21  2:44         ` skaller
  0 siblings, 1 reply; 11+ messages in thread
From: Jean-Baptiste Rouquier @ 2004-08-21  1:57 UTC (permalink / raw)
  To: caml-list

Quoting skaller:
>There is a further step: constructors. Never export
>class constructors. They must be wrapped in a normal
>Ocaml function which returns an abstract class type.

I would be glad to follow this rule, since I'm experiencing aesthetical problems
with constructors (see below). But could you develop a bit on this ?

My problem is that I'm exporting many class constructors (if you explain me why
I shouldnt, the next version probably won't) with similar argument types :
class type ['a] foo = object ... end
class foo_int : int -> string -> [int] foo
class foo_float : float -> string -> [float] foo
class ['a] foo_option : 'a wrappers -> 'a option -> string -> ['a option] foo
...

The actual class constructors have more arguments, so I'd like to define a sort
of polymorphic class specification and then avoid to repeat the arguments. The
aim is to have clearer documentation. I was considering wrapping it all into
functions but it's pure stub code.
Suggestions ?


Thanks,
-- 
Jean-Baptiste Rouquier

-------------------
To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [Caml-list] Programming with classes
  2004-08-21  1:57       ` [Caml-list] Programming with classes Jean-Baptiste Rouquier
@ 2004-08-21  2:44         ` skaller
  0 siblings, 0 replies; 11+ messages in thread
From: skaller @ 2004-08-21  2:44 UTC (permalink / raw)
  To: Jean-Baptiste Rouquier; +Cc: caml-list

On Sat, 2004-08-21 at 11:57, Jean-Baptiste Rouquier wrote:
> Quoting skaller:
> >There is a further step: constructors. Never export
> >class constructors. They must be wrapped in a normal
> >Ocaml function which returns an abstract class type.
> 
> I would be glad to follow this rule, since I'm experiencing aesthetical problems
> with constructors (see below). But could you develop a bit on this ?

Well, I will give an 'aesthetic' argument then :)

Ocaml only allows a single constructor. Typically you'd like
to make it just establish the data of the class -- it might
not even bother checking invariants. 

However, from a usage viewpoint, you often need multiple
constructors -- for example 'empty list' and 'list of one element'
are good starting points for a list like object. Or you might
have 'make_rational(p,q)' and 'unsafe_make_rational(p,q)'
the latter assuming that p,q are relatively prime and q>0,
and the former checking q<>0 and then reducing p,q to be
relatively prime -- obviously this function is expensive
and is used when the client passes p,q -- but if you're
copying a Rational_Number object there is no need since
the invariant is already assured.

But one can go further and say that, well, anything which
creates an object is a constructor. For example if you 
concantenate two 'list like objects' to get 'list like object'
is not that function a constructor? It is, after all, making
a new object.

So it seems sensible to 'abstract' the notion of 'user accessible
constructor' away from the physical constructor and make the
physical type constructor as brain dead and efficient
as possible, the price being it is unsafe: we protect against
that by restricting access to it.

> My problem is that I'm exporting many class constructors (if you explain me why
> I shouldnt, the next version probably won't) 

There is a trade off, obviously: abstraction costs.

One argument against exporting actual constructors is that
it makes your code fragile. It is hard to change the
representation of a type, when the constructor often
needs representation dependent data as arguments.


-- 
John Skaller, mailto:skaller@users.sf.net
voice: 061-2-9660-0850, 
snail: PO BOX 401 Glebe NSW 2037 Australia
Checkout the Felix programming language http://felix.sf.net



-------------------
To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [Caml-list] Programming with modules
  2004-08-20 11:59   ` Erik de Castro Lopo
  2004-08-20 12:09     ` Richard Jones
@ 2004-08-27 16:29     ` Richard Jones
  1 sibling, 0 replies; 11+ messages in thread
From: Richard Jones @ 2004-08-27 16:29 UTC (permalink / raw)
  Cc: caml-list

[-- Attachment #1: Type: text/plain, Size: 680 bytes --]

On Fri, Aug 20, 2004 at 09:59:38PM +1000, Erik de Castro Lopo wrote:
> Richard Jones <rich@annexia.org> wrote:
> > $ ocamlc -pp /lib/cpp main.ml
> 
> OK, I'm sure that will work for now, but I'm not sure if it
> scales. What happens when my the line count of the files
> hits 10,000 or 100,000 LOC?

There's another problem, apart from speed, which is that cpp barfs on
some valid OCaml code.

Rich.

-- 
Richard Jones. http://www.annexia.org/ http://www.j-london.com/
Merjis Ltd. http://www.merjis.com/ - improving website return on investment
If I have not seen as far as others, it is because I have been
standing in the footprints of giants.  -- from Usenet

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 189 bytes --]

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2004-08-27 16:29 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2004-08-20 11:28 [Caml-list] Programming with modules Erik de Castro Lopo
2004-08-20 11:45 ` Richard Jones
2004-08-20 11:59   ` Benjamin Geer
2004-08-20 11:59   ` Erik de Castro Lopo
2004-08-20 12:09     ` Richard Jones
2004-08-27 16:29     ` Richard Jones
2004-08-20 14:47 ` Brian Hurt
2004-08-20 16:56   ` brogoff
2004-08-21  1:28     ` skaller
2004-08-21  1:57       ` [Caml-list] Programming with classes Jean-Baptiste Rouquier
2004-08-21  2:44         ` skaller

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).