caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
* Rephrasing of dynamic module selection problem
@ 2006-02-21  0:54 Nathan Cooprider
  2006-02-21  3:49 ` "ocaml_beginners"::[] " Martin Jambon
                   ` (2 more replies)
  0 siblings, 3 replies; 5+ messages in thread
From: Nathan Cooprider @ 2006-02-21  0:54 UTC (permalink / raw)
  To: ocaml_beginners, caml-list

So I am still trying to get modules to be dynamically (run-time) 
selectable instead of only statically (compile-time). The closest I have 
come to so far is bellow. I want to be able to choose between a set of 
modules (hello1 and hello2 in this example) fairly transparently.

[coop@ender example]$ cat hello1.ml
type t = int
let of_int i =
  i
let print i =
  print_int i;
  print_string " says Hello1\n"

[coop@ender example]$ cat hello2.ml
type t = float
let of_int i =
  float_of_int i
let print i =
  print_float i;
  print_string " says Hello2\n"

[coop@ender example]$ cat main.ml
module Hello1 = struct
  #include "hello1.ml"
end ;;
module Hello2 = struct
  #include "hello2.ml"
end ;;
(* This works . . . *)
module H = Hello1
(* But I would like this to be something like this instead:
let parameter = 1
module H =
  match parameter with
    1 -> Hello1
  | _ -> Hello2
 *)

let argument = 42
let main () =
  H.print (H.of_int argument) ;;
main ();;

[coop@ender example]$ cpp main.ml > foo.ml ; ocamlc foo.ml ; rm foo.ml ; 
a.out
42 says Hello1

In my real application, there are five different modules (and I am 
adding more after I get this working) and they have around fifty 
functions in them.

Nathan


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

* Re: "ocaml_beginners"::[] Rephrasing of dynamic module selection problem
  2006-02-21  0:54 Rephrasing of dynamic module selection problem Nathan Cooprider
@ 2006-02-21  3:49 ` Martin Jambon
  2006-02-21  3:55 ` [Caml-list] " brogoff
  2006-02-21  9:55 ` Virgile Prevosto
  2 siblings, 0 replies; 5+ messages in thread
From: Martin Jambon @ 2006-02-21  3:49 UTC (permalink / raw)
  To: ocaml_beginners; +Cc: caml-list

On Mon, 20 Feb 2006, Nathan Cooprider wrote:

> So I am still trying to get modules to be dynamically (run-time)
> selectable instead of only statically (compile-time). The closest I have
> come to so far is bellow. I want to be able to choose between a set of
> modules (hello1 and hello2 in this example) fairly transparently.
>
> [coop@ender example]$ cat hello1.ml
> type t = int
> let of_int i =
>  i
> let print i =
>  print_int i;
>  print_string " says Hello1\n"
>
> [coop@ender example]$ cat hello2.ml
> type t = float
> let of_int i =
>  float_of_int i
> let print i =
>  print_float i;
>  print_string " says Hello2\n"
>
> [coop@ender example]$ cat main.ml
> module Hello1 = struct
>  #include "hello1.ml"
> end ;;
> module Hello2 = struct
>  #include "hello2.ml"
> end ;;
> (* This works . . . *)
> module H = Hello1
> (* But I would like this to be something like this instead:
> let parameter = 1
> module H =
>  match parameter with
>    1 -> Hello1
>  | _ -> Hello2
> *)

That's not possible because Hello1 and Hello2 don't have the same "type" 
(same module signature though): what I mean is that if you represent them 
as objects, the objects would have different types since Hello1.t and 
Hello2.t are incompatible.

Try the following code (which fails when I try to mix the objects):

module type HELLO =
sig
   type t
   val of_int : int -> t
   val print : t -> unit
   val obj : < of_int : int -> t; print : t -> unit >
end

module Hello1 : HELLO =
struct
   type t = int
   let of_int i =
     i
   let print i =
     print_int i;
     print_string " says Hello1\n"

   let obj =
   object
     method of_int = of_int
     method print = print
   end
end

module Hello2 : HELLO =
struct
   type t = float
   let of_int i =
     float_of_int i
   let print i =
     print_float i;
     print_string " says Hello2\n"

   let obj =
   object
     method of_int = of_int
     method print = print
   end
end

let param = 2 (* defined at runtime *)
let obj =
   match param with
       1 -> Hello1.obj
     | 2 -> Hello2.obj
     | _ -> assert false;;

         Characters 63-73:
       | 2 -> Hello2.obj
              ^^^^^^^^^^
This expression has type
   < of_int : int -> Hello2.t; print : Hello2.t -> unit >
but is here used with type
   < of_int : int -> Hello1.t; print : Hello1.t -> unit >
Types for method of_int are incompatible


So if you want to do that, you must give the same type to your objects.
That would work if your modules Hello* all use a common type t instead of 
their own. In this case you just have to include the same code at the end 
of each Hello* module so that obj is defined. You can also add a line 
which places obj in a global table, e.g.
   let obj = ...
   let _ = Hashtbl.add Hello_modules.tbl 1 obj

And your main program would be:

   let param = ...
   let obj = Hashtbl.find Hello_modules.tbl param in
   ...


Martin

--
Martin Jambon, PhD
http://martin.jambon.free.fr

Visit http://wikiomics.org, the Bioinformatics Howto Wiki


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

* Re: [Caml-list] Rephrasing of dynamic module selection problem
  2006-02-21  0:54 Rephrasing of dynamic module selection problem Nathan Cooprider
  2006-02-21  3:49 ` "ocaml_beginners"::[] " Martin Jambon
