caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
* [Caml-list] Why should I use .mli files?
@ 2012-10-30  0:43 Francois Berenger
  2012-10-30  1:04 ` Peter Groves
                   ` (7 more replies)
  0 siblings, 8 replies; 61+ messages in thread
From: Francois Berenger @ 2012-10-30  0:43 UTC (permalink / raw)
  To: caml-list

Hello,

Here is my stupid question of the day:
what's the use of those .mli files?

Is it just to separate interface from implementation
so that the implementation of a module can be changed
without clients of its interface to have to bother?

Does it make compilation of large software faster
by allowing for more parallelization and maybe later on avoiding to 
recompile some parts?

Usually I program in a pure functional style, so my modules
don't carry an internal state.
I feel like "if someone want to re-use a function, so be it".
If I really want to hide a function that I am afraid people
may call in an incorrect manner, I declare it internally
to some public function and use it correctly.

Also, maybe I only work on toy-size OCaml projects. So, I never 
bothrered to create any .mli file.
I would like to know if I should bother about them.

Thanks a lot,
Francois.

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

* Re: [Caml-list] Why should I use .mli files?
  2012-10-30  0:43 [Caml-list] Why should I use .mli files? Francois Berenger
@ 2012-10-30  1:04 ` Peter Groves
  2012-10-30  2:21   ` Francois Berenger
  2012-10-30  1:15 ` malc
                   ` (6 subsequent siblings)
  7 siblings, 1 reply; 61+ messages in thread
From: Peter Groves @ 2012-10-30  1:04 UTC (permalink / raw)
  To: Francois Berenger; +Cc: caml-list

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

If you only do small projects, you're probably doing things right by
ignoring the .mli files. Languages like Ruby and Python don't have
signature files and that's part of what makes them good for scripting tasks.

But since you asked, here's why I use mli files almost always:

1) The signature files are my "architecture." When I start implementing
something substantial, I'll first make the .mli files for the modules I
think I'll need. I can pretty quickly refactor them until they make sense
semantically and compile against each other. It's not unusual for me to
change an .mli file 10 times before I bother starting to implement it.
After that, I just use the unimplemented methods as my todo list.

2) Documentation. Sometimes I have a module with a 1000 line .ml file and
30 line .mli file (with comments). Much easier to refer to the .mli to
reuse it's methods.

-Peter

On Mon, Oct 29, 2012 at 7:43 PM, Francois Berenger <berenger@riken.jp>wrote:

> Hello,
>
> Here is my stupid question of the day:
> what's the use of those .mli files?
>
> Is it just to separate interface from implementation
> so that the implementation of a module can be changed
> without clients of its interface to have to bother?
>
> Does it make compilation of large software faster
> by allowing for more parallelization and maybe later on avoiding to
> recompile some parts?
>
> Usually I program in a pure functional style, so my modules
> don't carry an internal state.
> I feel like "if someone want to re-use a function, so be it".
> If I really want to hide a function that I am afraid people
> may call in an incorrect manner, I declare it internally
> to some public function and use it correctly.
>
> Also, maybe I only work on toy-size OCaml projects. So, I never bothrered
> to create any .mli file.
> I would like to know if I should bother about them.
>
> Thanks a lot,
> Francois.
>
> --
> Caml-list mailing list.  Subscription management and archives:
> https://sympa.inria.fr/sympa/**arc/caml-list<https://sympa.inria.fr/sympa/arc/caml-list>
> Beginner's list: http://groups.yahoo.com/group/**ocaml_beginners<http://groups.yahoo.com/group/ocaml_beginners>
> Bug reports: http://caml.inria.fr/bin/caml-**bugs<http://caml.inria.fr/bin/caml-bugs>
>

[-- Attachment #2: Type: text/html, Size: 2913 bytes --]

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

* Re: [Caml-list] Why should I use .mli files?
  2012-10-30  0:43 [Caml-list] Why should I use .mli files? Francois Berenger
  2012-10-30  1:04 ` Peter Groves
@ 2012-10-30  1:15 ` malc
  2012-10-30  2:24   ` Francois Berenger
  2012-10-30  1:19 ` Daniel Bünzli
                   ` (5 subsequent siblings)
  7 siblings, 1 reply; 61+ messages in thread
From: malc @ 2012-10-30  1:15 UTC (permalink / raw)
  To: Francois Berenger; +Cc: caml-list

On Tue, 30 Oct 2012, Francois Berenger wrote:

> Hello,
> 
> Here is my stupid question of the day:
> what's the use of those .mli files?
> 
> Is it just to separate interface from implementation
> so that the implementation of a module can be changed
> without clients of its interface to have to bother?
> 
> Does it make compilation of large software faster
> by allowing for more parallelization and maybe later on avoiding to recompile
> some parts?
> 
> Usually I program in a pure functional style, so my modules
> don't carry an internal state.
> I feel like "if someone want to re-use a function, so be it".
> If I really want to hide a function that I am afraid people
> may call in an incorrect manner, I declare it internally
> to some public function and use it correctly.
> 
> Also, maybe I only work on toy-size OCaml projects. So, I never bothrered to
> create any .mli file.
> I would like to know if I should bother about them.
> 

Say you have a 1MLOC .ml(a) that uses something from 100LOC one(b), if you
do not use .mli then every time (b) is touched not only (a) but also (b)
must be recompiled, in .mli case however (a) will be rebuilt only when
the public interface changes. So .mli is a good way to keep separate 
compilation useful. However this (in general) only applies to the bytecode
compiler (ocamlopt uses .cmx files for inlining, making it necessary
to play build system games if one cares more about compile rather than
run time).

-- 
mailto:av1474@comtv.ru

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

* Re: [Caml-list] Why should I use .mli files?
  2012-10-30  0:43 [Caml-list] Why should I use .mli files? Francois Berenger
  2012-10-30  1:04 ` Peter Groves
  2012-10-30  1:15 ` malc
@ 2012-10-30  1:19 ` Daniel Bünzli
  2012-10-30  2:36   ` Francois Berenger
  2012-10-30  2:21 ` gallais @ ensl.org
                   ` (4 subsequent siblings)
  7 siblings, 1 reply; 61+ messages in thread
From: Daniel Bünzli @ 2012-10-30  1:19 UTC (permalink / raw)
  To: Francois Berenger; +Cc: caml-list

Le mardi, 30 octobre 2012 à 01:43, Francois Berenger a écrit :
> Also, maybe I only work on toy-size OCaml projects. So, I never
> bothrered to create any .mli file.
> I would like to know if I should bother about them.

For me, a program that lacks mli files means lack of design, abstraction and documentation and hence equates with rubbish.  

For example at a certain point you (or others) will read your code. At that moment simple things like being able to distinguish between functions/types that are local to a module and those that are used by other part of the program is immensely useful. And that's only one of the purpose of mli files.

In fact mli files are the first thing I write when I design programs.  

Best,

Daniel  







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

* Re: [Caml-list] Why should I use .mli files?
  2012-10-30  0:43 [Caml-list] Why should I use .mli files? Francois Berenger
                   ` (2 preceding siblings ...)
  2012-10-30  1:19 ` Daniel Bünzli
@ 2012-10-30  2:21 ` gallais @ ensl.org
  2012-10-30  6:12 ` Anton Lavrik
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 61+ messages in thread
From: gallais @ ensl.org @ 2012-10-30  2:21 UTC (permalink / raw)
  To: Francois Berenger; +Cc: caml-list

Hi François,

No need to work on big projects to benefit from abstraction: last time
I used an .mli for something else than documentation was when I was
implementing a simulator for a small machine whose memory was an
array of hexadecimal numbers.

After quite a long time spent tracking bugs, I realized that almost all
of them were due to me screwing up the hexadecimal computations.
Fast forward, a module [Hexa] with an abstract type [t] and various
functions such as

from_int: int -> Hexa.t
minus : Hexa.t -> Hexa.t -> Hexa.t
add_int: Hexa.t -> int -> Hexa.t
...

and all my problems were gone: the typechecker was tracking the
use of hexadecimal numbers for me and flagging all operations not
going through these few secure functions as being ill-typed.

That was a nice afternoon.

--
gallais


On 30 October 2012 00:43, Francois Berenger <berenger@riken.jp> wrote:
> Hello,
>
> Here is my stupid question of the day:
> what's the use of those .mli files?
>
> Is it just to separate interface from implementation
> so that the implementation of a module can be changed
> without clients of its interface to have to bother?
>
> Does it make compilation of large software faster
> by allowing for more parallelization and maybe later on avoiding to
> recompile some parts?
>
> Usually I program in a pure functional style, so my modules
> don't carry an internal state.
> I feel like "if someone want to re-use a function, so be it".
> If I really want to hide a function that I am afraid people
> may call in an incorrect manner, I declare it internally
> to some public function and use it correctly.
>
> Also, maybe I only work on toy-size OCaml projects. So, I never bothrered to
> create any .mli file.
> I would like to know if I should bother about them.
>
> Thanks a lot,
> Francois.
>
> --
> Caml-list mailing list.  Subscription management and archives:
> https://sympa.inria.fr/sympa/arc/caml-list
> Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
> Bug reports: http://caml.inria.fr/bin/caml-bugs

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

* Re: [Caml-list] Why should I use .mli files?
  2012-10-30  1:04 ` Peter Groves
@ 2012-10-30  2:21   ` Francois Berenger
  0 siblings, 0 replies; 61+ messages in thread
From: Francois Berenger @ 2012-10-30  2:21 UTC (permalink / raw)
  To: Peter Groves; +Cc: caml-list

On 10/30/2012 10:04 AM, Peter Groves wrote:
> If you only do small projects, you're probably doing things right by
> ignoring the .mli files. Languages like Ruby and Python don't have
> signature files and that's part of what makes them good for scripting tasks.
>
> But since you asked, here's why I use mli files almost always:
>
> 1) The signature files are my "architecture." When I start implementing
> something substantial, I'll first make the .mli files for the modules I
> think I'll need. I can pretty quickly refactor them until they make
> sense semantically and compile against each other. It's not unusual for
> me to change an .mli file 10 times before I bother starting to implement
> it. After that, I just use the unimplemented methods as my todo list.

OK, so as part of a top-down design approach, plus as milestones for
a project. Interesting.

> 2) Documentation. Sometimes I have a module with a 1000 line .ml file
> and 30 line .mli file (with comments). Much easier to refer to the .mli
> to reuse it's methods.

I see.

Thanks,
F.

> -Peter
>
> On Mon, Oct 29, 2012 at 7:43 PM, Francois Berenger <berenger@riken.jp
> <mailto:berenger@riken.jp>> wrote:
>
>     Hello,
>
>     Here is my stupid question of the day:
>     what's the use of those .mli files?
>
>     Is it just to separate interface from implementation
>     so that the implementation of a module can be changed
>     without clients of its interface to have to bother?
>
>     Does it make compilation of large software faster
>     by allowing for more parallelization and maybe later on avoiding to
>     recompile some parts?
>
>     Usually I program in a pure functional style, so my modules
>     don't carry an internal state.
>     I feel like "if someone want to re-use a function, so be it".
>     If I really want to hide a function that I am afraid people
>     may call in an incorrect manner, I declare it internally
>     to some public function and use it correctly.
>
>     Also, maybe I only work on toy-size OCaml projects. So, I never
>     bothrered to create any .mli file.
>     I would like to know if I should bother about them.
>
>     Thanks a lot,
>     Francois.
>
>     --
>     Caml-list mailing list.  Subscription management and archives:
>     https://sympa.inria.fr/sympa/__arc/caml-list
>     <https://sympa.inria.fr/sympa/arc/caml-list>
>     Beginner's list: http://groups.yahoo.com/group/__ocaml_beginners
>     <http://groups.yahoo.com/group/ocaml_beginners>
>     Bug reports: http://caml.inria.fr/bin/caml-__bugs
>     <http://caml.inria.fr/bin/caml-bugs>
>
>


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

* Re: [Caml-list] Why should I use .mli files?
  2012-10-30  1:15 ` malc
@ 2012-10-30  2:24   ` Francois Berenger
  2012-10-30 10:23     ` malc
  0 siblings, 1 reply; 61+ messages in thread
From: Francois Berenger @ 2012-10-30  2:24 UTC (permalink / raw)
  To: malc; +Cc: caml-list

On 10/30/2012 10:15 AM, malc wrote:
> On Tue, 30 Oct 2012, Francois Berenger wrote:
>
>> Hello,
>>
>> Here is my stupid question of the day:
>> what's the use of those .mli files?
>>
>> Is it just to separate interface from implementation
>> so that the implementation of a module can be changed
>> without clients of its interface to have to bother?
>>
>> Does it make compilation of large software faster
>> by allowing for more parallelization and maybe later on avoiding to recompile
>> some parts?
>>
>> Usually I program in a pure functional style, so my modules
>> don't carry an internal state.
>> I feel like "if someone want to re-use a function, so be it".
>> If I really want to hide a function that I am afraid people
>> may call in an incorrect manner, I declare it internally
>> to some public function and use it correctly.
>>
>> Also, maybe I only work on toy-size OCaml projects. So, I never bothrered to
>> create any .mli file.
>> I would like to know if I should bother about them.
>>
> Say you have a 1MLOC .ml(a) that uses something from 100LOC one(b), if you
> do not use .mli then every time (b) is touched not only (a) but also (b)
> must be recompiled, in .mli case however (a) will be rebuilt only when
> the public interface changes. So .mli is a good way to keep separate
> compilation useful. However this (in general) only applies to the bytecode
> compiler (ocamlopt uses .cmx files for inlining,

What about the .cmi files?

> making it necessary
> to play build system games if one cares more about compile rather than
> run time).

I care about both compilation time and run-time, as I am an impatient
and demanding user.


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

* Re: [Caml-list] Why should I use .mli files?
  2012-10-30  1:19 ` Daniel Bünzli
@ 2012-10-30  2:36   ` Francois Berenger
  2012-10-30  3:26     ` Anthony Tavener
  2012-10-30 12:28     ` Daniel Bünzli
  0 siblings, 2 replies; 61+ messages in thread
From: Francois Berenger @ 2012-10-30  2:36 UTC (permalink / raw)
  To: Daniel Bünzli; +Cc: caml-list

On 10/30/2012 10:19 AM, Daniel Bünzli wrote:
> Le mardi, 30 octobre 2012 à 01:43, Francois Berenger a écrit :
>> Also, maybe I only work on toy-size OCaml projects. So, I never
>> bothrered to create any .mli file.
>> I would like to know if I should bother about them.
>
> For me, a program that lacks mli files means lack of design, abstraction and documentation and hence equates with rubbish.

Thanks for the compliment.

To my defence, my main programming goal because of my employer
and colleagues is to deliver fast and correct (software) in order to 
investigate research ideas.
We don't deliver libraries or things targeting at a wide developer
audience (we don't do research in computer science, also).

> For example at a certain point you (or others) will read your code.

I don't have any problem reading my code.
It reads like an English text usually.

 >At that moment simple things like being able to distinguish between 
functions/types that are local to a module and those that are used by 
other part of the program is immensely useful.

Well, if I want to know this, I change the function parameters
and let the compiler tell me where it was used with the initial parameters.
I also quite know my swiss knives (egrep and co).

 > And that's only one of the purpose of mli files.
>
> In fact mli files are the first thing I write when I design programs.

OK, so you too are a top-down design practitioner
and use .mli files to this end.

Thanks,
F.


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

* Re: [Caml-list] Why should I use .mli files?
  2012-10-30  2:36   ` Francois Berenger
@ 2012-10-30  3:26     ` Anthony Tavener
  2012-10-30 12:28     ` Daniel Bünzli
  1 sibling, 0 replies; 61+ messages in thread
From: Anthony Tavener @ 2012-10-30  3:26 UTC (permalink / raw)
  To: Francois Berenger; +Cc: Daniel Bünzli, caml-list

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

Hi Francois,

To add a different perspective, I usually start without mli files. I do
this for one of the reasons you give: leaving most typing up to inferencing.

But parts of my code move into the realm of libraries which are reused, and
here I'll make the mli files concrete. This aids in pinning down type
errors where they really are, forms a kind of documentation, and provides a
nice abstract view of a module suitable for functors.

When you pin down some types, it gives the type system more info to help
you, the programmer. So if you have a module which is fairly concrete and
not likely to change -- specifying the exact signature in an mli can
identify erroneous usage of this module, rather than throwing a more
obscure type error because the inference can't know if the problem is in
the module you're using or the way it's used.

If you are writing small programs and not much reused library-like code,
then you really might not benefit from explicit mli files. They can be a
minor pain, since you have to update them with additions or changes of the
corresponding ml.

Overall, mli's have their place, but I'm glad OCaml has implicit mli
files... so that in cases where they aren't needed, you can ignore them!

-Tony


On Mon, Oct 29, 2012 at 8:36 PM, Francois Berenger <berenger@riken.jp>wrote:

> On 10/30/2012 10:19 AM, Daniel Bünzli wrote:
>
>> Le mardi, 30 octobre 2012 à 01:43, Francois Berenger a écrit :
>>
>>> Also, maybe I only work on toy-size OCaml projects. So, I never
>>> bothrered to create any .mli file.
>>> I would like to know if I should bother about them.
>>>
>>
>> For me, a program that lacks mli files means lack of design, abstraction
>> and documentation and hence equates with rubbish.
>>
>
> Thanks for the compliment.
>
> To my defence, my main programming goal because of my employer
> and colleagues is to deliver fast and correct (software) in order to
> investigate research ideas.
> We don't deliver libraries or things targeting at a wide developer
> audience (we don't do research in computer science, also).
>
>
>  For example at a certain point you (or others) will read your code.
>>
>
> I don't have any problem reading my code.
> It reads like an English text usually.
>
>
> >At that moment simple things like being able to distinguish between
> functions/types that are local to a module and those that are used by other
> part of the program is immensely useful.
>
> Well, if I want to know this, I change the function parameters
> and let the compiler tell me where it was used with the initial parameters.
> I also quite know my swiss knives (egrep and co).
>
>
> > And that's only one of the purpose of mli files.
>
>>
>> In fact mli files are the first thing I write when I design programs.
>>
>
> OK, so you too are a top-down design practitioner
> and use .mli files to this end.
>
> Thanks,
> F.
>
>
>
> --
> Caml-list mailing list.  Subscription management and archives:
> https://sympa.inria.fr/sympa/**arc/caml-list<https://sympa.inria.fr/sympa/arc/caml-list>
> Beginner's list: http://groups.yahoo.com/group/**ocaml_beginners<http://groups.yahoo.com/group/ocaml_beginners>
> Bug reports: http://caml.inria.fr/bin/caml-**bugs<http://caml.inria.fr/bin/caml-bugs>
>

[-- Attachment #2: Type: text/html, Size: 4513 bytes --]

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

* Re: [Caml-list] Why should I use .mli files?
  2012-10-30  0:43 [Caml-list] Why should I use .mli files? Francois Berenger
                   ` (3 preceding siblings ...)
  2012-10-30  2:21 ` gallais @ ensl.org
@ 2012-10-30  6:12 ` Anton Lavrik
  2012-10-30  9:18   ` Francois Berenger
  2012-10-30 14:32   ` [Caml-list] " Oliver Bandel
  2012-10-30  7:43 ` Mike Lin
                   ` (2 subsequent siblings)
  7 siblings, 2 replies; 61+ messages in thread
From: Anton Lavrik @ 2012-10-30  6:12 UTC (permalink / raw)
  To: Francois Berenger; +Cc: caml-list

Hi Francois,

I don't use .mli files that much. Granted, I'm a rather casual OCaml
user, but hey, at least you are not alone :)

I'm surprised by some of the comments you've received. The fact that
some people tend to practice top-down coding more than others doesn't
really mean anything. Other people do it differently even regardless
of the language they use. For me, paper and pencil are far more useful
than .mli files up until the interfaces converge and stabilize.

In general, .mli files are useful and even essential for libraries and
large projects. For instance, they allow to clearly (and cleanly)
define interfaces and help with separate compilation (i.e. to avoid
recompiling parts).

The biggest inconvenience with .mli files as I see it is that I have
to repeat myself and make related but slightly different changes in
two places when I change a module implementation. I would very much
prefer to declare and document public interfaces next to the
implementation and have language tooling take care of separate
compilation and documentation generation.

OCaml is kind of clumsy in this respect. For example, it does allow to
specify types for values and function parameters inline. The syntax
isn't the best, but the feature itself is very useful and I rely on it
all the time. But when I get to define a type signature for a function
e.g. in .mli file, I loose the ability to use parameter names and have
to specify them in the comments.

Overall, I count .mli files as a fairly minor language usability
issue. Perhaps, it wouldn't be even very hard to fix, for example, by
allowing something like "[public] val value-name :  typexpr" in .ml
files so that .mli/.cmi files can be generated automatically with
desired public interfaces.

Anton


On Mon, Oct 29, 2012 at 7:43 PM, Francois Berenger <berenger@riken.jp> wrote:
> Hello,
>
> Here is my stupid question of the day:
> what's the use of those .mli files?
>
> Is it just to separate interface from implementation
> so that the implementation of a module can be changed
> without clients of its interface to have to bother?
>
> Does it make compilation of large software faster
> by allowing for more parallelization and maybe later on avoiding to
> recompile some parts?
>
> Usually I program in a pure functional style, so my modules
> don't carry an internal state.
> I feel like "if someone want to re-use a function, so be it".
> If I really want to hide a function that I am afraid people
> may call in an incorrect manner, I declare it internally
> to some public function and use it correctly.
>
> Also, maybe I only work on toy-size OCaml projects. So, I never bothrered to
> create any .mli file.
> I would like to know if I should bother about them.
>
> Thanks a lot,
> Francois.
>
> --
> Caml-list mailing list.  Subscription management and archives:
> https://sympa.inria.fr/sympa/arc/caml-list
> Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
> Bug reports: http://caml.inria.fr/bin/caml-bugs

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

* Re: [Caml-list] Why should I use .mli files?
  2012-10-30  0:43 [Caml-list] Why should I use .mli files? Francois Berenger
                   ` (4 preceding siblings ...)
  2012-10-30  6:12 ` Anton Lavrik
@ 2012-10-30  7:43 ` Mike Lin
  2012-10-30 15:52 ` Didier Cassirame
  2012-10-31 15:32 ` Alain Frisch
  7 siblings, 0 replies; 61+ messages in thread
From: Mike Lin @ 2012-10-30  7:43 UTC (permalink / raw)
  To: Francois Berenger; +Cc: caml-list

Here are a couple minor benefits that I didn't notice mentioned yet:

1) If you inadvertently/carelessly change the signature of a
function/record/class, you will get a compilation error. (Lots of ways
to get that; this is one of them)

2) You can declare things in the .mli file in a different order than
they appear in the .ml file, and declare mutually recursive functions
separately. This allows you to structure your ocamldoc in the way you
think will be most beneficial to the reader, rather than whatever
order is dictated by the call graph in the implementation.

On Mon, Oct 29, 2012 at 5:43 PM, Francois Berenger <berenger@riken.jp> wrote:
> Hello,
>
> Here is my stupid question of the day:
> what's the use of those .mli files?
>
> Is it just to separate interface from implementation
> so that the implementation of a module can be changed
> without clients of its interface to have to bother?
>
> Does it make compilation of large software faster
> by allowing for more parallelization and maybe later on avoiding to
> recompile some parts?
>
> Usually I program in a pure functional style, so my modules
> don't carry an internal state.
> I feel like "if someone want to re-use a function, so be it".
> If I really want to hide a function that I am afraid people
> may call in an incorrect manner, I declare it internally
> to some public function and use it correctly.
>
> Also, maybe I only work on toy-size OCaml projects. So, I never bothrered to
> create any .mli file.
> I would like to know if I should bother about them.
>
> Thanks a lot,
> Francois.
>
> --
> Caml-list mailing list.  Subscription management and archives:
> https://sympa.inria.fr/sympa/arc/caml-list
> Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
> Bug reports: http://caml.inria.fr/bin/caml-bugs

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

* Re: [Caml-list] Why should I use .mli files?
  2012-10-30  6:12 ` Anton Lavrik
@ 2012-10-30  9:18   ` Francois Berenger
  2012-10-30 10:01     ` Malcolm Matalka
                       ` (2 more replies)
  2012-10-30 14:32   ` [Caml-list] " Oliver Bandel
  1 sibling, 3 replies; 61+ messages in thread
From: Francois Berenger @ 2012-10-30  9:18 UTC (permalink / raw)
  To: Anton Lavrik; +Cc: caml-list

On 10/30/2012 03:12 PM, Anton Lavrik wrote:
> Hi Francois,
>
> I don't use .mli files that much. Granted, I'm a rather casual OCaml
> user, but hey, at least you are not alone :)
>
> I'm surprised by some of the comments you've received. The fact that
> some people tend to practice top-down coding more than others doesn't
> really mean anything. Other people do it differently even regardless
> of the language they use. For me, paper and pencil are far more useful
> than .mli files up until the interfaces converge and stabilize.
>
> In general, .mli files are useful and even essential for libraries and
> large projects. For instance, they allow to clearly (and cleanly)
> define interfaces and help with separate compilation (i.e. to avoid
> recompiling parts).
>
> The biggest inconvenience with .mli files as I see it is that I have
> to repeat myself and make related but slightly different changes in
> two places when I change a module implementation. I would very much
> prefer to declare and document public interfaces next to the
> implementation and have language tooling take care of separate
> compilation and documentation generation.

