caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
* RE: [Caml-list] recursive modules redux, & interface files
@ 2001-03-22 11:55 Dave Berry
  2001-03-22 12:01 ` Markus Mottl
  2001-03-27  6:29 ` John Max Skaller
  0 siblings, 2 replies; 42+ messages in thread
From: Dave Berry @ 2001-03-22 11:55 UTC (permalink / raw)
  To: Markus Mottl, John Max Skaller; +Cc: Chris Hecker, caml-list

Pardon me if this is a dumb question, but what is the difference between
"include" and "open"?

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

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

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


^ permalink raw reply	[flat|nested] 42+ messages in thread
* RE: [Caml-list] recursive modules redux, & interface files
@ 2001-03-27 17:05 Manuel Fahndrich
  0 siblings, 0 replies; 42+ messages in thread
From: Manuel Fahndrich @ 2001-03-27 17:05 UTC (permalink / raw)
  To: caml-list

To add more fuel to this interesting conversation, I've recently come
across a nice analogy between recursive modules and the assume-guarantee
rules known from model checking. The assume-guarantee rule in model
checking allows models to be checked relatively independently. In
general, the AG rule takes on the form

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

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

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

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

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

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

contains such a circular definition, whereas 

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

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

Regards,

-Manuel Fahndrich
 

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

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

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

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

Cheers,

- Xavier Leroy
-------------------
To unsubscribe, mail caml-list-request@inria.fr.  Archives:
http://caml.inria.fr
-------------------
To unsubscribe, mail caml-list-request@inria.fr.  Archives: http://caml.inria.fr


^ permalink raw reply	[flat|nested] 42+ messages in thread
* RE: [Caml-list] recursive modules redux, & interface files
@ 2001-03-27 14:38 Don Syme
  0 siblings, 0 replies; 42+ messages in thread
From: Don Syme @ 2001-03-27 14:38 UTC (permalink / raw)
  To: Xavier Leroy; +Cc: caml-list

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

Yes, sorry.

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

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

Cheers,
Don
-------------------
To unsubscribe, mail caml-list-request@inria.fr.  Archives: http://caml.inria.fr


^ permalink raw reply	[flat|nested] 42+ messages in thread
* RE: [Caml-list] recursive modules redux, & interface files
@ 2001-03-23 20:33 Don Syme
  2001-03-27  9:00 ` Xavier Leroy
  0 siblings, 1 reply; 42+ messages in thread
From: Don Syme @ 2001-03-23 20:33 UTC (permalink / raw)
  To: Xavier Leroy, Chris Hecker; +Cc: caml-list

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


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

foo.mli:

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

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

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

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

However, this would not solve the problem:

    A.mli    val x : int                B.mli    val y : int
    A.ml     let x = B.y                B.ml     let y = A.x

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

Cheers,
Don
-------------------
To unsubscribe, mail caml-list-request@inria.fr.  Archives: http://caml.inria.fr


^ permalink raw reply	[flat|nested] 42+ messages in thread
* RE: [Caml-list] recursive modules redux, & interface files
@ 2001-03-23 10:33 Dave Berry
  0 siblings, 0 replies; 42+ messages in thread
From: Dave Berry @ 2001-03-23 10:33 UTC (permalink / raw)
  To: Tom.Hirschowitz, caml-list

I'd say that the module Ten would have to include a declaration of the
sub-module PLAYER.

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


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

Just curious, but how would you treat this?

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

module Ten = 
  struct 
    includesig TEN
    ...
  end

Reject?

Friendly, 

Tom

Dave Berry a écrit :
> 
> To be more general, perhaps specifications could be interleaved with
> declarations in modules.  In addition to including entire structures,
> this would let you specify the type of a function separately from it's
> implementation:
> 
> val map: ('a -> 'b) -> 'a list -> 'b list
> let rec map f l =
>   match ...
> 
> This is one aspect I like about Haskell's syntax.  I find it clearer
> than the current:
> 
> let rec map (f: 'a -> 'b) (l: 'a list) =
>   match ...
> 
> 
> type coleur = Rouge | Vert | Bleu
> (both type and implementation exported)
> 
> type animal
> type animal = Chien | Chat | Oiseau
> (only the type is visible outside the module)
> 
> I've no idea how easy or hard it would be to incorporate this into
> either the semantics or the implementation of the language.  But from
a
> pragmatic point of view, it seems a relatively clean change.
> 
> Dave.
> 
> -----Original Message-----
> From: Hendrik Tews [mailto:tews@tcs.inf.tu-dresden.de]
> Sent: Thursday, March 22, 2001 12:03
> To: caml-list@inria.fr
> Subject: Re: [Caml-list] recursive modules redux, & interface files
> 
> What about changing
> include, such that including a signature into a structure
> includes all types and all exceptions?
> 
> -------------------
> To unsubscribe, mail caml-list-request@inria.fr.  Archives:
http://caml.inria.fr
-------------------
To unsubscribe, mail caml-list-request@inria.fr.  Archives: http://caml.inria.fr


^ permalink raw reply	[flat|nested] 42+ messages in thread
* RE: [Caml-list] recursive modules redux, & interface files
@ 2001-03-22 18:04 Dave Berry
  2001-03-23  7:54 ` Tom Hirschowitz
  0 siblings, 1 reply; 42+ messages in thread