@ 2006-02-21  3:55 ` brogoff
  2006-02-21  9:07   ` Andreas Rossberg
  2006-02-21  9:55 ` Virgile Prevosto
  2 siblings, 1 reply; 5+ messages in thread
From: brogoff @ 2006-02-21  3:55 UTC (permalink / raw)
  To: Nathan Cooprider; +Cc: ocaml_beginners, caml-list

On Mon, 20 Feb 2006, Nathan Cooprider wrote:
> So I am still trying to get modules to be dynamically (run-time)
> selectable instead of only statically (compile-time).

You can't do that in OCaml. Why don't you use objects or records to hold
the functions, instead of modules?

There are other MLs where you can pack a module into some manipulable
entity, but OCaml isn't one of them. Once you go there I wonder why not
just remove all differences between modules and records, since the two
things seem very similar.

-- Brian


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

* Re: [Caml-list] Rephrasing of dynamic module selection problem
  2006-02-21  3:55 ` [Caml-list] " brogoff
@ 2006-02-21  9:07   ` Andreas Rossberg
  0 siblings, 0 replies; 5+ messages in thread
From: Andreas Rossberg @ 2006-02-21  9:07 UTC (permalink / raw)
  To: ocaml_beginners, caml-list

"brogoff" <brogoff@speakeasy.net> wrote:
>
> There are other MLs where you can pack a module into some manipulable
> entity, but OCaml isn't one of them. Once you go there I wonder why not
> just remove all differences between modules and records, since the two
> things seem very similar.

Simple answer: type inference. You can do it for records, but not for
modules, because their type system is much too higher-order. In fact, even
type /checking/ may easily become undecidable.

These probably aren't unsurmountable problems, but unfortunately unsolved
yet.

  - Andreas


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

* Re: [Caml-list] Rephrasing of dynamic module selection problem
  2006-02-21  0:54 Rephrasing of dynamic module selection problem Nathan Cooprider
  2006-02-21  3:49 ` "ocaml_beginners"::[] " Martin Jambon
  2006-02-21  3:55 ` [Caml-list] " brogoff
@ 2006-02-21  9:55 ` Virgile Prevosto
  2 siblings, 0 replies; 5+ messages in thread
From: Virgile Prevosto @ 2006-02-21  9:55 UTC (permalink / raw)
  To: caml-list

Hello,

Le lun 20 fév 2006 17:54:32 CET, Nathan Cooprider a écrit:
> [coop@ender example]$ cat main.ml
> module Hello1 = struct
>   #include "hello1.ml"
> end ;;
> module Hello2 = struct
>   #include "hello2.ml"
> end ;;

This is not needed: the file hello1.ml implicitely defines a module Hello1
(same for hello2.ml and Hello2).

> (* This works . . . *)
> module H = Hello1
> (* But I would like this to be something like this instead:
> let parameter = 1
> module H =
>   match parameter with
>     1 -> Hello1
>   | _ -> Hello2
>  *)

This might not completely solve your problem, but the following camlp4
extension allows you to use the following expression:
choose_module H = 
match parameter with
 1 -> Hello1
| _ -> Hello2
in 
let argument = 42 in 
let main () = H.print (H.of_int argument) in
main ();;

Note that the scope of H is the expression following the first "in" and
not all the remaining of main.ml. This might be an issue, but it could
be solved by the use of functors (e.g.:
module type Hello = sig ... end
module F (H: Hello) = struct ... end
...
choose_module H = ... in
let module FH = F(H) in ... ;;
)

-------- choose_module.ml4 ----------
(* compile it with
ocamlc -c -I +camlp4 -pp "camlp4o pa_extend.cmo q_MLast.cmo -impl" -impl
choose_modules.ml4

to use it,
ocamlc -c -pp "camlp4o choose_modules.cmo" main.ml 
Note that by default, camlp4 doesn't search for extension in the current
directory, so that you may have to add a "-I ." directive
*) 
open Pcaml;;

let make_one_choice a mod_expr exp =
  let _loc = Lexing.dummy_pos, Lexing.dummy_pos in 
    <:expr<let module $uid:a$ = $mod_expr$ in $exp$>> 

let choices = Grammar.Entry.create Pcaml.gram "choices" 

EXTEND
   expr: [[
            "choose_module"; a = UIDENT; "="; "match" ; cond = expr;
            "with"; OPT "|"; l = LIST1 choices SEP "|";  
            "in"; e = expr -> 
              let new_l = List.map 
                            (fun (patt,optwhen,expr) -> 
                               (patt,optwhen, make_one_choice a expr e)) l
              in  <:expr< match $cond$ with [$list:new_l$] >> ]];
  choices: [[ p=patt; w = OPT ["when"; e = expr -> e]; "->"; 
              m = module_expr -> (p,w,m)
            ]];
END
-------------------------------------
-- 
E tutto per oggi, a la prossima volta
Virgile


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

end of thread, other threads:[~2006-02-21  9:55 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2006-02-21  0:54 Rephrasing of dynamic module selection problem Nathan Cooprider
2006-02-21  3:49 ` "ocaml_beginners"::[] " Martin Jambon
2006-02-21  3:55 ` [Caml-list] " brogoff
2006-02-21  9:07   ` Andreas Rossberg
2006-02-21  9:55 ` Virgile Prevosto

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