Thanks for pointing this out!

The exact thing that would annoy me if I would adopt .mli files: 
repeating myself.
In C, I used a tool call cproto to extract header files out of my .c
implementation code. Then, I just snipped out some parts of the header
I didn't want to make public, if I remember well.
That was not perfect, but at least I did not have to maintain two
files at the same time.

> OCaml is kind of clumsy in this respect. For example, it does allow to
> specify types for values and function parameters inline. The syntax
> isn't the best, but the feature itself is very useful and I rely on it
> all the time. But when I get to define a type signature for a function
> e.g. in .mli file, I loose the ability to use parameter names and have
> to specify them in the comments.
>
> Overall, I count .mli files as a fairly minor language usability
> issue. Perhaps, it wouldn't be even very hard to fix, for example, by
> allowing something like "[public] val value-name :  typexpr" in .ml
> files so that .mli/.cmi files can be generated automatically with
> desired public interfaces.

I was thinking more about "export" as the keyword of choice,
but the functionality would be exactly the same.

Best regards,
Francois.

> Anton
>
>
> On Mon, Oct 29, 2012 at 7:43 PM, Francois Berenger <berenger@riken.jp> wrote:
>> Hello,
>>
>> Here is my stupid question of the day:
>> what's the use of those .mli files?
>>
>> Is it just to separate interface from implementation
>> so that the implementation of a module can be changed
>> without clients of its interface to have to bother?
>>
>> Does it make compilation of large software faster
>> by allowing for more parallelization and maybe later on avoiding to
>> recompile some parts?
>>
>> Usually I program in a pure functional style, so my modules
>> don't carry an internal state.
>> I feel like "if someone want to re-use a function, so be it".
>> If I really want to hide a function that I am afraid people
>> may call in an incorrect manner, I declare it internally
>> to some public function and use it correctly.
>>
>> Also, maybe I only work on toy-size OCaml projects. So, I never bothrered to
>> create any .mli file.
>> I would like to know if I should bother about them.
>>
>> Thanks a lot,
>> Francois.
>>
>> --
>> Caml-list mailing list.  Subscription management and archives:
>> https://sympa.inria.fr/sympa/arc/caml-list
>> Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
>> Bug reports: http://caml.inria.fr/bin/caml-bugs


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

* Re: [Caml-list] Why should I use .mli files?
  2012-10-30  9:18   ` Francois Berenger
@ 2012-10-30 10:01     ` Malcolm Matalka
  2012-10-30 11:03     ` Richard W.M. Jones
  2012-10-30 11:41     ` [Caml-list] " Hongbo Zhang
  2 siblings, 0 replies; 61+ messages in thread
From: Malcolm Matalka @ 2012-10-30 10:01 UTC (permalink / raw)
  To: Francois Berenger; +Cc: caml-list, Anton Lavrik

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

Ocamlc can produce mli files for you, but I generally write the mli first
anyways. I found the repetition annoying at first but I quickly found it to
be a none issue and has saved me a few times. Especially when type system
infers a different type than I thought,  the error is localized to the
module.
On Oct 30, 2012 10:18 AM, "Francois Berenger" <berenger@riken.jp> wrote:

> On 10/30/2012 03:12 PM, Anton Lavrik wrote:
>
>> Hi Francois,
>>
>> I don't use .mli files that much. Granted, I'm a rather casual OCaml
>> user, but hey, at least you are not alone :)
>>
>> I'm surprised by some of the comments you've received. The fact that
>> some people tend to practice top-down coding more than others doesn't
>> really mean anything. Other people do it differently even regardless
>> of the language they use. For me, paper and pencil are far more useful
>> than .mli files up until the interfaces converge and stabilize.
>>
>> In general, .mli files are useful and even essential for libraries and
>> large projects. For instance, they allow to clearly (and cleanly)
>> define interfaces and help with separate compilation (i.e. to avoid
>> recompiling parts).
>>
>> The biggest inconvenience with .mli files as I see it is that I have
>> to repeat myself and make related but slightly different changes in
>> two places when I change a module implementation. I would very much
>> prefer to declare and document public interfaces next to the
>> implementation and have language tooling take care of separate
>> compilation and documentation generation.
>>
>
> Thanks for pointing this out!
>
> The exact thing that would annoy me if I would adopt .mli files: repeating
> myself.
> In C, I used a tool call cproto to extract header files out of my .c
> implementation code. Then, I just snipped out some parts of the header
> I didn't want to make public, if I remember well.
> That was not perfect, but at least I did not have to maintain two
> files at the same time.
>
>  OCaml is kind of clumsy in this respect. For example, it does allow to
>> specify types for values and function parameters inline. The syntax
>> isn't the best, but the feature itself is very useful and I rely on it
>> all the time. But when I get to define a type signature for a function
>> e.g. in .mli file, I loose the ability to use parameter names and have
>> to specify them in the comments.
>>
>> Overall, I count .mli files as a fairly minor language usability
>> issue. Perhaps, it wouldn't be even very hard to fix, for example, by
>> allowing something like "[public] val value-name :  typexpr" in .ml
>> files so that .mli/.cmi files can be generated automatically with
>> desired public interfaces.
>>
>
> I was thinking more about "export" as the keyword of choice,
> but the functionality would be exactly the same.
>
> Best regards,
> Francois.
>
>  Anton
>>
>>
>> On Mon, Oct 29, 2012 at 7:43 PM, Francois Berenger <berenger@riken.jp>
>> wrote:
>>
>>> Hello,
>>>
>>> Here is my stupid question of the day:
>>> what's the use of those .mli files?
>>>
>>> Is it just to separate interface from implementation
>>> so that the implementation of a module can be changed
>>> without clients of its interface to have to bother?
>>>
>>> Does it make compilation of large software faster
>>> by allowing for more parallelization and maybe later on avoiding to
>>> recompile some parts?
>>>
>>> Usually I program in a pure functional style, so my modules
>>> don't carry an internal state.
>>> I feel like "if someone want to re-use a function, so be it".
>>> If I really want to hide a function that I am afraid people
>>> may call in an incorrect manner, I declare it internally
>>> to some public function and use it correctly.
>>>
>>> Also, maybe I only work on toy-size OCaml projects. So, I never
>>> bothrered to
>>> create any .mli file.
>>> I would like to know if I should bother about them.
>>>
>>> Thanks a lot,
>>> Francois.
>>>
>>> --
>>> Caml-list mailing list.  Subscription management and archives:
>>> https://sympa.inria.fr/sympa/**arc/caml-list<https://sympa.inria.fr/sympa/arc/caml-list>
>>> Beginner's list: http://groups.yahoo.com/group/**ocaml_beginners<http://groups.yahoo.com/group/ocaml_beginners>
>>> Bug reports: http://caml.inria.fr/bin/caml-**bugs<http://caml.inria.fr/bin/caml-bugs>
>>>
>>
>
> --
> Caml-list mailing list.  Subscription management and archives:
> https://sympa.inria.fr/sympa/**arc/caml-list<https://sympa.inria.fr/sympa/arc/caml-list>
> Beginner's list: http://groups.yahoo.com/group/**ocaml_beginners<http://groups.yahoo.com/group/ocaml_beginners>
> Bug reports: http://caml.inria.fr/bin/caml-**bugs<http://caml.inria.fr/bin/caml-bugs>
>