From: Dave Berry @ 2001-03-22 18:04 UTC (permalink / raw)
  To: Hendrik Tews, caml-list

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

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

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

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

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

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

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

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

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

Dave.


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

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

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


^ permalink raw reply	[flat|nested] 42+ messages in thread
* [Caml-list] recursive modules redux, & interface files
@ 2001-03-18 23:05 Chris Hecker
  2001-03-19  0:01 ` Brian Rogoff
                   ` (2 more replies)
  0 siblings, 3 replies; 42+ messages in thread
From: Chris Hecker @ 2001-03-18 23:05 UTC (permalink / raw)
  To: caml-list


Two questions/problems:

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

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

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

Thanks,
Chris

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

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

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


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

end of thread, other threads:[~2001-04-05 17:47 UTC | newest]

Thread overview: 42+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2001-03-22 11:55 [Caml-list] recursive modules redux, & interface files Dave Berry
2001-03-22 12:01 ` Markus Mottl
2001-03-27  6:29 ` John Max Skaller
  -- strict thread matches above, loose matches on Subject: below --
2001-03-27 17:05 Manuel Fahndrich
2001-03-27 14:38 Don Syme
2001-03-23 20:33 Don Syme
2001-03-27  9:00 ` Xavier Leroy
2001-03-23 10:33 Dave Berry
2001-03-22 18:04 Dave Berry
2001-03-23  7:54 ` Tom Hirschowitz
2001-03-23 12:18   ` Fabrice Le Fessant
2001-03-27  8:49   ` Hendrik Tews
2001-03-18 23:05 Chris Hecker
2001-03-19  0:01 ` Brian Rogoff
2001-03-19 11:04 ` John Max Skaller
2001-03-19 11:41   ` Chris Hecker
2001-03-20 17:43     ` John Max Skaller
2001-03-21  4:03       ` Chris Hecker
2001-03-21  5:10         ` Patrick M Doane
2001-03-21  9:27           ` Chris Hecker
2001-03-21 18:20           ` John Max Skaller
2001-03-22  0:03             ` Patrick M Doane
2001-03-22  0:22               ` Brian Rogoff
2001-03-22  9:11               ` Francois Pottier
2001-03-21 23:24           ` John Prevost
2001-03-22  0:00             ` Patrick M Doane
2001-03-21 18:18         ` John Max Skaller
2001-03-21 18:19         ` John Max Skaller
2001-03-22 11:40   ` Markus Mottl
2001-03-21 18:41 ` Xavier Leroy
2001-03-22  0:23   ` Patrick M Doane
2001-03-22 12:02   ` Hendrik Tews
2001-03-22 13:01     ` Markus Mottl
2001-03-22 16:56       ` Brian Rogoff
2001-03-22 17:13         ` Daniel de Rauglaudre
2001-03-23 17:30         ` Fergus Henderson
2001-03-23 18:04           ` Brian Rogoff
2001-03-26  2:29             ` Fergus Henderson
2001-03-27 22:11         ` John Max Skaller
2001-03-28  4:30           ` Brian Rogoff
2001-04-05 17:07             ` John Max Skaller
2001-03-27  8:21       ` Hendrik Tews

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