[-- Attachment #2: Type: text/html, Size: 5910 bytes --]

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

* Re: [Caml-list] Why should I use .mli files?
  2012-10-30  2:24   ` Francois Berenger
@ 2012-10-30 10:23     ` malc
  0 siblings, 0 replies; 61+ messages in thread
From: malc @ 2012-10-30 10:23 UTC (permalink / raw)
  To: Francois Berenger; +Cc: caml-list

On Tue, 30 Oct 2012, Francois Berenger wrote:

> On 10/30/2012 10:15 AM, malc wrote:
> > On Tue, 30 Oct 2012, Francois Berenger wrote:
> > 
> > > Hello,
> > > 

[..snip..]

> > Say you have a 1MLOC .ml(a) that uses something from 100LOC one(b), if you
> > do not use .mli then every time (b) is touched not only (a) but also (b)
> > must be recompiled, in .mli case however (a) will be rebuilt only when
> > the public interface changes. So .mli is a good way to keep separate
> > compilation useful. However this (in general) only applies to the bytecode
> > compiler (ocamlopt uses .cmx files for inlining,
> 
> What about the .cmi files?

I don't understand the question.

> 
> > making it necessary
> > to play build system games if one cares more about compile rather than
> > run time).
> 
> I care about both compilation time and run-time, as I am an impatient
> and demanding user.
> 

Then use .mli files.

-- 
mailto:av1474@comtv.ru

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

* Re: [Caml-list] Why should I use .mli files?
  2012-10-30  9:18   ` Francois Berenger
  2012-10-30 10:01     ` Malcolm Matalka
@ 2012-10-30 11:03     ` Richard W.M. Jones
  2012-10-30 11:41     ` [Caml-list] " Hongbo Zhang
  2 siblings, 0 replies; 61+ messages in thread
From: Richard W.M. Jones @ 2012-10-30 11:03 UTC (permalink / raw)
  To: Francois Berenger; +Cc: Anton Lavrik, caml-list

On Tue, Oct 30, 2012 at 06:18:14PM +0900, Francois Berenger wrote:
> In C, I used a tool call cproto to extract header files out of my .c
> implementation code. Then, I just snipped out some parts of the header
> I didn't want to make public, if I remember well.
> That was not perfect, but at least I did not have to maintain two
> files at the same time.

ocamlc -i can do the same thing.

Maintaining two files can occasionally be annoying, but the benefits
of having a well-defined, well-documented interface between your
modules should not be minimized.

However it doesn't sound as if your project involves large amounts of
people working on the code base over a long period of time, so perhaps
maintainability is not so important for you.

Rich.

-- 
Richard Jones
Red Hat

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

* [Caml-list] Re: Why should I use .mli files?
  2012-10-30  9:18   ` Francois Berenger
  2012-10-30 10:01     ` Malcolm Matalka
  2012-10-30 11:03     ` Richard W.M. Jones
@ 2012-10-30 11:41     ` Hongbo Zhang
  2012-10-30 13:31       ` Romain Bardou
  2 siblings, 1 reply; 61+ messages in thread
From: Hongbo Zhang @ 2012-10-30 11:41 UTC (permalink / raw)
  To: Francois Berenger; +Cc: Anton Lavrik, caml-list

Hi all,
    It's correct that .mli is great for third-party library, but it's 
not helpful for in-house library and agile-development. Sometimes I have 
.mli thousands of lines long, it's not fun to sync it up....
    That's why I filed a feature request which uses access modifier 
'private' like F# http://caml.inria.fr/mantis/view.php?id=5764
    If you like the proposal, plz leave a comment to support it ;-)
On 10/30/12 5:18 AM, Francois Berenger wrote:
> On 10/30/2012 03:12 PM, Anton Lavrik wrote:
>> Hi Francois,
>>
>> I don't use .mli files that much. Granted, I'm a rather casual OCaml
>> user, but hey, at least you are not alone :)
>>
>> I'm surprised by some of the comments you've received. The fact that
>> some people tend to practice top-down coding more than others doesn't
>> really mean anything. Other people do it differently even regardless
>> of the language they use. For me, paper and pencil are far more useful
>> than .mli files up until the interfaces converge and stabilize.
>>
>> In general, .mli files are useful and even essential for libraries and
>> large projects. For instance, they allow to clearly (and cleanly)
>> define interfaces and help with separate compilation (i.e. to avoid
>> recompiling parts).
>>
>> The biggest inconvenience with .mli files as I see it is that I have
>> to repeat myself and make related but slightly different changes in
>> two places when I change a module implementation. I would very much
>> prefer to declare and document public interfaces next to the
>> implementation and have language tooling take care of separate
>> compilation and documentation generation.
>
> Thanks for pointing this out!
>
> The exact thing that would annoy me if I would adopt .mli files:
> repeating myself.
> In C, I used a tool call cproto to extract header files out of my .c
> implementation code. Then, I just snipped out some parts of the header
> I didn't want to make public, if I remember well.
> That was not perfect, but at least I did not have to maintain two
> files at the same time.
>
>> OCaml is kind of clumsy in this respect. For example, it does allow to
>> specify types for values and function parameters inline. The syntax
>> isn't the best, but the feature itself is very useful and I rely on it
>> all the time. But when I get to define a type signature for a function
>> e.g. in .mli file, I loose the ability to use parameter names and have
>> to specify them in the comments.
>>
>> Overall, I count .mli files as a fairly minor language usability
>> issue. Perhaps, it wouldn't be even very hard to fix, for example, by
>> allowing something like "[public] val value-name :  typexpr" in .ml
>> files so that .mli/.cmi files can be generated automatically with
>> desired public interfaces.
>
> I was thinking more about "export" as the keyword of choice,
> but the functionality would be exactly the same.
>
> Best regards,
> Francois.
>
>> Anton
>>
>>
>> On Mon, Oct 29, 2012 at 7:43 PM, Francois Berenger <berenger@riken.jp>
>> wrote:
>>> Hello,
>>>
>>> Here is my stupid question of the day:
>>> what's the use of those .mli files?
>>>
>>> Is it just to separate interface from implementation
>>> so that the implementation of a module can be changed
>>> without clients of its interface to have to bother?
>>>
>>> Does it make compilation of large software faster
>>> by allowing for more parallelization and maybe later on avoiding to
>>> recompile some parts?
>>>
>>> Usually I program in a pure functional style, so my modules
>>> don't carry an internal state.
>>> I feel like "if someone want to re-use a function, so be it".
>>> If I really want to hide a function that I am afraid people
>>> may call in an incorrect manner, I declare it internally
>>> to some public function and use it correctly.
>>>
>>> Also, maybe I only work on toy-size OCaml projects. So, I never
>>> bothrered to
>>> create any .mli file.
>>> I would like to know if I should bother about them.
>>>
>>> Thanks a lot,
>>> Francois.
>>>
>>> --
>>> Caml-list mailing list.  Subscription management and archives:
>>> https://sympa.inria.fr/sympa/arc/caml-list
>>> Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
>>> Bug reports: http://caml.inria.fr/bin/caml-bugs
>
>


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

* Re: [Caml-list] Why should I use .mli files?
  2012-10-30  2:36   ` Francois Berenger
  2012-10-30  3:26     ` Anthony Tavener
@ 2012-10-30 12:28     ` Daniel Bünzli
  2012-10-31  0:53       ` Francois Berenger
  1 sibling, 1 reply; 61+ messages in thread
From: Daniel Bünzli @ 2012-10-30 12:28 UTC (permalink / raw)
  To: Francois Berenger; +Cc: caml-list



Le mardi, 30 octobre 2012 à 03:36, Francois Berenger a écrit :

> > For me, a program that lacks mli files means lack of design, abstraction and documentation and hence equates with rubbish.
>  
>  
> Thanks for the compliment.
Oh don't take it personally it also happens to me.  

> To my defence, my main programming goal because of my employer
> and colleagues is to deliver fast and correct (software) in order to
> investigate research ideas.
> We don't deliver libraries or things targeting at a wide developer


I personnally find none of these arguments very compelling. And if you are interested in correct software, you better have a good/understandable design and mli files help you with that.

> > At that moment simple things like being able to distinguish between  
> functions/types that are local to a module and those that are used by  
> other part of the program is immensely useful.
>  
> Well, if I want to know this, I change the function parameters
> and let the compiler tell me where it was used with the initial parameters.
> I also quite know my swiss knives (egrep and co).

I don't really think that this approach scales if you need to get in touch with a code base that you didn't write --- and remember, for most persons, after a year, your own code looks like code that you didn't write yourself.

> OK, so you too are a top-down design practitioner
> and use .mli files to this end.

Well not necessarily, I mean things are no so clear cut, design informs implementation and vice-versa. It's not as if I necessarily get the mli files right from the start and then just implement them and everything works, it's a refinement process. It also happens to me start the ideas in an ml files and then gradually split it into different modules when it becomes clear what functions/types form the modular units of the programs.  

What is essential to me with mli files is that it makes you think about your program modularity. And modularity is an essential tool for both program understanding and maintenance.

Best,

Daniel

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

* Re: [Caml-list] Re: Why should I use .mli files?
  2012-10-30 11:41     ` [Caml-list] " Hongbo Zhang
@ 2012-10-30 13:31       ` Romain Bardou
  2012-10-31  1:03         ` Francois Berenger
  0 siblings, 1 reply; 61+ messages in thread
From: Romain Bardou @ 2012-10-30 13:31 UTC (permalink / raw)
  To: caml-list

Usually the code you have to duplicate is type definitions which are not 
private. If you don't want to copy-paste them, you can put them in a 
separate file, which you open in the .mli and the .ml.

I often wished for this "private" or "public" keywords myself though. 
But it's not clear what would be the best implementation. For instance:

type t = int
public let f x = x + 1

What should be the type of f in the inferred interface? "int -> int" or 
"t -> int" or "t -> t" or "int -> t"? What about type t, should it be 
"type t = private int" in the interface? Or "type t"?

Cheers,

-- 
Romain Bardou

Le 30/10/2012 12:41, Hongbo Zhang a écrit :
> Hi all,
> It's correct that .mli is great for third-party library, but it's not
> helpful for in-house library and agile-development. Sometimes I have
> .mli thousands of lines long, it's not fun to sync it up....
> That's why I filed a feature request which uses access modifier
> 'private' like F# http://caml.inria.fr/mantis/view.php?id=5764
> If you like the proposal, plz leave a comment to support it ;-)
> On 10/30/12 5:18 AM, Francois Berenger wrote:
>> On 10/30/2012 03:12 PM, Anton Lavrik wrote:
>>> Hi Francois,
>>>
>>> I don't use .mli files that much. Granted, I'm a rather casual OCaml
>>> user, but hey, at least you are not alone :)
>>>
>>> I'm surprised by some of the comments you've received. The fact that
>>> some people tend to practice top-down coding more than others doesn't
>>> really mean anything. Other people do it differently even regardless
>>> of the language they use. For me, paper and pencil are far more useful
>>> than .mli files up until the interfaces converge and stabilize.
>>>
>>> In general, .mli files are useful and even essential for libraries and
>>> large projects. For instance, they allow to clearly (and cleanly)
>>> define interfaces and help with separate compilation (i.e. to avoid
>>> recompiling parts).
>>>
>>> The biggest inconvenience with .mli files as I see it is that I have
>>> to repeat myself and make related but slightly different changes in
>>> two places when I change a module implementation. I would very much
>>> prefer to declare and document public interfaces next to the
>>> implementation and have language tooling take care of separate
>>> compilation and documentation generation.
>>
>> Thanks for pointing this out!
>>
>> The exact thing that would annoy me if I would adopt .mli files:
>> repeating myself.
>> In C, I used a tool call cproto to extract header files out of my .c
>> implementation code. Then, I just snipped out some parts of the header
>> I didn't want to make public, if I remember well.
>> That was not perfect, but at least I did not have to maintain two
>> files at the same time.
>>
>>> OCaml is kind of clumsy in this respect. For example, it does allow to
>>> specify types for values and function parameters inline. The syntax
>>> isn't the best, but the feature itself is very useful and I rely on it
>>> all the time. But when I get to define a type signature for a function
>>> e.g. in .mli file, I loose the ability to use parameter names and have
>>> to specify them in the comments.
>>>
>>> Overall, I count .mli files as a fairly minor language usability
>>> issue. Perhaps, it wouldn't be even very hard to fix, for example, by
>>> allowing something like "[public] val value-name : typexpr" in .ml
>>> files so that .mli/.cmi files can be generated automatically with
>>> desired public interfaces.
>>
>> I was thinking more about "export" as the keyword of choice,
>> but the functionality would be exactly the same.
>>
>> Best regards,
>> Francois.
>>
>>> Anton
>>>
>>>
>>> On Mon, Oct 29, 2012 at 7:43 PM, Francois Berenger <berenger@riken.jp>
>>> wrote:
>>>> Hello,
>>>>
>>>> Here is my stupid question of the day:
>>>> what's the use of those .mli files?
>>>>
>>>> Is it just to separate interface from implementation
>>>> so that the implementation of a module can be changed
>>>> without clients of its interface to have to bother?
>>>>
>>>> Does it make compilation of large software faster
>>>> by allowing for more parallelization and maybe later on avoiding to
>>>> recompile some parts?
>>>>
>>>> Usually I program in a pure functional style, so my modules
>>>> don't carry an internal state.
>>>> I feel like "if someone want to re-use a function, so be it".
>>>> If I really want to hide a function that I am afraid people
>>>> may call in an incorrect manner, I declare it internally
>>>> to some public function and use it correctly.
>>>>
>>>> Also, maybe I only work on toy-size OCaml projects. So, I never
>>>> bothrered to
>>>> create any .mli file.
>>>> I would like to know if I should bother about them.
>>>>
>>>> Thanks a lot,
>>>> Francois.
>>>>
>>>> --
>>>> Caml-list mailing list. Subscription management and archives:
>>>> https://sympa.inria.fr/sympa/arc/caml-list
>>>> Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
>>>> Bug reports: http://caml.inria.fr/bin/caml-bugs
>>
>>
>
>


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

* Re: [Caml-list] Why should I use .mli files?
  2012-10-30  6:12 ` Anton Lavrik
  2012-10-30  9:18   ` Francois Berenger
@ 2012-10-30 14:32   ` Oliver Bandel
  2012-10-30 14:45     ` Anton Lavrik
  2012-10-30 14:47     ` Romain Bardou
  1 sibling, 2 replies; 61+ messages in thread
From: Oliver Bandel @ 2012-10-30 14:32 UTC (permalink / raw)
  To: Anton Lavrik; +Cc: Francois Berenger, caml-list



Am 30.10.2012 um 07:12 schrieb Anton Lavrik <alavrik@piqi.org>:

> Hi Francois,
> 
> I don't use .mli files that much. Granted, I'm a rather casual OCaml
> user, but hey, at least you are not alone :)
> 
> I'm surprised by some of the comments you've received. The fact that
> some people tend to practice top-down coding more than others doesn't
> really mean anything. Other people do it differently even regardless
> of the language they use. For me, paper and pencil are far more useful
> than .mli files up until the interfaces converge and stabilize.
> 
> In general, .mli files are useful and even essential for libraries and
> large projects. For instance, they allow to clearly (and cleanly)
> define interfaces and help with separate compilation (i.e. to avoid
> recompiling parts).
> 
> The biggest inconvenience with .mli files as I see it is that I have
> to repeat myself and make related but slightly different changes in
> two places when I change a module implementation. I would very much
> prefer to declare and document public interfaces next to the
> implementation and have language tooling take care of separate
> compilation and documentation generation.


ocamlc -i
is your friend...

Ciao,
   Oliver


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

* Re: [Caml-list] Why should I use .mli files?
  2012-10-30 14:32   ` [Caml-list] " Oliver Bandel
@ 2012-10-30 14:45     ` Anton Lavrik
  2012-10-30 14:49       ` Oliver Bandel
  2012-10-30 14:51       ` Didier Cassirame
  2012-10-30 14:47     ` Romain Bardou
  1 sibling, 2 replies; 61+ messages in thread
From: Anton Lavrik @ 2012-10-30 14:45 UTC (permalink / raw)
  To: Oliver Bandel; +Cc: caml-list

On Tue, Oct 30, 2012 at 9:32 AM, Oliver Bandel
<oliver@first.in-berlin.de> wrote:
>
> Am 30.10.2012 um 07:12 schrieb Anton Lavrik <alavrik@piqi.org>:
>
>> The biggest inconvenience with .mli files as I see it is that I have
>> to repeat myself and make related but slightly different changes in
>> two places when I change a module implementation. I would very much
>> prefer to declare and document public interfaces next to the
>> implementation and have language tooling take care of separate
>> compilation and documentation generation.
>
>
> ocamlc -i
> is your friend...

"ocamlc -i" is useful, but it can't distinguish between public and
private interfaces and it wouldn't be helpful for generating
documentation.

Anton

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

* Re: [Caml-list] Why should I use .mli files?
  2012-10-30 14:32   ` [Caml-list] " Oliver Bandel
  2012-10-30 14:45     ` Anton Lavrik
@ 2012-10-30 14:47     ` Romain Bardou
  2012-10-30 16:06       ` Edgar Friendly
  1 sibling, 1 reply; 61+ messages in thread
From: Romain Bardou @ 2012-10-30 14:47 UTC (permalink / raw)
  To: caml-list

Le 30/10/2012 15:32, Oliver Bandel a écrit :
>
>
> Am 30.10.2012 um 07:12 schrieb Anton Lavrik<alavrik@piqi.org>:
>
>> Hi Francois,
>>
>> I don't use .mli files that much. Granted, I'm a rather casual OCaml
>> user, but hey, at least you are not alone :)
>>
>> I'm surprised by some of the comments you've received. The fact that
>> some people tend to practice top-down coding more than others doesn't
>> really mean anything. Other people do it differently even regardless
>> of the language they use. For me, paper and pencil are far more useful
>> than .mli files up until the interfaces converge and stabilize.
>>
>> In general, .mli files are useful and even essential for libraries and
>> large projects. For instance, they allow to clearly (and cleanly)
>> define interfaces and help with separate compilation (i.e. to avoid
>> recompiling parts).
>>
>> The biggest inconvenience with .mli files as I see it is that I have
>> to repeat myself and make related but slightly different changes in
>> two places when I change a module implementation. I would very much
>> prefer to declare and document public interfaces next to the
>> implementation and have language tooling take care of separate
>> compilation and documentation generation.
>
>
> ocamlc -i
> is your friend...
>
> Ciao,
>     Oliver
>
>

ocamlc -i is not that useful IMO.

It's not incremental: if you modify a file and want to update the .mli, 
ocamlc -i will not help, because using it directly would remove all 
comments and abstractions.

I don't even find it useful to start a new .mli file, because usually 
when I do that, I don't have the implementation yet.

Even if I have the implementation, so much work will be needed after 
ocamlc -i that it's just easier to start from scratch, write the 
interface that I think I should have, and compare with the existing one. 
It allows to check that what I have implemented is what I actually want.

The work I'm talking about is the following.
- Abstract stuff. This involves removing some values, some types, some 
type definitions, adding "private" keywords, replacing types by their 
abstraction.
- Documentation. This involves writing some ocamldoc and categorizing 
stuff in sections. I know a lot of programmers are lazy and do not put 
ocamldoc in their .mli but this is even more important than the .mli 
itself, IMO.

Related:

http://caml.inria.fr/mantis/view.php?id=5777

Now, it does not mean that nothing could be done. Probably an approach a 
la Pascal, with an "interface" section and an "implementation" section 
in the same file, could be used to avoid some code duplication. But that 
would not help with separate compilation. Maybe ocaml should provide 
something like:

include type t in sig

Which would mean "copy-paste the definition of t from the .mli".

Cheers,

-- 
Romain Bardou

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

* Re: [Caml-list] Why should I use .mli files?
  2012-10-30 14:45     ` Anton Lavrik
@ 2012-10-30 14:49       ` Oliver Bandel
  2012-10-30 14:51       ` Didier Cassirame
  1 sibling, 0 replies; 61+ messages in thread
From: Oliver Bandel @ 2012-10-30 14:49 UTC (permalink / raw)
  To: Anton Lavrik; +Cc: caml-list



Am 30.10.2012 um 15:45 schrieb Anton Lavrik <alavrik@piqi.org>:

> On Tue, Oct 30, 2012 at 9:32 AM, Oliver Bandel
> <oliver@first.in-berlin.de> wrote:
>> 
>> Am 30.10.2012 um 07:12 schrieb Anton Lavrik <alavrik@piqi.org>:
>> 
>>> The biggest inconvenience with .mli files as I see it is that I have
>>> to repeat myself and make related but slightly different changes in
>>> two places when I change a module implementation. I would very much
>>> prefer to declare and document public interfaces next to the
>>> implementation and have language tooling take care of separate
>>> compilation and documentation generation.
>> 
>> 
>> ocamlc -i
>> is your friend...
> 
> "ocamlc -i" is useful, but it can't distinguish between public and
> private interfaces and it wouldn't be helpful for generating
> documentation.
> 
> Anton

Ah, now I see what you mean...

Ciao,
   Oliver

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

* Re: [Caml-list] Why should I use .mli files?
  2012-10-30 14:45     ` Anton Lavrik
  2012-10-30 14:49       ` Oliver Bandel
@ 2012-10-30 14:51       ` Didier Cassirame
  1 sibling, 0 replies; 61+ messages in thread
From: Didier Cassirame @ 2012-10-30 14:51 UTC (permalink / raw)
  To: Anton Lavrik; +Cc: Oliver Bandel, caml-list

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

2012/10/30 Anton Lavrik <alavrik@piqi.org>

> On Tue, Oct 30, 2012 at 9:32 AM, Oliver Bandel
> <oliver@first.in-berlin.de> wrote:
> >
> > Am 30.10.2012 um 07:12 schrieb Anton Lavrik <alavrik@piqi.org>:
> >
> >> The biggest inconvenience with .mli files as I see it is that I have
> >> to repeat myself and make related but slightly different changes in
> >> two places when I change a module implementation. I would very much
> >> prefer to declare and document public interfaces next to the
> >> implementation and have language tooling take care of separate
> >> compilation and documentation generation.
> >
> >
> > ocamlc -i
> > is your friend...
>
> "ocamlc -i" is useful, but it can't distinguish between public and
> private interfaces and it wouldn't be helpful for generating
> documentation.
>
>
I don't think it's meant to be. It's just a tool to get a first draft, and
it's up to the developer to edit it afterward if necessary.

didier

[-- Attachment #2: Type: text/html, Size: 1541 bytes --]

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

* Re: [Caml-list] Why should I use .mli files?
  2012-10-30  0:43 [Caml-list] Why should I use .mli files? Francois Berenger
                   ` (5 preceding siblings ...)
  2012-10-30  7:43 ` Mike Lin
@ 2012-10-30 15:52 ` Didier Cassirame
  2012-10-30 15:56   ` Romain Bardou
  2012-10-31 21:30   ` Oliver Bandel
  2012-10-31 15:32 ` Alain Frisch
  7 siblings, 2 replies; 61+ messages in thread
From: Didier Cassirame @ 2012-10-30 15:52 UTC (permalink / raw)
  To: Francois Berenger; +Cc: caml-list

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

Thinking about it, there's at least one case where mli files are not so
useful: When you have several modules which must all comply with a certain
module type. In that case, all the mli files would be identical, and a
modification of the module type would necessitate to change all the .mli.
What would be the best way to handle that situation?
I was thinking of making an inner module, coerce it to the desired type,
and open it afterwards, but the resulting module would still have a ref to
the inner module in its type.

E.g.:

in the file mymodule.ml

-----------------------8<-------------------

module Inner = (
struct

  (* implementation *)

end : Sig)

open Inner

-----------------------8<-------------------

and the file sig.mli would be the required module type.

didier

2012/10/30 Francois Berenger <berenger@riken.jp>

> Hello,
>
> Here is my stupid question of the day:
> what's the use of those .mli files?
>
> Is it just to separate interface from implementation
> so that the implementation of a module can be changed
> without clients of its interface to have to bother?
>
> Does it make compilation of large software faster
> by allowing for more parallelization and maybe later on avoiding to
> recompile some parts?
>
> Usually I program in a pure functional style, so my modules
> don't carry an internal state.
> I feel like "if someone want to re-use a function, so be it".
> If I really want to hide a function that I am afraid people
> may call in an incorrect manner, I declare it internally
> to some public function and use it correctly.
>
> Also, maybe I only work on toy-size OCaml projects. So, I never bothrered
> to create any .mli file.
> I would like to know if I should bother about them.
>
> Thanks a lot,
> Francois.
>
> --
> Caml-list mailing list.  Subscription management and archives:
> https://sympa.inria.fr/sympa/**arc/caml-list<https://sympa.inria.fr/sympa/arc/caml-list>
> Beginner's list: http://groups.yahoo.com/group/**ocaml_beginners<http://groups.yahoo.com/group/ocaml_beginners>
> Bug reports: http://caml.inria.fr/bin/caml-**bugs<http://caml.inria.fr/bin/caml-bugs>
>

[-- Attachment #2: Type: text/html, Size: 2784 bytes --]

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

* Re: [Caml-list] Why should I use .mli files?
  2012-10-30 15:52 ` Didier Cassirame
@ 2012-10-30 15:56   ` Romain Bardou
  2012-10-30 16:14     ` Didier Cassirame
  2012-10-31 21:30   ` Oliver Bandel
  1 sibling, 1 reply; 61+ messages in thread
From: Romain Bardou @ 2012-10-30 15:56 UTC (permalink / raw)
  To: caml-list

Maybe you can just write "include module type of X" where X is the 
module which already has the .mli. Or you define the signature as a 
module type Sig in a separate file "x.ml" and write "include X.Sig".

Cheers,

-- 
Romain Bardou

Le 30/10/2012 16:52, Didier Cassirame a écrit :
>
> Thinking about it, there's at least one case where mli files are not so
> useful: When you have several modules which must all comply with a
> certain module type. In that case, all the mli files would be identical,
> and a modification of the module type would necessitate to change all
> the .mli.
> What would be the best way to handle that situation?
> I was thinking of making an inner module, coerce it to the desired type,
> and open it afterwards, but the resulting module would still have a ref
> to the inner module in its type.
>
> E.g.:
>
> in the file mymodule.ml <http://mymodule.ml>
>
> -----------------------8<-------------------
>
> module Inner = (
> struct
>
>    (* implementation *)
>
> end : Sig)
>
> open Inner
>
> -----------------------8<-------------------
>
> and the file sig.mli would be the required module type.
>
> didier
>
> 2012/10/30 Francois Berenger <berenger@riken.jp <mailto:berenger@riken.jp>>
>
>     Hello,
>
>     Here is my stupid question of the day:
>     what's the use of those .mli files?
>
>     Is it just to separate interface from implementation
>     so that the implementation of a module can be changed
>     without clients of its interface to have to bother?
>
>     Does it make compilation of large software faster
>     by allowing for more parallelization and maybe later on avoiding to
>     recompile some parts?
>
>     Usually I program in a pure functional style, so my modules
>     don't carry an internal state.
>     I feel like "if someone want to re-use a function, so be it".
>     If I really want to hide a function that I am afraid people
>     may call in an incorrect manner, I declare it internally
>     to some public function and use it correctly.
>
>     Also, maybe I only work on toy-size OCaml projects. So, I never
>     bothrered to create any .mli file.
>     I would like to know if I should bother about them.
>
>     Thanks a lot,
>     Francois.
>
>     --
>     Caml-list mailing list.  Subscription management and archives:
>     https://sympa.inria.fr/sympa/__arc/caml-list
>     <https://sympa.inria.fr/sympa/arc/caml-list>
>     Beginner's list: http://groups.yahoo.com/group/__ocaml_beginners
>     <http://groups.yahoo.com/group/ocaml_beginners>
>     Bug reports: http://caml.inria.fr/bin/caml-__bugs
>     <http://caml.inria.fr/bin/caml-bugs>
>
>


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

* Re: [Caml-list] Why should I use .mli files?
  2012-10-30 14:47     ` Romain Bardou
@ 2012-10-30 16:06       ` Edgar Friendly
  2012-10-30 16:21         ` Romain Bardou
  0 siblings, 1 reply; 61+ messages in thread
From: Edgar Friendly @ 2012-10-30 16:06 UTC (permalink / raw)
  To: caml-list

On 10/30/2012 10:47 AM, Romain Bardou wrote:
> Maybe ocaml should provide something like:
>
> include type t in sig
>
Is there any case where type declarations in the .mli file should not be 
included as part of the .ml file?
> Which would mean "copy-paste the definition of t from the .mli".
>
Why not have this be the default?  i.e. when compiling a .ml file, if 
the corresponding .mli file exists, its type declarations are in scope 
for the .ml file, and its value declarations are applied to the 
corresponding values in the .ml file.  The only edge case I can think of 
is when an identifier is bound multiple times in the .ml file, the type 
from the .mli file currently only applies to the last binding, whereas 
with this strategy, the type would most easily be implemented as 
applying to all bindings of that identifier.

E.

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

* Re: [Caml-list] Why should I use .mli files?
  2012-10-30 15:56   ` Romain Bardou
@ 2012-10-30 16:14     ` Didier Cassirame
  0 siblings, 0 replies; 61+ messages in thread
From: Didier Cassirame @ 2012-10-30 16:14 UTC (permalink / raw)
  To: Romain Bardou; +Cc: caml-list

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

Indeed, I didn't know the "module type of" construct!

didier

2012/10/30 Romain Bardou <romain.bardou@inria.fr>

> Maybe you can just write "include module type of X" where X is the module
> which already has the .mli. Or you define the signature as a module type
> Sig in a separate file "x.ml" and write "include X.Sig".
>
> Cheers,
>
> --
> Romain Bardou
>
> Le 30/10/2012 16:52, Didier Cassirame a écrit :
>
>>
>> Thinking about it, there's at least one case where mli files are not so
>> useful: When you have several modules which must all comply with a
>> certain module type. In that case, all the mli files would be identical,
>> and a modification of the module type would necessitate to change all
>> the .mli.
>> What would be the best way to handle that situation?
>> I was thinking of making an inner module, coerce it to the desired type,
>> and open it afterwards, but the resulting module would still have a ref
>> to the inner module in its type.
>>
>> E.g.:
>>
>> in the file mymodule.ml <http://mymodule.ml>
>>
>>
>> -----------------------8<-----**--------------
>>
>> module Inner = (
>> struct
>>
>>    (* implementation *)
>>
>> end : Sig)
>>
>> open Inner
>>
>> -----------------------8<-----**--------------
>>
>> and the file sig.mli would be the required module type.
>>
>> didier
>>
>> 2012/10/30 Francois Berenger <berenger@riken.jp <mailto:berenger@riken.jp
>> >>
>>
>>
>>     Hello,
>>
>>     Here is my stupid question of the day:
>>     what's the use of those .mli files?
>>
>>     Is it just to separate interface from implementation
>>     so that the implementation of a module can be changed
>>     without clients of its interface to have to bother?
>>
>>     Does it make compilation of large software faster
>>     by allowing for more parallelization and maybe later on avoiding to
>>     recompile some parts?
>>
>>     Usually I program in a pure functional style, so my modules
>>     don't carry an internal state.
>>     I feel like "if someone want to re-use a function, so be it".
>>     If I really want to hide a function that I am afraid people
>>     may call in an incorrect manner, I declare it internally
>>     to some public function and use it correctly.
>>
>>     Also, maybe I only work on toy-size OCaml projects. So, I never
>>     bothrered to create any .mli file.
>>     I would like to know if I should bother about them.
>>
>>     Thanks a lot,
>>     Francois.
>>
>>     --
>>     Caml-list mailing list.  Subscription management and archives:
>>     https://sympa.inria.fr/sympa/_**_arc/caml-list<https://sympa.inria.fr/sympa/__arc/caml-list>
>>     <https://sympa.inria.fr/sympa/**arc/caml-list<https://sympa.inria.fr/sympa/arc/caml-list>
>> >
>>     Beginner's list: http://groups.yahoo.com/group/**__ocaml_beginners<http://groups.yahoo.com/group/__ocaml_beginners>
>>     <http://groups.yahoo.com/**group/ocaml_beginners<http://groups.yahoo.com/group/ocaml_beginners>
>> >
>>     Bug reports: http://caml.inria.fr/bin/caml-**__bugs<http://caml.inria.fr/bin/caml-__bugs>
>>     <http://caml.inria.fr/bin/**caml-bugs<http://caml.inria.fr/bin/caml-bugs>
>> >
>>
>>
>>
>
> --
> Caml-list mailing list.  Subscription management and archives:
> https://sympa.inria.fr/sympa/**arc/caml-list<https://sympa.inria.fr/sympa/arc/caml-list>
> Beginner's list: http://groups.yahoo.com/group/**ocaml_beginners<http://groups.yahoo.com/group/ocaml_beginners>
> Bug reports: http://caml.inria.fr/bin/caml-**bugs<http://caml.inria.fr/bin/caml-bugs>
>

[-- Attachment #2: Type: text/html, Size: 4877 bytes --]

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

* Re: [Caml-list] Why should I use .mli files?
  2012-10-30 16:06       ` Edgar Friendly
@ 2012-10-30 16:21         ` Romain Bardou
  2012-10-30 16:46           ` Edgar Friendly
  0 siblings, 1 reply; 61+ messages in thread
From: Romain Bardou @ 2012-10-30 16:21 UTC (permalink / raw)
  To: caml-list

Le 30/10/2012 17:06, Edgar Friendly a écrit :
> On 10/30/2012 10:47 AM, Romain Bardou wrote:
>> Maybe ocaml should provide something like:
>>
>> include type t in sig
>>
> Is there any case where type declarations in the .mli file should not be
> included as part of the .ml file?

No, as it does not compile otherwise. However, maybe the user wants the 
declarations to be put in some specific order.

>> Which would mean "copy-paste the definition of t from the .mli".
>>
> Why not have this be the default? i.e. when compiling a .ml file, if the
> corresponding .mli file exists, its type declarations are in scope for
> the .ml file, and its value declarations are applied to the
> corresponding values in the .ml file. The only edge case I can think of
> is when an identifier is bound multiple times in the .ml file, the type
> from the .mli file currently only applies to the last binding, whereas
> with this strategy, the type would most easily be implemented as
> applying to all bindings of that identifier.
>
> E.
>

I'm not sure I understand what you mean, but here are some examples I 
worry about.

1) You have the following .mli:
         type t = A
         type u = A
with the following implementation:
         let x = A
Where should type t and type u be copied? In other words, should x be of 
type t or of type u?

It may also happen that the user wants the order of t and u to be 
reversed in the implementation.

2) You have a declaration like this in the .mli:
         type t = private something
Should it be copied as:
         type t = something
or as:
         type t = private something
I don't think the latter makes much sense most of the time, but it is a 
valid declaration.

You could argue that "if private, then do not copy" but it would make 
the extension less useful. Probably "if private, copy as not private" is 
the most sensible thing to do.

Cheers,

-- 
Romain Bardou

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

* Re: [Caml-list] Why should I use .mli files?
  2012-10-30 16:21         ` Romain Bardou
@ 2012-10-30 16:46           ` Edgar Friendly
  2012-10-30 21:25             ` Gabriel Scherer
  0 siblings, 1 reply; 61+ messages in thread
From: Edgar Friendly @ 2012-10-30 16:46 UTC (permalink / raw)
  To: caml-list

On 10/30/2012 12:21 PM, Romain Bardou wrote:
> Le 30/10/2012 17:06, Edgar Friendly a écrit :
>> On 10/30/2012 10:47 AM, Romain Bardou wrote:
>>> Maybe ocaml should provide something like:
>>>
>>> include type t in sig
>>>
>> Is there any case where type declarations in the .mli file should not be
>> included as part of the .ml file?
>
> No, as it does not compile otherwise. However, maybe the user wants 
> the declarations to be put in some specific order.
>
>>> Which would mean "copy-paste the definition of t from the .mli".
>>>
>> Why not have this be the default? i.e. when compiling a .ml file, if the
>> corresponding .mli file exists, its type declarations are in scope for
>> the .ml file, and its value declarations are applied to the
>> corresponding values in the .ml file. The only edge case I can think of
>> is when an identifier is bound multiple times in the .ml file, the type
>> from the .mli file currently only applies to the last binding, whereas
>> with this strategy, the type would most easily be implemented as
>> applying to all bindings of that identifier.
>>
>> E.
>>
>
> I'm not sure I understand what you mean, but here are some examples I 
> worry about.
>
> 1) You have the following .mli:
>         type t = A
>         type u = A
> with the following implementation:
>         let x = A
> Where should type t and type u be copied? In other words, should x be 
> of type t or of type u?
>
They could be copied to the top of the .ml file in the order specified 
in .mli file.
> It may also happen that the user wants the order of t and u to be 
> reversed in the implementation.
>
> 2) You have a declaration like this in the .mli:
>         type t = private something
> Should it be copied as:
>         type t = something
> or as:
>         type t = private something
> I don't think the latter makes much sense most of the time, but it is 
> a valid declaration.
>
Or the user could specify "type t = something" in the .ml file and 
override the .mli file's type.  To do this, we'd need the concept of 
these "copied" types being overrideable in the .ml file, but I think 
doing this would be necessary for backwards compatibility, as all 
existing code would break under the new .mli semantics.

E.

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

* Re: [Caml-list] Why should I use .mli files?
  2012-10-30 16:46           ` Edgar Friendly
@ 2012-10-30 21:25             ` Gabriel Scherer
  2012-10-30 22:18               ` Oliver Bandel
                                 ` (2 more replies)
  0 siblings, 3 replies; 61+ messages in thread
From: Gabriel Scherer @ 2012-10-30 21:25 UTC (permalink / raw)
  To: Edgar Friendly; +Cc: caml-list

Independently of this discussion, I have been discussed related issues
with a friend for the last two weeks. I think there would be a feature
proposal to make in this area that would be *relatively* natural and
help solve the following different problems in this area:
1. Repeating types, module types and class types declarations in the
.mli and the .ml is redundant and increases the maintenance burden
2. The semantics of type-checking the .ml as a whole, and then
checking that it matches the .mli signature is sometimes inconvenient:
checking values against their .mli counterpart could help detect
typing mistakes sooner, which is helpful to get error messages that
are easier to understand
3. Some users want to have annotations on values (at least at
toplevel) for readability and the expression language is not optimal
for this (in particular the fact that type variables do not enforce
polymorphism)

## Proposal

My suggestion would be to allow two features (the second depending on
the first):
1. allow to insert signature items anywhere in a module structure or
.ml file, giving a reasonable semantics to it
    (in particular allow inclusion of signature as a structure item,
with the derived semantics)
2. have a syntax to designate the mli signature from the ml file
(possible suggestion: "module type", used a signature expression)

By combining the two features you could have something like

a.mli
  type t = A | B of u
  type u
  val f : 'a -> 'a

a.ml
  include (module type with type u = int)
  let f x = x

But you could also write only a.ml:
  type t = A | B of u
  type u = int
  val f : 'a -> 'a
  let f x = x

## Corner cases and rejected extensions

Regarding feature 1., there is indeed something to be decided about
shadowing of values:
  val x : int
  let x = 0.
  let x = int_of_float x
or:
  val x : float
  let x = 0.
  val x : int
  let x = 0

My suggestion would be, as a conservative measure, to reject all
shadowing of an identifier that has been prototype with "val" -- as
Edgar suggested. This can always be extended with time (eg. to accept
the second example).

It is also natural, in particular if you come from the world of C
prototypes and predeclared types, to wish to accept something like
  type u
  type u = int (* refining semantics *)
I think we should reject those because they have a muddier semantic
(you could define what the least abstract "unifier" of two definitions
would be, but let's net get down that road). The "S with type u = ..."
(in particular when S is "module type") allows to refine type in a
principle way without shadowing/redeclaration.

Finally, the presence of these "val f : ..." ahead of the actual
definition made me think of the well-known regret that OCaml
compilation units are not very good at top-down programming: you have
to define everything before use which enforces a bottom-up style which
is sometimes not how you would like your code to be read. C prototypes
allow top-down programming, but picking a right semantics without
implicit mutual recursion is tricky. My feature idea willingly rejects
this ambitious direction to stay simple and true. I would still be
interested in thinking about this in the future.


## Known issues and competing proposals

The main problem with this proposal is that the presence of the
"module type" construction can only be explained in terms of the
"superficial" semantics of OCaml compilation units, rather than as a
"pure" feature of a typed lambda calculus. More precisely, I see no
way to explain this semantics but saying "we include the signature of
the .mli", which is admittedly an presentation detail of the OCaml
compiler rather than a deep aspect of the OCaml language.

"module type" could be explained in terms of the module sublanguage:
module M : sig
   type t = int
end = struct
    include (module type)
    let x : t = 1
end

But as you see the context-dependent semantics is not very nice and it
feels ad-hoc -- it is. I think this is the most serious problem with
the proposal and the reason why I'm unsure it could ever be accepted
by the language designers.

Another criticism is that most of the benefits of this proposal can
already be obtained with existing features:
1. one can define the relevant signatures in a "interfaces.ml" files
reused in both the current .ml and the .mli, to avoid duplication
2. there is a rich annotation¹ language for OCaml expressions patterns
or modules that can express what would be independently expressed as a
signature item

¹: while we're at it, I'm considering pushing for the syntax "fun pat
pat ... pat : ty -> expr" as a synonym for "fun pat pat ... pat ->
(expr : ty)", but the potential confusion between "fun x : int ->" and
"fun (x : int) ->" is disheartening.

There is another related proposal: Alain Frisch's suggestion to make
compilation units *recursive* modules implicitly, rather than
non-recursive modules.
  http://caml.inria.fr/mantis/print_bug_page.php?bug_id=5480
Using recursive modules induces a definitive amount of complexity, but
is also more expressive in terms of allowing forward references (the
top-to-bottom style aspect I mentioned earlier). I think a simpler,
non-recursive proposition is a more reasonable choice. Alain described
a compromise in use at Lexifi, where compilation units are
*type-checked* are recursive modules but *compiled* as non-recursive
modules. That's probably close in expressivity to this proposal (but
harder, I think, to explain to the newcomer).

On another level, the signature module of OCaml is not arbitrarily
expressive, and there are some things that cannot be presently handled
by signature manipulations and inclusion alone. For example, you
cannot easily hide/remove values or types from a signature
(destructive substitution "with t := ..." partly does that for type).
Heavy use of the proposed feature could run into these limitations. I
think we should be ready to enrich the signature language in this
case.


On Tue, Oct 30, 2012 at 5:46 PM, Edgar Friendly <thelema314@gmail.com> wrote:
> On 10/30/2012 12:21 PM, Romain Bardou wrote:
>>
>> Le 30/10/2012 17:06, Edgar Friendly a écrit :
>>>
>>> On 10/30/2012 10:47 AM, Romain Bardou wrote:
>>>>
>>>> Maybe ocaml should provide something like:
>>>>
>>>> include type t in sig
>>>>
>>> Is there any case where type declarations in the .mli file should not be
>>> included as part of the .ml file?
>>
>>
>> No, as it does not compile otherwise. However, maybe the user wants the
>> declarations to be put in some specific order.
>>
>>>> Which would mean "copy-paste the definition of t from the .mli".
>>>>
>>> Why not have this be the default? i.e. when compiling a .ml file, if the
>>> corresponding .mli file exists, its type declarations are in scope for
>>> the .ml file, and its value declarations are applied to the
>>> corresponding values in the .ml file. The only edge case I can think of
>>> is when an identifier is bound multiple times in the .ml file, the type
>>> from the .mli file currently only applies to the last binding, whereas
>>> with this strategy, the type would most easily be implemented as
>>> applying to all bindings of that identifier.
>>>
>>> E.
>>>
>>
>> I'm not sure I understand what you mean, but here are some examples I
>> worry about.
>>
>> 1) You have the following .mli:
>>         type t = A
>>         type u = A
>> with the following implementation:
>>         let x = A
>> Where should type t and type u be copied? In other words, should x be of
>> type t or of type u?
>>
> They could be copied to the top of the .ml file in the order specified in
> .mli file.
>
>> It may also happen that the user wants the order of t and u to be reversed
>> in the implementation.
>>
>> 2) You have a declaration like this in the .mli:
>>         type t = private something
>> Should it be copied as:
>>         type t = something
>> or as:
>>         type t = private something
>> I don't think the latter makes much sense most of the time, but it is a
>> valid declaration.
>>
> Or the user could specify "type t = something" in the .ml file and override
> the .mli file's type.  To do this, we'd need the concept of these "copied"
> types being overrideable in the .ml file, but I think doing this would be
> necessary for backwards compatibility, as all existing code would break
> under the new .mli semantics.
>
> E.
>
>
> --
> Caml-list mailing list.  Subscription management and archives:
> https://sympa.inria.fr/sympa/arc/caml-list
> Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
> Bug reports: http://caml.inria.fr/bin/caml-bugs

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

* Re: [Caml-list] Why should I use .mli files?
  2012-10-30 21:25             ` Gabriel Scherer
@ 2012-10-30 22:18               ` Oliver Bandel
  2012-10-31  9:25                 ` Gabriel Scherer
  2012-10-31 10:20               ` Alain Frisch
  2012-10-31 13:50               ` Edgar Friendly
  2 siblings, 1 reply; 61+ messages in thread
From: Oliver Bandel @ 2012-10-30 22:18 UTC (permalink / raw)
  To: Gabriel Scherer; +Cc: Edgar Friendly, caml-list



Am 30.10.2012 um 22:25 schrieb Gabriel Scherer <gabriel.scherer@gmail.com>:

> Independently of this discussion, I have been discussed related issues
> with a friend for the last two weeks. I think there would be a feature
> proposal to make in this area that would be *relatively* natural and
> help solve the following different problems in this area:
> 1. Repeating types, module types and class types declarations in the
> .mli and the .ml is redundant and increases the maintenance burden


Hmhh, not sure if Innserstand whatbyou mean.
But as a mli-file narrows the default signature,
repeating types mustbe done.
An empty mli-file would create an empty signature,
and IMHO thats good.
Otherwise it would be necessary to have another mechanism to
narrow the automatic copying of types.

If I missed your pointm then you need to explain in more depth, what you mean.



> 2. The semantics of type-checking the .ml as a whole, and then
> checking that it matches the .mli signature is sometimes inconvenient:
> checking values against their .mli counterpart could help detect
> typing mistakes sooner, which is helpful to get error messages that
> are easier to understand

What is your argument? pro or contra?
It looks weird to me.


> 3. Some users want to have annotations on values (at least at
> toplevel) for readability and the expression language is not optimal
> for this (in particular the fact that type variables do not enforce
> polymorphism)

??


> 
> ## Proposal
> 
> My suggestion would be to allow two features (the second depending on
> the first):
> 1. allow to insert signature items anywhere in a module structure or
> .ml file, giving a reasonable semantics to it
>    (in particular allow inclusion of signature as a structure item,
> with the derived semantics)


This is something that possibly would create a big mess,
and also seems to mix up interface and implementation
for the module language.
At least thats my fear. Mybe if its well done, it would work.

I just suspect, that something important has been forgotten...






> 2. have a syntax to designate the mli signature from the ml file
> (possible suggestion: "module type", used a signature expression)
> 
> By combining the two features you could have something like
> 
> a.mli
>  type t = A | B of u
>  type u
>  val f : 'a -> 'a
> 
> a.ml
>  include (module type with type u = int)
>  let f x = x

??


> 
> But you could also write only a.ml:
>  type t = A | B of u
>  type u = int
>  val f : 'a -> 'a
>  let f x = x

??


If you don't use mli files, then the exported signiture
is available and is like what you find inside the ml-file.
So what is new here?

I,may missed the point, but you can omit mli-files today also....

Ciao,
   Oliver


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

* Re: [Caml-list] Why should I use .mli files?
  2012-10-30 12:28     ` Daniel Bünzli
@ 2012-10-31  0:53       ` Francois Berenger
  0 siblings, 0 replies; 61+ messages in thread
From: Francois Berenger @ 2012-10-31  0:53 UTC (permalink / raw)
  To: Daniel Bünzli; +Cc: caml-list

On 10/30/2012 09:28 PM, Daniel Bünzli wrote:
>
>
> Le mardi, 30 octobre 2012 à 03:36, Francois Berenger a écrit :
>
>>> For me, a program that lacks mli files means lack of design, abstraction and documentation and hence equates with rubbish.
>>
>>
>> Thanks for the compliment.
> Oh don't take it personally it also happens to me.
>
>> To my defence, my main programming goal because of my employer
>> and colleagues is to deliver fast and correct (software) in order to
>> investigate research ideas.
>> We don't deliver libraries or things targeting at a wide developer
>
>
> I personnally find none of these arguments very compelling.

"don't take it personally" ;)


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

* Re: [Caml-list] Re: Why should I use .mli files?
  2012-10-30 13:31       ` Romain Bardou
@ 2012-10-31  1:03         ` Francois Berenger
  2012-10-31  1:44           ` Daniel Bünzli
  0 siblings, 1 reply; 61+ messages in thread
From: Francois Berenger @ 2012-10-31  1:03 UTC (permalink / raw)
  To: caml-list; +Cc: romain.bardou

On 10/30/2012 10:31 PM, Romain Bardou wrote:
> Usually the code you have to duplicate is type definitions which are not
> private. If you don't want to copy-paste them, you can put them in a
> separate file, which you open in the .mli and the .ml.

In the first place, I don't want to write those .mli files as the 
compiler can infer them for me automatically (I'm lazy).

And I understand that some people need to cast these type signatures
in stone and constrain them in a different way than the default
inferred by the compiler, for large projects.

Regards,
F.


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

* Re: [Caml-list] Re: Why should I use .mli files?
  2012-10-31  1:03         ` Francois Berenger
@ 2012-10-31  1:44           ` Daniel Bünzli
  2012-10-31  9:51             ` Oliver Bandel
  0 siblings, 1 reply; 61+ messages in thread
From: Daniel Bünzli @ 2012-10-31  1:44 UTC (permalink / raw)
  To: Francois Berenger; +Cc: caml-list

Francois Berenger a écrit :
 > On 10/30/2012 09:28 PM, Daniel Bünzli wrote:
 >> I personnally find none of these arguments very compelling.
 >
 > "don't take it personally" ;)

Well... really !

> In the first place, I don't want to write those .mli files as the
> compiler can infer them for me automatically (I'm lazy).

Sure, but it infers the most flexible one and there are many case where 
this is not desired. For example if you want to use typing tricks for 
correctness like phantom types you must write mli files.

And at the risk of repeating myself, knowing by a quick glance what is 
internal/external to a module is also very useful information, e.g. if 
you intend to rewrite its functionality. The compiler cannot know what's 
really important for the clients of the module, it exports everything. 
Consider mli files as cheap documentation.

> And I understand that some people need to cast these type signatures
> in stone and constrain them in a different way than the default
> inferred by the compiler, for large projects.

I'm don't thing large/small project really makes a difference here.

A project may be small but still suffer at a certain point of the data 
structure you initially choose (you may even have deliberately done so 
for quick prototyping).

If you didn't care to define a proper abstract datatype via an mli 
file/signature, the rest of the program will very likely access/make 
assumptions about the internal representation of the data structure.

It should be evident that switching to a different data structure is 
going to be much more time consuming than if you had initially taken the 
time to define an abstract datatype.

Best,

Daniel

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

* Re: [Caml-list] Why should I use .mli files?
  2012-10-30 22:18               ` Oliver Bandel
@ 2012-10-31  9:25                 ` Gabriel Scherer
  2012-10-31  9:59                   ` Daniel Bünzli
  0 siblings, 1 reply; 61+ messages in thread
From: Gabriel Scherer @ 2012-10-31  9:25 UTC (permalink / raw)
  To: Oliver Bandel; +Cc: Edgar Friendly, caml-list

> If I missed your pointm then you need to explain in more depth, what you mean.

My point of view is that you write .mli files, but then you don't want
to repeat in the .ml the concrete type definitions that have been
written in the .mli already. One problem with writing those concrete
(non-abstract) type definitions (and exceptions, class types and
module types) is that you have two places to edit instead of one when
you make a change, which increases the maintenance burden.

>> 2. The semantics of type-checking the .ml as a whole, and then
>> checking that it matches the .mli signature is sometimes inconvenient:
>> checking values against their .mli counterpart could help detect
>> typing mistakes sooner, which is helpful to get error messages that
>> are easier to understand

The current semantics is nice from a conceptual point of view (you
just need to explain how a .ml/.mli pair are understood as a module
with its interface, and then let the usual type-checking rule do the
work), but sometimes you would wish to have values type-checked
against their specification directly, rather than after the whole
module is type-checked. If the value has an unexpected type (compared
to the .mli signature), being warned at the value declaration site is
often better than at a (possibly remote) use site in the rest of the
module. The proposed semantics for having signature items in
structures allows to do this: every "let foo = ..." that comes after a
"val foo : bar" is type-checked under the expected type "bar".

>> 3. Some users want to have annotations on values (at least at
>> toplevel) for readability and the expression language is not optimal
>> for this (in particular the fact that type variables do not enforce
>> polymorphism)

The following code is valid:
  let f : 'a -> 'a = fun x -> x + 1

Beginners are often surprised by this. The language of type
annotations of OCaml is not simple, with three different ways to
enforce polymorphism, none of them obvious to the beginner. Value
signatures have a simple and non-surprising semantics that would
reject the following
  val f : 'a -> 'a
  let f x = x + 1

> I just suspect, that something important has been forgotten...

It's my turn to not understand what you say.

> If you don't use mli files, then the exported signiture
> is available and is like what you find inside the ml-file.
> So what is new here?

Allowing signatures items in structures and .ml files alone does not
increase the expressivity of the language. It is just a different way
to annotate names with expected types, that has the advantage of being
simple and predictable, and coincide with a syntax that users
sometimes wish they could use.
The new aspect of the proposal is the way it can be combined with the
(more debatable in itself) "module type" feature to avoid repeating
type definitions in the .ml. I believe the combination of these two
features is conceptually simpler than other approaches to this problem
(but not the recursive proposal of Alain which is very simple), and
has desirable other effects regarding the principled use of
annotations as signatures.

That said, I'm not clung to this proposal. I have been thinking about
it infrequently for a few weeks, and I'm still not satisfied with the
rather ad-hoc semantics of the "module type" feature. I was exposing
it as a contribution to the discussion, but I don't expect it to turn
into a submitted type-system patch right away.

On Tue, Oct 30, 2012 at 11:18 PM, Oliver Bandel
<oliver@first.in-berlin.de> wrote:
>
>
> Am 30.10.2012 um 22:25 schrieb Gabriel Scherer <gabriel.scherer@gmail.com>:
>
>> Independently of this discussion, I have been discussed related issues
>> with a friend for the last two weeks. I think there would be a feature
>> proposal to make in this area that would be *relatively* natural and
>> help solve the following different problems in this area:
>> 1. Repeating types, module types and class types declarations in the
>> .mli and the .ml is redundant and increases the maintenance burden
>
>
> Hmhh, not sure if Innserstand whatbyou mean.
> But as a mli-file narrows the default signature,
> repeating types mustbe done.
> An empty mli-file would create an empty signature,
> and IMHO thats good.
> Otherwise it would be necessary to have another mechanism to
> narrow the automatic copying of types.
>
> If I missed your pointm then you need to explain in more depth, what you mean.
>
>
>
>> 2. The semantics of type-checking the .ml as a whole, and then
>> checking that it matches the .mli signature is sometimes inconvenient:
>> checking values against their .mli counterpart could help detect
>> typing mistakes sooner, which is helpful to get error messages that
>> are easier to understand
>
> What is your argument? pro or contra?
> It looks weird to me.
>
>
>> 3. Some users want to have annotations on values (at least at
>> toplevel) for readability and the expression language is not optimal
>> for this (in particular the fact that type variables do not enforce
>> polymorphism)
>
> ??
>
>
>>
>> ## Proposal
>>
>> My suggestion would be to allow two features (the second depending on
>> the first):
>> 1. allow to insert signature items anywhere in a module structure or
>> .ml file, giving a reasonable semantics to it
>>    (in particular allow inclusion of signature as a structure item,
>> with the derived semantics)
>
>
> This is something that possibly would create a big mess,
> and also seems to mix up interface and implementation
> for the module language.
> At least thats my fear. Mybe if its well done, it would work.
>
> I just suspect, that something important has been forgotten...
>
>
>
>
>
>
>> 2. have a syntax to designate the mli signature from the ml file
>> (possible suggestion: "module type", used a signature expression)
>>
>> By combining the two features you could have something like
>>
>> a.mli
>>  type t = A | B of u
>>  type u
>>  val f : 'a -> 'a
>>
>> a.ml
>>  include (module type with type u = int)
>>  let f x = x
>
> ??
>
>
>>
>> But you could also write only a.ml:
>>  type t = A | B of u
>>  type u = int
>>  val f : 'a -> 'a
>>  let f x = x
>
> ??
>
>
> If you don't use mli files, then the exported signiture
> is available and is like what you find inside the ml-file.
> So what is new here?
>
> I,may missed the point, but you can omit mli-files today also....
>
> Ciao,
>    Oliver
>

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

* Re: [Caml-list] Re: Why should I use .mli files?
  2012-10-31  1:44           ` Daniel Bünzli
@ 2012-10-31  9:51             ` Oliver Bandel
  0 siblings, 0 replies; 61+ messages in thread
From: Oliver Bandel @ 2012-10-31  9:51 UTC (permalink / raw)
  To: Daniel Bünzli; +Cc: Francois Berenger, caml-list



Am 31.10.2012 um 02:44 schrieb Daniel Bünzli <daniel.buenzli@erratique.ch>:

> Francois Berenger a écrit :
> > On 10/30/2012 09:28 PM, Daniel Bünzli wrote:
> >> I personnally find none of these arguments very compelling.
> >
> > "don't take it personally" ;)
> 
> Well... really !
> 
>> In the first place, I don't want to write those .mli files as the
>> compiler can infer them for me automatically (I'm lazy).
> 
> Sure, but it infers the most flexible one and there are many case where this is not desired. For example if you want to use typing tricks for correctness like phantom types you must write mli files.
> 
> And at the risk of repeating myself, knowing by a quick glance what is internal/external to a module is also very useful information, e.g. if you intend to rewrite its functionality. The compiler cannot know what's really important for the clients of the module, it exports everything. Consider mli files as cheap documentation.
[...]

The point, some peoplembrought in, was, that after changing the ml-file,
the mli is thenold one nevertheless. This also, means, that ocamlc -i
will not help here.
Thenmli file first mustbbe removed or renamed, to get the output for the changed
ml-file.
This also has annoyed me sometimes, when I wanted to to get the new
default signature.

A solution to this problem could be, to have a --force flag, so that
ocamlc -i --force would print the default-signature of the raw ml-file,
as if the mli file corrosponding to it would not exist.
Then the forced ocamlc would print the whole sig of the ml.
One could pick out the new stuff then.

Or a   ocamlc -i --force --diff
could print a diff of the signatures of the raw ml-file with unused mli
to the signature which is forced by the mli-file.

In this way the needed functionality of generating mli-content would be
achieved, without changing the classical behaviour of the mli-files.
And an implementation seems also to be also comparingly easy.

And I would not insist on "--force" and "--diff" as being best choices,
but it was just to explain what is meant as proposal.


Best regards,
   Oliver

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

* Re: [Caml-list] Why should I use .mli files?
  2012-10-31  9:25                 ` Gabriel Scherer
@ 2012-10-31  9:59                   ` Daniel Bünzli
  2012-10-31 13:22                     ` Edgar Friendly
  0 siblings, 1 reply; 61+ messages in thread
From: Daniel Bünzli @ 2012-10-31  9:59 UTC (permalink / raw)
  To: caml-list



Gabriel Scherer a écrit :

> Allowing signatures items in structures and .ml files alone does not
> increase the expressivity of the language.

I'm against this idea. This means that you have to skim trough the whole 
ml file to actually understand what the module signature is. This is 
very inconvenient.

I think it's again the symptom of focusing on program writing whereas 
the focus should be on reading programs. The latter actually happens 
more than the former. I look forward to the day language designers will 
focus on readability rather than brevity (look ! my ununderstandable two 
liner solve this very complex problem by having all this implicit stuff 
going on).

Now at a certain point I was also annoyed by the problem you mention but 
I think it can be solved by something like typerex or an interactive 
mode to the compiler that would allow you to reconcile a signature with 
its implementation when there is a module signature mismatch (asking 
questions like keep the mli type one or the ml type and updating the 
files accordingly).

Best,

Daniel

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

* Re: [Caml-list] Why should I use .mli files?
  2012-10-30 21:25             ` Gabriel Scherer
  2012-10-30 22:18               ` Oliver Bandel
@ 2012-10-31 10:20               ` Alain Frisch
  2012-10-31 13:50               ` Edgar Friendly
  2 siblings, 0 replies; 61+ messages in thread
From: Alain Frisch @ 2012-10-31 10:20 UTC (permalink / raw)
  To: Gabriel Scherer; +Cc: Edgar Friendly, caml-list

On 10/30/2012 10:25 PM, Gabriel Scherer wrote:
> There is another related proposal: Alain Frisch's suggestion to make
> compilation units *recursive* modules implicitly, rather than
> non-recursive modules.
>    http://caml.inria.fr/mantis/print_bug_page.php?bug_id=5480
> Using recursive modules induces a definitive amount of complexity, but
> is also more expressive in terms of allowing forward references (the
> top-to-bottom style aspect I mentioned earlier). I think a simpler,
> non-recursive proposition is a more reasonable choice. Alain described
> a compromise in use at Lexifi, where compilation units are
> *type-checked* are recursive modules but *compiled* as non-recursive
> modules. That's probably close in expressivity to this proposal (but
> harder, I think, to explain to the newcomer).

Type-checking compilation units as recursive modules addresses several 
issues at the same time:

  - Mutual recursion between type-level components of different kinds 
(e.g. a data type declaration and a class type).  The current solution 
is to introduce a local recursive module.

  - Avoid duplication of type declarations between the interface and the 
implementation (at least for structural definitions; a type-include 
feature, as described in the Mantis ticket, would also give a solution 
for data types).


In addition, compiling units as recursive modules (not only for 
type-checking) would address the common need of forward references and 
the less common need of allowing recursion between, say, a class 
definition and a function.  The current work-around is to use references 
to break the recursion, but this is quite an ugly solution (the nice 
thing with it, though, is that it also works for allowing recursion 
between several compilation units).


Unfortunately, the type-checking and compilation of recursive modules 
does not seem to be a mastered domain yet, and it sounds dangerous to 
rely on them for defining the semantics of normal compilation units, at 
least for now (this is Xavier's argument, and I tend to agree). 
Hopefully, some more research will give a better understanding of 
recursive modules...



Alain

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

* Re: [Caml-list] Why should I use .mli files?
  2012-10-31  9:59                   ` Daniel Bünzli
@ 2012-10-31 13:22                     ` Edgar Friendly
  2012-10-31 13:38                       ` Daniel Bünzli
  2012-10-31 13:43                       ` Gabriel Scherer
  0 siblings, 2 replies; 61+ messages in thread
From: Edgar Friendly @ 2012-10-31 13:22 UTC (permalink / raw)
  To: caml-list

On 10/31/2012 5:59 AM, Daniel Bünzli wrote:
> Gabriel Scherer a écrit :
>> Allowing signatures items in structures and .ml files alone does not
>> increase the expressivity of the language.
> I'm against this idea. This means that you have to skim trough the 
> whole ml file to actually understand what the module signature is. 
> This is very inconvenient.
It makes sense to me that such a signature item in a .ml file should be 
restricted to being immediately before the value binding it applies to.  
i.e.

val foo : 'a -> 'a
let foo x = x

would be legal, while the following would not be allowed:

val foo: 'a -> 'a
val bar: int -> string
let foo x = x
let bar = string_of_int

This should solve the "skim through the whole ml file" problem.

E.

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

* Re: [Caml-list] Why should I use .mli files?
  2012-10-31 13:22                     ` Edgar Friendly
@ 2012-10-31 13:38                       ` Daniel Bünzli
  2012-10-31 13:55                         ` Edgar Friendly
  2012-10-31 13:43                       ` Gabriel Scherer
  1 sibling, 1 reply; 61+ messages in thread
From: Daniel Bünzli @ 2012-10-31 13:38 UTC (permalink / raw)
  To: Edgar Friendly; +Cc: caml-list

> It makes sense to me that such a signature item in a .ml file should 
> be restricted to being immediately before the value binding it applies 
> to. i.e.
[...]
> This should solve the "skim through the whole ml file" problem.

Not at all. 

The problem is not for a single value. The problem is understanding what this modules actually exports and hence the information flow between the larger program and that module. With this proposal that information is scattered across the whole module among intermediary, hidden, definitions.

An mli summarizes very well the actual interface of the module without being distracted by the way the code is actually organized in the module. It's a huge tool for understanding programs.  

Best,

Daniel

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

* Re: [Caml-list] Why should I use .mli files?
  2012-10-31 13:22                     ` Edgar Friendly
  2012-10-31 13:38                       ` Daniel Bünzli
@ 2012-10-31 13:43                       ` Gabriel Scherer
  2012-11-01  0:38                         ` Francois Berenger
  1 sibling, 1 reply; 61+ messages in thread
From: Gabriel Scherer @ 2012-10-31 13:43 UTC (permalink / raw)
  To: Edgar Friendly; +Cc: caml-list

> It makes sense to me that such a signature item in a .ml file should be
> restricted to being immediately before the value binding it applies to.

It makes sense, but then the (include (module type)) feature I was
proposing to avoid duplicating transparent definition from the .mli
into the .ml doesn't work anymore. I need a sufficiently relaxed
syntax that allows to put signature items at the top of the file and
use them afterwards.

I don't think any restriction of this kind would be sufficient nor
necessary to dispel Daniel's fears. Daniel, I fully agree that .mli
are helpful and should be preserved, and my suggestion was precisely
in the sense of making the .ml/.mli combination more convenient for
users, so that they would have less incentive to use the .ml alone.
There is not much in the feature proposal that would allow to get rid
of the .mli anymore that it currently is the case, so I don't
understand your opposition based on this particular argument.

(On the other side, I must note that your argument that ".ml/.mli
redundancy should be handled by tooling" could be reused in the
converse direction: the .mli (including documentation if present in
the source) could be produced from the .ml by tooling. In the absence
of such tooling, I don't give much weight to either arguments which
are a modern form of the too-convenient Sufficiently Smart Compiler
point of view.)

On Wed, Oct 31, 2012 at 2:22 PM, Edgar Friendly <thelema314@gmail.com> wrote:
> On 10/31/2012 5:59 AM, Daniel Bünzli wrote:
>>
>> Gabriel Scherer a écrit :
>>>
>>> Allowing signatures items in structures and .ml files alone does not
>>> increase the expressivity of the language.
>>
>> I'm against this idea. This means that you have to skim trough the whole
>> ml file to actually understand what the module signature is. This is very
>> inconvenient.
>
> It makes sense to me that such a signature item in a .ml file should be
> restricted to being immediately before the value binding it applies to.
> i.e.
>
> val foo : 'a -> 'a
> let foo x = x
>
> would be legal, while the following would not be allowed:
>
> val foo: 'a -> 'a
> val bar: int -> string
> let foo x = x
> let bar = string_of_int
>
> This should solve the "skim through the whole ml file" problem.
>
> E.
>
>
> --
> Caml-list mailing list.  Subscription management and archives:
> https://sympa.inria.fr/sympa/arc/caml-list
> Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
> Bug reports: http://caml.inria.fr/bin/caml-bugs

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

* Re: [Caml-list] Why should I use .mli files?
  2012-10-30 21:25             ` Gabriel Scherer
  2012-10-30 22:18               ` Oliver Bandel
  2012-10-31 10:20               ` Alain Frisch
@ 2012-10-31 13:50               ` Edgar Friendly
  2012-10-31 15:12                 ` Gabriel Scherer
  2 siblings, 1 reply; 61+ messages in thread
From: Edgar Friendly @ 2012-10-31 13:50 UTC (permalink / raw)
  To: Gabriel Scherer; +Cc: caml-list

On 10/30/2012 5:25 PM, Gabriel Scherer wrote:
> ## Proposal
>
> 1. allow to insert signature items anywhere in a module structure or
> .ml file, giving a reasonable semantics to it
>      (in particular allow inclusion of signature as a structure item,
> with the derived semantics)
This seems a quite reasonable feature for OCaml to have, as annotating 
the desired type of a declaration
> 2. have a syntax to designate the mli signature from the ml file
> (possible suggestion: "module type", used a signature expression)
Eww.  This seems quite ugly, especially using the complex "with type foo 
= bar" syntax for something as common as giving the implementation of an 
abstract type.
> It is also natural, in particular if you come from the world of C
> prototypes and predeclared types, to wish to accept something like
>    type u
>    type u = int (* refining semantics *)
> I think we should reject those because they have a muddier semantic
> (you could define what the least abstract "unifier" of two definitions
> would be, but let's net get down that road). The "S with type u = ..."
> (in particular when S is "module type") allows to refine type in a
> principle way without shadowing/redeclaration.
Maybe it's my over-exposure to C++ lately, but I see a clear semantic 
for type re-declaration:
1) It is only allowed to re-declare types from the auto-import of a 
module signature
2) abstract types can be re-declared arbitrarily
3) private foo types can be re-declared to foo
Nothing else can be re-declared.

I might even go so far as to say that these re-declarations have to be 
at the top of the module definition; before any value declarations or 
private type declarations.  I see some use in forcing these to complete 
before normal compilation can proceed, to avoid the case of having to 
type a value before its concrete type is declared.

module Foo = sig
     type t
     val x : t
end = struct
     let x = 5
     type t = string
end

Rules like this should allow a module signature to have its typechecking 
effect on the associated module implementation as that module 
implementation is compiled and typechecked without needing a second pass 
over the inferred signature of the module to verify that the final 
result of the module is compatible.  Not that the second pass is a bad 
thing, but you're right that we will enable better error messages from a 
one-pass, local typing as opposed to a global structure comparison.

E.

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

* Re: [Caml-list] Why should I use .mli files?
  2012-10-31 13:38                       ` Daniel Bünzli
@ 2012-10-31 13:55                         ` Edgar Friendly
  0 siblings, 0 replies; 61+ messages in thread
From: Edgar Friendly @ 2012-10-31 13:55 UTC (permalink / raw)
  To: Daniel Bünzli; +Cc: caml-list

On 10/31/2012 9:38 AM, Daniel Bünzli wrote:
> The problem is not for a single value. The problem is understanding 
> what this modules actually exports and hence the information flow 
> between the larger program and that module. With this proposal that 
> information is scattered across the whole module among intermediary, 
> hidden, definitions.
>
> An mli summarizes very well the actual interface of the module without 
> being distracted by the way the code is actually organized in the 
> module. It's a huge tool for understanding programs.
> Best,
>
> Daniel
Ah, I misunderstood your criticism.  You're right, we should keep .mli 
files as the great summary of the interface of .ml files.  I'm pretty 
neutral about having type declarations (val foo : <type of foo>) in the 
.ml file, as this is just another duplication of what needs to be in the 
.mli file.  I think that the information in the .mli file should 
directly impact the compilation of the .ml file, in that types declared 
there should be available in the .ml file, and the types given to 
identifiers should be applied to bindings for those identifiers as 
they're being compiled (so that int specialization can produce better 
compiled code, for one example).

E.

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

* Re: [Caml-list] Why should I use .mli files?
  2012-10-31 13:50               ` Edgar Friendly
@ 2012-10-31 15:12                 ` Gabriel Scherer
  2012-10-31 16:48                   ` Edgar Friendly
  0 siblings, 1 reply; 61+ messages in thread
From: Gabriel Scherer @ 2012-10-31 15:12 UTC (permalink / raw)
  To: Edgar Friendly; +Cc: caml-list

> Maybe it's my over-exposure to C++ lately, but I see a clear semantic for
> type re-declaration:
> 1) It is only allowed to re-declare types from the auto-import of a module
> signature
> 2) abstract types can be re-declared arbitrarily
> 3) private foo types can be re-declared to foo
> Nothing else can be re-declared.

Why not. We even have a syntax for explicit type overriding: "type! u = int"!
(But if you want to preserve backward-compatibility and still make the
implicit inclusion of the interface in the implementation the default,
you need to allow innocent-looking definitions to have a rebinding
semantics.)

I liked the idea of reusing the "with type ..." semantics instead of
introducing a new feature, but if this proposal can get rid of the
rather ad-hoc "module type" construct, you're trading one ad-hoc for
another ad-hoc yet potentially simpler feature. I would be happy with
such a langage feature.

Alain wrote:
> Type-checking compilation units as recursive modules addresses several
> issues at the same time:
>  - Mutual recursion between type-level components of different kinds
> (e.g. a data type declaration and a class type).
> The current solution is to introduce a local recursive module.
>
> - Avoid duplication of type declarations between the interface and the implementation
> (at least for structuraldefinitions; a type-include feature, as described in the Mantis ticket,
> would also give a solution for data types).
>
> In addition, compiling units as recursive modules (not only for type-checking) would address
> the common need of forward references and the less common need of allowing recursion between,
> say, a class definition and a function.  The current work-around is to use references to break
> the recursion, but this is quite an ugly solution (the nice thing with it, though, is that it also works
> for allowing recursion between several compilation units).

Those are all compelling arguments (in terms of "necessary language
change" to "solved problems" ratio, your proposal is probably
optimally low), but the complexity cost (in term of theory but also of
program comprehension for the unaware beginner) of module recursion
are really high. I would favor working out smaller, isolated solutions
for type duplication, forward references and mutually recursive
structure items -- but indeed that would mean more language changes,
which often means no change at all. Besides, the proposal still
requires some form of (include (module type of M)) in m.ml to avoid
type redefinitions, which is less ad-hoc than (include (module type))
but also less convenient that the implicit-and-by-default solution
that Edgar champions.

On Wed, Oct 31, 2012 at 2:50 PM, Edgar Friendly <thelema314@gmail.com> wrote:
> On 10/30/2012 5:25 PM, Gabriel Scherer wrote:
>>
>> ## Proposal
>>
>>
>> 1. allow to insert signature items anywhere in a module structure or
>> .ml file, giving a reasonable semantics to it
>>      (in particular allow inclusion of signature as a structure item,
>> with the derived semantics)
>
> This seems a quite reasonable feature for OCaml to have, as annotating the
> desired type of a declaration
>
>> 2. have a syntax to designate the mli signature from the ml file
>> (possible suggestion: "module type", used a signature expression)
>
> Eww.  This seems quite ugly, especially using the complex "with type foo =
> bar" syntax for something as common as giving the implementation of an
> abstract type.
>
>> It is also natural, in particular if you come from the world of C
>> prototypes and predeclared types, to wish to accept something like
>>    type u
>>    type u = int (* refining semantics *)
>> I think we should reject those because they have a muddier semantic
>> (you could define what the least abstract "unifier" of two definitions
>> would be, but let's net get down that road). The "S with type u = ..."
>> (in particular when S is "module type") allows to refine type in a
>> principle way without shadowing/redeclaration.
>
> Maybe it's my over-exposure to C++ lately, but I see a clear semantic for
> type re-declaration:
> 1) It is only allowed to re-declare types from the auto-import of a module
> signature
> 2) abstract types can be re-declared arbitrarily
> 3) private foo types can be re-declared to foo
> Nothing else can be re-declared.
>
> I might even go so far as to say that these re-declarations have to be at
> the top of the module definition; before any value declarations or private
> type declarations.  I see some use in forcing these to complete before
> normal compilation can proceed, to avoid the case of having to type a value
> before its concrete type is declared.
>
> module Foo = sig
>     type t
>     val x : t
> end = struct
>     let x = 5
>     type t = string
> end
>
> Rules like this should allow a module signature to have its typechecking
> effect on the associated module implementation as that module implementation
> is compiled and typechecked without needing a second pass over the inferred
> signature of the module to verify that the final result of the module is
> compatible.  Not that the second pass is a bad thing, but you're right that
> we will enable better error messages from a one-pass, local typing as
> opposed to a global structure comparison.
>
> E.

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

* Re: [Caml-list] Why should I use .mli files?
  2012-10-30  0:43 [Caml-list] Why should I use .mli files? Francois Berenger
                   ` (6 preceding siblings ...)
  2012-10-30 15:52 ` Didier Cassirame
@ 2012-10-31 15:32 ` Alain Frisch
  2012-10-31 17:32   ` Tiphaine Turpin
  7 siblings, 1 reply; 61+ messages in thread
From: Alain Frisch @ 2012-10-31 15:32 UTC (permalink / raw)
  To: Francois Berenger; +Cc: caml-list

On 10/30/2012 01:43 AM, Francois Berenger wrote:
> Here is my stupid question of the day:
> what's the use of those .mli files?

An argument which I haven't seen mentioned (but I did not read all the 
thread) is that providing an explicit .mli file give the compiler a 
chance to detect unused declarations (types, values) in your module 
(declarations which are not used internally and not exported).

FWIW, we have a tiny parser extension which allows us to put an 
interface on top of the current unit, without having to provide a proper 
.mli file.  This is used in our "addins", which typically register 
themselves into some kind of registry but don't export too many values 
otherwise (most often, none).  We can write:

   sig ... end
   .......

which is just sugar for:

include (.......  : sig ... end)


(without this extension, we would end up with many empty .mli files)


Alain

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

* Re: [Caml-list] Why should I use .mli files?
  2012-10-31 15:12                 ` Gabriel Scherer
@ 2012-10-31 16:48                   ` Edgar Friendly
  2012-10-31 17:15                     ` Gabriel Scherer
  0 siblings, 1 reply; 61+ messages in thread
From: Edgar Friendly @ 2012-10-31 16:48 UTC (permalink / raw)
  To: Gabriel Scherer; +Cc: caml-list

On 10/31/2012 11:12 AM, Gabriel Scherer wrote:
>> Maybe it's my over-exposure to C++ lately, but I see a clear semantic for
>> type re-declaration:
>> 1) It is only allowed to re-declare types from the auto-import of a module
>> signature
>> 2) abstract types can be re-declared arbitrarily
>> 3) private foo types can be re-declared to foo
>> Nothing else can be re-declared.
I missed one case:
4) any type can be re-declared as itself.
This uses up the one "re-declaration" that an auto-imported type is allowed.
> Why not. We even have a syntax for explicit type overriding: "type! u = int"!
> (But if you want to preserve backward-compatibility and still make the
> implicit inclusion of the interface in the implementation the default,
> you need to allow innocent-looking definitions to have a rebinding
> semantics.)
Yes, the backwards compatibility is key to my proposal; existing 
.ml+.mli files would re-declare everything, resulting in all types being 
as listed in the .ml file.
> I liked the idea of reusing the "with type ..." semantics instead of
> introducing a new feature, but if this proposal can get rid of the
> rather ad-hoc "module type" construct, you're trading one ad-hoc for
> another ad-hoc yet potentially simpler feature. I would be happy with
> such a langage feature.
I hope my solution is not only potentially simpler, but easier for 
people to use and more natural for people coming to OCaml from other 
languages where types are declared once.  It also allows us to sidestep 
the issue of type declarations and recursion, as it doesn't depend on 
any new syntax.

E.

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

* Re: [Caml-list] Why should I use .mli files?
  2012-10-31 16:48                   ` Edgar Friendly
@ 2012-10-31 17:15                     ` Gabriel Scherer
  2012-10-31 19:05                       ` Tiphaine Turpin
  0 siblings, 1 reply; 61+ messages in thread
From: Gabriel Scherer @ 2012-10-31 17:15 UTC (permalink / raw)
  To: Edgar Friendly; +Cc: caml-list

On Wed, Oct 31, 2012 at 6:32 PM, Tiphaine Turpin
<Tiphaine.Turpin@free.fr> wrote:
> Here is another proposal on this type topic : why not change the
> semantics of module type inclusion to consider missing types (and module
> types as well) as if they were declared with the same definition ? In
> other words, a signature S would be a subtype of S' if there exists some
> set of type declarations which, if prepended to S, make it have the type
> S' in the usual sense ? Exactly as [> `a ] is a subtype of [> `a | `b ]
> for polymorphic variants.

The problem with this idea is that you cannot ask yourself if "the
signature S (coming from the .mli) is a subtype of the signature S'
(coming from the .ml)" if the .ml, or the module definition, cannot be
type-checked without information coming from S. (S') doesn't exist
here, as the implementation cannot be type-checked by itself.

What you would need to do is recognize a contextual situation where
you type-check an implementation *given* a known signature context
(just as we extended type-checking expression to know about the
expected type for GADTs in 4.00), instead of type-checking it by
itself. This is essentially equivalent to the design considerations of
the (module type) feature that only makes sense in the context of a
larger signature sealing, only you're doing it implicitly.

(I think that once you realize that, you end up with something
equivalent to Edgar's proposal.)

On Wed, Oct 31, 2012 at 5:48 PM, Edgar Friendly <thelema314@gmail.com> wrote:
> I hope my solution is not only potentially simpler, but easier for people to
> use and more natural for people coming to OCaml from other languages where
> types are declared once.  It also allows us to sidestep the issue of type
> declarations and recursion, as it doesn't depend on any new syntax.

Convincing. I'll fight for having signature items usable in structures
(and forward references) another day, consider me a supporter of your
thought experiment.


On Wed, Oct 31, 2012 at 5:48 PM, Edgar Friendly <thelema314@gmail.com> wrote:
> On 10/31/2012 11:12 AM, Gabriel Scherer wrote:
>>>
>>> Maybe it's my over-exposure to C++ lately, but I see a clear semantic for
>>> type re-declaration:
>>> 1) It is only allowed to re-declare types from the auto-import of a
>>> module
>>> signature
>>> 2) abstract types can be re-declared arbitrarily
>>> 3) private foo types can be re-declared to foo
>>> Nothing else can be re-declared.
>
> I missed one case:
> 4) any type can be re-declared as itself.
> This uses up the one "re-declaration" that an auto-imported type is allowed.
>
>> Why not. We even have a syntax for explicit type overriding: "type! u =
>> int"!
>> (But if you want to preserve backward-compatibility and still make the
>> implicit inclusion of the interface in the implementation the default,
>> you need to allow innocent-looking definitions to have a rebinding
>> semantics.)
>
> Yes, the backwards compatibility is key to my proposal; existing .ml+.mli
> files would re-declare everything, resulting in all types being as listed in
> the .ml file.
>
>> I liked the idea of reusing the "with type ..." semantics instead of
>> introducing a new feature, but if this proposal can get rid of the
>> rather ad-hoc "module type" construct, you're trading one ad-hoc for
>> another ad-hoc yet potentially simpler feature. I would be happy with
>> such a langage feature.
>
> I hope my solution is not only potentially simpler, but easier for people to
> use and more natural for people coming to OCaml from other languages where
> types are declared once.  It also allows us to sidestep the issue of type
> declarations and recursion, as it doesn't depend on any new syntax.
>
> E.

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

* Re: [Caml-list] Why should I use .mli files?
  2012-10-31 15:32 ` Alain Frisch
@ 2012-10-31 17:32   ` Tiphaine Turpin
  2012-10-31 21:40     ` Oliver Bandel
  0 siblings, 1 reply; 61+ messages in thread
From: Tiphaine Turpin @ 2012-10-31 17:32 UTC (permalink / raw)
  To: caml-list

I personally find that the most useful of the missing features that have
been addressed here is the ability to write type definitions only once,
when using interfaces (in particular mi files). Type annotations
(especially with explicit polymorphism) are sufficient for the "value
declaration" concern, in my opinion.

Here is another proposal on this type topic : why not change the
semantics of module type inclusion to consider missing types (and module
types as well) as if they were declared with the same definition ? In
other words, a signature S would be a subtype of S' if there exists some
set of type declarations which, if prepended to S, make it have the type
S' in the usual sense ? Exactly as [> `a ] is a subtype of [> `a | `b ]
for polymorphic variants.

I don't know if a sound semantics can be found for such a thing
(especially since type declarations can refer to each other, unlike
tags) but this would definitely be a backward-compatible modification
(which we still may want to enable only with a command-line flag).

Tiphaine


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

* Re: [Caml-list] Why should I use .mli files?
  2012-10-31 17:15                     ` Gabriel Scherer
@ 2012-10-31 19:05                       ` Tiphaine Turpin
  0 siblings, 0 replies; 61+ messages in thread
From: Tiphaine Turpin @ 2012-10-31 19:05 UTC (permalink / raw)
  To: caml-list

On 10/31/12 18:15, Gabriel Scherer wrote:
> On Wed, Oct 31, 2012 at 6:32 PM, Tiphaine Turpin
> <Tiphaine.Turpin@free.fr> wrote:
>> Here is another proposal on this type topic : why not change the
>> semantics of module type inclusion to consider missing types (and module
>> types as well) as if they were declared with the same definition ? In
>> other words, a signature S would be a subtype of S' if there exists some
>> set of type declarations which, if prepended to S, make it have the type
>> S' in the usual sense ? Exactly as [> `a ] is a subtype of [> `a | `b ]
>> for polymorphic variants.
> The problem with this idea is that you cannot ask yourself if "the
> signature S (coming from the .mli) is a subtype of the signature S'
> (coming from the .ml)" if the .ml, or the module definition, cannot be
> type-checked without information coming from S. (S') doesn't exist
> here, as the implementation cannot be type-checked by itself.
I realize that I overlooked a detail in my suggestion: fields and
constructors names must be declared before they are used in expressions
and patterns... The idea works well for polymorphic variant types and
objects, with their structural typing. Here is an example:

a.ml:
    let f = function `a | `b -> ()

a.mli:
    type t = [`a | `b]
    val f : t -> unit

You can infer the signature

"sig val f : [< `a | `b ] -> unit end"

for a.ml, and then check that it is a subtype (in the non-conventional
sense) of a.mli

This doesn't mean that it is impossible to adapt this for record and
variant types (at the cost of implicit field and constructor
declaration), but you are right, a "contextual" typing seems more
natural. However, this doesn't fit well with the module system of OCaml,
where a module type can be declared a subtype of several others, and
this subtyping can happen anytime "after" the definition of the first
module type. So this could only be an ad hoc trick for toplevel modules,
which is seems much less appealing to me (maybe its my under-exposure to
C++).

Tiphaine


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

* Re: [Caml-list] Why should I use .mli files?
  2012-10-30 15:52 ` Didier Cassirame
  2012-10-30 15:56   ` Romain Bardou
@ 2012-10-31 21:30   ` Oliver Bandel
  2012-11-01 15:26     ` Didier Cassirame
  1 sibling, 1 reply; 61+ messages in thread
From: Oliver Bandel @ 2012-10-31 21:30 UTC (permalink / raw)
  To: Didier Cassirame; +Cc: Francois Berenger, caml-list



Am 30.10.2012 um 16:52 schrieb Didier Cassirame <didier.cassirame@gmail.com>:

> 
> Thinking about it, there's at least one case where mli files are not so useful: When you have several modules which must all comply with a certain module type. In that case, all the mli files would be identical, and a modification of the module type would necessitate to change all the .mli.

Sounds like you reformulated an advantagenas being a disadvantage.
If someone changes a type of a module by accident, it,will pop up as
problem.
Also I wonder, if a type that is used by other modules
might not also need to change the mplementation.

I think it depends on the kind of change.

Maybe you can provide an example.


Somehow the discussion looks a bit like
changing the interface often to be a sport
for programmers.
I remember times, when it was a good idea tomchange interfaces
as seldom as possible.
But modern times bring modern behaviour.

Maybe soon there will be a fast-interface-change contest.

One big advantage of mli-files is, to carve the interface in stone.

So even I mostly used OCaml only for my own small projects,
in a big project with many developers, it would make sense
that the team will plan the interface, and when the decisionis done,
the project leader or a certain person who is responsible for
mantaining the nterfaces, will create the file and has
rw-permissions, and the other developers only have group-readability.
So then they have to use the interface as it was agreed upon.

And the one who wants to implement furthe things can omit the mli file for a while,
but if the code does not compile with the official mli-file,
the code will be rejected.

I think this is a valuable tool, the mli can provide clear interfaces,
and this is working well wirh many developers.
And if changing of intefcüace really can't be avoided,
it will need a team meeting on intercace change.

Thats totally different to lets-change-they-interface-as-often-as-possible
contest behaviour.


Best wishes,
    Oliver


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

* Re: [Caml-list] Why should I use .mli files?
  2012-10-31 17:32   ` Tiphaine Turpin
@ 2012-10-31 21:40     ` Oliver Bandel
  0 siblings, 0 replies; 61+ messages in thread
From: Oliver Bandel @ 2012-10-31 21:40 UTC (permalink / raw)
  To: Tiphaine Turpin; +Cc: caml-list



Am 31.10.2012 um 18:32 schrieb Tiphaine Turpin <Tiphaine.Turpin@free.fr>:

> I personally find that the most useful of the missing features that have
> been addressed here is the ability to write type definitions only once,
> when using interfaces (in particular mi files). Type annotations
> (especially with explicit polymorphism) are sufficient for the "value
> declaration" concern, in my opinion.

Not sure if I see the argument.
When should type declarations be written more than once?

I mean.. inside the ml file, there is the detail,
and itncannbe repeated, but that also can be done with 
ocamlc -i
But when an abstractbtype is used, it needs the concrete implementation
( is t an int or string or what else? ) and the abstract declaration.
So they differ.
If they do not differ, ocamlc -i can be used, going from ml to mli.


Ciao,
 Oliver

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

* Re: [Caml-list] Why should I use .mli files?
  2012-10-31 13:43                       ` Gabriel Scherer
@ 2012-11-01  0:38                         ` Francois Berenger
  2012-11-01  0:42                           ` Edgar Friendly
  0 siblings, 1 reply; 61+ messages in thread
From: Francois Berenger @ 2012-11-01  0:38 UTC (permalink / raw)
  To: caml-list

On 10/31/2012 10:43 PM, Gabriel Scherer wrote:
>> [...]
> (On the other side, I must note that your argument that ".ml/.mli
> redundancy should be handled by tooling" could be reused in the
> converse direction: the .mli (including documentation if present in
> the source) could be produced from the .ml by tooling.

I think that's the kind of tool that would entice me
to use .mli files.

How does this tool would know that some types from the .ml
file are not to be exported in the .mli?

Also, this tool should probably be able to update a .mli file,
detect that a .mli file needs to be updated and maybe other things.

It gives me the impression that with such a tool
people would no more need to maintain both a .ml
and a .mli file. I like the "centralization" of it.

Regards,
F.


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

* Re: [Caml-list] Why should I use .mli files?
  2012-11-01  0:38                         ` Francois Berenger
@ 2012-11-01  0:42                           ` Edgar Friendly
  2012-11-01  0:52                             ` Francois Berenger
  0 siblings, 1 reply; 61+ messages in thread
From: Edgar Friendly @ 2012-11-01  0:42 UTC (permalink / raw)
  To: caml-list

On 10/31/2012 8:38 PM, Francois Berenger wrote:
> It gives me the impression that with such a tool
> people would no more need to maintain both a .ml
> and a .mli file. I like the "centralization" of it.
It's exactly the opposite that drives people to use .mli files; by 
having a separation between interface and implementation, it's easier 
for people to dig through interfaces to find what's available, instead 
of having to dig through the much lengthier implementation.

E.

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

* Re: [Caml-list] Why should I use .mli files?
  2012-11-01  0:42                           ` Edgar Friendly
@ 2012-11-01  0:52                             ` Francois Berenger
  2012-11-01  2:06                               ` Edgar Friendly
  0 siblings, 1 reply; 61+ messages in thread
From: Francois Berenger @ 2012-11-01  0:52 UTC (permalink / raw)
  To: caml-list

On 11/01/2012 09:42 AM, Edgar Friendly wrote:
> On 10/31/2012 8:38 PM, Francois Berenger wrote:
>> It gives me the impression that with such a tool
>> people would no more need to maintain both a .ml
>> and a .mli file. I like the "centralization" of it.
> It's exactly the opposite that drives people to use .mli files; by
> having a separation between interface and implementation, it's easier
> for people to dig through interfaces to find what's available, instead
> of having to dig through the much lengthier implementation.

If the .mli is generated automatically from the .ml,
including documentation, people can still read their dear
.mli file (once it has been generated).

Maybe the tool should also be able to detect in an efficient manner
that a .mli file is up to date.

And people can still write interface files by writing .ml files
where all implementation is left to 'failwith "not implemented yet"'.

Regards,
F.


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

* Re: [Caml-list] Why should I use .mli files?
  2012-11-01  0:52                             ` Francois Berenger
@ 2012-11-01  2:06                               ` Edgar Friendly
  2012-11-01  2:37                                 ` Francois Berenger
  2012-11-01  2:44                                 ` Jacques Garrigue
  0 siblings, 2 replies; 61+ messages in thread
From: Edgar Friendly @ 2012-11-01  2:06 UTC (permalink / raw)
  To: caml-list

On 10/31/2012 8:52 PM, Francois Berenger wrote:
> If the .mli is generated automatically from the .ml,
> including documentation, people can still read their dear
> .mli file (once it has been generated). 
Why bother generating a .mli file if this is the only goal; instead, 
just use ocamldoc to build documentation exactly for the exported 
interface.  But this still needs some backwards-compatible magic to 
indicate the public interface in the .ml file, and I don't think we have 
a good solution to this at the moment.

E.

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

* Re: [Caml-list] Why should I use .mli files?
  2012-11-01  2:06                               ` Edgar Friendly
@ 2012-11-01  2:37                                 ` Francois Berenger
  2012-11-01  2:44                                 ` Jacques Garrigue
  1 sibling, 0 replies; 61+ messages in thread
From: Francois Berenger @ 2012-11-01  2:37 UTC (permalink / raw)
  To: caml-list

On 11/01/2012 11:06 AM, Edgar Friendly wrote:
> On 10/31/2012 8:52 PM, Francois Berenger wrote:
>> If the .mli is generated automatically from the .ml,
>> including documentation, people can still read their dear
>> .mli file (once it has been generated).
> Why bother generating a .mli file if this is the only goal;

 From what I understood from previous posts, .mli files
also accelerate compilation of large projects by preventing
recompilation of some things when there is an implementation
change without an interface change.

So, I understand they don't have a "documentation"-only goal.

 > instead,
> just use ocamldoc to build documentation exactly for the exported
> interface.

I guess my friend Daniel Bunzli will want to do this. ;)

 > But this still needs some backwards-compatible magic to
> indicate the public interface in the .ml file, and I don't think we have
> a good solution to this at the moment.

I am not advocating for the disappearance of .mli files.

I just don't want to have to bother with them manually
or have to maintain them because to me everything
can be said in a central place, the .ml file.
But that's just my personal taste.

Regards,
F.


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

* Re: [Caml-list] Why should I use .mli files?
  2012-11-01  2:06                               ` Edgar Friendly
  2012-11-01  2:37                                 ` Francois Berenger
@ 2012-11-01  2:44                                 ` Jacques Garrigue
  2012-11-01  7:45                                   ` Andreas Rossberg
  1 sibling, 1 reply; 61+ messages in thread
From: Jacques Garrigue @ 2012-11-01  2:44 UTC (permalink / raw)
  To: OCaml List

Wow.
I see that a big debate is going on mli files and declarations
inside ml files.

I think that lots of people have given this problem a lot of thought
during many years.
My conclusion has unfortunately been that trying to solve this at
the language level without breaking backward compatibility is
very difficult.

For instance, one is currently allowed to do something like that:

a.ml:
let f x = x

let b = f true

a.mli:
val f: int -> int

This may look stupid, but this kind of code (of course more
complicated) exists in the wild, and sometimes for sensible
reasons.
For this kind of reason, I do not see any easy way to import
information from mli files to ml files.

Now, is maintaining mli files really painful?
In my experience, not at all.
Taking as example the ocaml compiler itself, the only
duplication that bothers me a little is the error type exported
by many modules, as one always has to keep it in sync by
copy-paste. This is a bit of a problem because for most uses
this type could be abstract (you don't really care about its
contents), but in some rare occasions you need it public.
For other types,  do not see syncing as a disadvantage, because
it rather makes you conscious that other modules depend on
this type, so better look at it twice :-)

Of course I know that some people (probably with a different
background) do not like mli files.
Couldn't we just imagine a preprocessing tool that allows to
generate both ml and mli from the same file?
This is pretty standard for literate programming.
It could even call the compiler if you want the types to be inferred
automatically (even though I personally think that having to write
value types in the mli file is good, because you know when you
are changing an export.)
As an external tool, it could use pragmas (keywords inside
comments) for instance.
Something close to ocamldoc (ocamldoc itself?) but which you
would integrate in the compilation cycle.

Anyway, I just wanted to state, from my experience, my lack of
enthusiasm about modifying the core language to accommodate
that.

Jacques Garrigue

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

* Re: [Caml-list] Why should I use .mli files?
  2012-11-01  2:44                                 ` Jacques Garrigue
@ 2012-11-01  7:45                                   ` Andreas Rossberg
  0 siblings, 0 replies; 61+ messages in thread
From: Andreas Rossberg @ 2012-11-01  7:45 UTC (permalink / raw)
  To: OCaml List

On Nov 1, 2012, at 03.44 h, Jacques Garrigue wrote:
> Wow.
> I see that a big debate is going on mli files and declarations
> inside ml files.
>
> I think that lots of people have given this problem a lot of thought
> during many years.
>
> [...]
>
> Now, is maintaining mli files really painful?
> In my experience, not at all.

I strongly second that. Separation of interface and implementation _is  
a feature_! In fact, it is one of the high marks of ML modules (as  
opposed to, say, privacy in Java classes, let alone the mess that is C/ 
C++ style header files). Its semantics is simple but powerful.

The separation improves modularity by naturally encouraging  
abstraction, low coupling, and documentation. Better modularity makes  
for better maintainability. And the separation makes code more  
readable -- which, as others have noted, is 10 times more important  
than making it more writable, for anything but trivial projects (i.e.,  
anything where modules are actually needed).

No doubt you can find cases where the redundancy is unfortunate.  
Mainly these are ones involving larger data type definitions that  
refer to abstract types from the same module, and hence cannot easily  
be factored out into a separate module. But in my experience, such  
cases are rare, and the minor inconvenience is far outweighed by the  
overall benefits.

/Andreas


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

* Re: [Caml-list] Why should I use .mli files?
  2012-10-31 21:30   ` Oliver Bandel
@ 2012-11-01 15:26     ` Didier Cassirame
  0 siblings, 0 replies; 61+ messages in thread
From: Didier Cassirame @ 2012-11-01 15:26 UTC (permalink / raw)
  To: Oliver Bandel; +Cc: Francois Berenger, caml-list

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

2012/10/31 Oliver Bandel <oliver@first.in-berlin.de>

>
>
> Am 30.10.2012 um 16:52 schrieb Didier Cassirame <
> didier.cassirame@gmail.com>:
>
> >
> > Thinking about it, there's at least one case where mli files are not so
> useful: When you have several modules which must all comply with a certain
> module type. In that case, all the mli files would be identical, and a
> modification of the module type would necessitate to change all the .mli.
>
> Sounds like you reformulated an advantagenas being a disadvantage.
> If someone changes a type of a module by accident, it,will pop up as
> problem.
> Also I wonder, if a type that is used by other modules
> might not also need to change the mplementation.
>

Yes, reading my words now, maybe the wording wasn't that great.
When you're using functors, you usually expect a very specific interface
for lifted modules. In fact, it's not so clear cut, but I think it's good
practice to conform the lifted modules to the module type that the functor
expects. Ah, also, one cannot make a functor of a ml/mli file.

That's the kind of situation I was thinking about, because I more or less
had the problem, for one of my projects. I am still not sure about the best
way to split the code in several files (The practice for functors is to
have a Make functor within the module, which is Ok, but if I want to have
each module in its own file, I don't know how to do it properly).

didier

[-- Attachment #2: Type: text/html, Size: 1884 bytes --]

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

* Re: [Caml-list] Why should I use .mli files?
       [not found]         ` <fa.KulHINoVpgjN1uI63QvwcxoNuiY@ifi.uio.no>
@ 2012-11-01 11:38           ` Radu Grigore
  0 siblings, 0 replies; 61+ messages in thread
From: Radu Grigore @ 2012-11-01 11:38 UTC (permalink / raw)
  To: fa.caml; +Cc: caml-list

On Thursday, November 1, 2012 12:40:03 AM UTC, Francois Berenger wrote:
> How does this tool would know that some types from the .ml
> file are not to be exported in the .mli?

Sometimes, I use this brain-dead script:
  https://github.com/seplogic/jstar/blob/master/scripts/unused.ml

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

* Re: [Caml-list] Why should I use .mli files?
       [not found] <fa.4zzWyGZIo+GsGOz7cSC34yWTunY@ifi.uio.no>
@ 2012-10-31 14:32 ` Radu Grigore
       [not found] ` <fa.pEEaqh4bLDLiRdYkCRHvi9787TQ@ifi.uio.no>
  1 sibling, 0 replies; 61+ messages in thread
From: Radu Grigore @ 2012-10-31 14:32 UTC (permalink / raw)
  To: fa.caml; +Cc: caml-list

On Tuesday, October 30, 2012 12:44:27 AM UTC, Francois Berenger wrote:
> what's the use of those .mli files?

They are good for documentation.  Most projects don't fit in one human head, at any one moment.  When you approach code that is new to you or that you forgot, it is helpful to know which are the important bits.  MLI files are one good mechanism to point to the important parts of a big module.  I read MLI files like this: "Out of these 60 functions you are most likely to need these 3."

If an MLI file is big, then it fails to identify the important parts.  Those big MLI files are also annoying to maintain.  So, just don't write big MLI files.  The one case where MLIs tend to be big is when the module includes many type declarations.  In that case you can often pull out all type declarations into a separate ML file, which you *don't* pair up with an MLI file.

On a more advanced level, you need interfaces when you mess around with functors.  But, playing with functors in OCaml feels a bit like playing with templates in C++ or with Arrows in Haskell: more seductive than productive.

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

end of thread, other threads:[~2012-11-01 15:27 UTC | newest]

Thread overview: 61+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-10-30  0:43 [Caml-list] Why should I use .mli files? Francois Berenger
2012-10-30  1:04 ` Peter Groves
2012-10-30  2:21   ` Francois Berenger
2012-10-30  1:15 ` malc
2012-10-30  2:24   ` Francois Berenger
2012-10-30 10:23     ` malc
2012-10-30  1:19 ` Daniel Bünzli
2012-10-30  2:36   ` Francois Berenger
2012-10-30  3:26     ` Anthony Tavener
2012-10-30 12:28     ` Daniel Bünzli
2012-10-31  0:53       ` Francois Berenger
2012-10-30  2:21 ` gallais @ ensl.org
2012-10-30  6:12 ` Anton Lavrik
2012-10-30  9:18   ` Francois Berenger
2012-10-30 10:01     ` Malcolm Matalka
2012-10-30 11:03     ` Richard W.M. Jones
2012-10-30 11:41     ` [Caml-list] " Hongbo Zhang
2012-10-30 13:31       ` Romain Bardou
2012-10-31  1:03         ` Francois Berenger
2012-10-31  1:44           ` Daniel Bünzli
2012-10-31  9:51             ` Oliver Bandel
2012-10-30 14:32   ` [Caml-list] " Oliver Bandel
2012-10-30 14:45     ` Anton Lavrik
2012-10-30 14:49       ` Oliver Bandel
2012-10-30 14:51       ` Didier Cassirame
2012-10-30 14:47     ` Romain Bardou
2012-10-30 16:06       ` Edgar Friendly
2012-10-30 16:21         ` Romain Bardou
2012-10-30 16:46           ` Edgar Friendly
2012-10-30 21:25             ` Gabriel Scherer
2012-10-30 22:18               ` Oliver Bandel
2012-10-31  9:25                 ` Gabriel Scherer
2012-10-31  9:59                   ` Daniel Bünzli
2012-10-31 13:22                     ` Edgar Friendly
2012-10-31 13:38                       ` Daniel Bünzli
2012-10-31 13:55                         ` Edgar Friendly
2012-10-31 13:43                       ` Gabriel Scherer
2012-11-01  0:38                         ` Francois Berenger
2012-11-01  0:42                           ` Edgar Friendly
2012-11-01  0:52                             ` Francois Berenger
2012-11-01  2:06                               ` Edgar Friendly
2012-11-01  2:37                                 ` Francois Berenger
2012-11-01  2:44                                 ` Jacques Garrigue
2012-11-01  7:45                                   ` Andreas Rossberg
2012-10-31 10:20               ` Alain Frisch
2012-10-31 13:50               ` Edgar Friendly
2012-10-31 15:12                 ` Gabriel Scherer
2012-10-31 16:48                   ` Edgar Friendly
2012-10-31 17:15                     ` Gabriel Scherer
2012-10-31 19:05                       ` Tiphaine Turpin
2012-10-30  7:43 ` Mike Lin
2012-10-30 15:52 ` Didier Cassirame
2012-10-30 15:56   ` Romain Bardou
2012-10-30 16:14     ` Didier Cassirame
2012-10-31 21:30   ` Oliver Bandel
2012-11-01 15:26     ` Didier Cassirame
2012-10-31 15:32 ` Alain Frisch
2012-10-31 17:32   ` Tiphaine Turpin
2012-10-31 21:40     ` Oliver Bandel
     [not found] <fa.4zzWyGZIo+GsGOz7cSC34yWTunY@ifi.uio.no>
2012-10-31 14:32 ` Radu Grigore
     [not found] ` <fa.pEEaqh4bLDLiRdYkCRHvi9787TQ@ifi.uio.no>
     [not found]   ` <fa.JtZOlOTbNCp6rOoRnHhKEARwLDQ@ifi.uio.no>
     [not found]     ` <fa.s4gDOdOTZVbthjceZ5OEMxHiH90@ifi.uio.no>
     [not found]       ` <fa.rfsHI3X48Zri1S2pu1SEFowmDZg@ifi.uio.no>
     [not found]         ` <fa.KulHINoVpgjN1uI63QvwcxoNuiY@ifi.uio.no>
2012-11-01 11:38           ` Radu Grigore

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).