5

How can I emulate this Python idiom in OCaml?

if __name__=="__main__":
   main()

See RosettaCode for examples in other programming languages.

mcandre
  • 22,868
  • 20
  • 88
  • 147

2 Answers2

6

There is no notion of main module in Ocaml. All the modules in a program are equal. So you can't directly translate this Python idiom.

The usual way in Ocaml is to have a separate file containing the call to main, as well as other stuff like command line parsing that only make sense in a standalone executable. Don't include that source file when linking your code as a library.

There is a way to get at the name of the module, but it's rather hackish, as it is intended for debugging only. It violates the usual assumption that you can rename a module without changing its behavior. If you rely on it, other programmers reading your code will curse you. This method is provided for entertainment purposes only and should not be used in real life.

let name_of_this_compilation_unit = 
  try assert false with Assert_failure (filename, _, _) -> filename

You can compare the name of the compilation unit with Sys.executable_name or Sys.argv.(0). Note that this is not really the same thing as the Python idiom, which does not rely on the toplevel script having a particular name.

Gilles 'SO- stop being evil'
  • 104,111
  • 38
  • 209
  • 254
  • Aye, in many languages this is the standard practice. But suppose I _do_ want to translate the Python idiom. There's gotta be a way to access the filename, or the module name, or the command line arguments sent to `ocaml`. – mcandre Sep 30 '11 at 00:25
  • 2
    Those are different questions. I think the file name is available when using certain camlp4 syntax extensions. The module name may be as well, although the definition of "the module name" could get tricky with functors, local modules and first class modules. Command line arguments are available through Sys.argv. You can also check to see if you are running in an interactive environment with the value Sys.interactive. – hcarty Sep 30 '11 at 00:53
  • 1
    @mcandre There's no way to access the name of the compilation unit in Ocaml, why do you think “there's gotta be” one? You can get it indirectly if you compile your program with a wrapper that translates `ocamlc -c foo.ml` into `ocamlc -pp 'camlp4 something.cma -Dmodule_name=\"foo\"' -c foo.ml` (where I don't remember offhand what `something.cma` would be). You're thinking in primarily-an-interpreter mode; the feature you want is not typically provided in primarily-compiled languages. – Gilles 'SO- stop being evil' Sep 30 '11 at 07:28
  • @Gilles Aye, but the filename is passed to `Sys.Argv.(0)`. It would be helpful to know a function or macro as a shorthand. – mcandre Sep 30 '11 at 16:56
  • @mcandre That's the name of the executable, which need not have any connection with the name of any module linked in the executable. – Gilles 'SO- stop being evil' Oct 03 '11 at 22:56
1
$ ocamlc -o scriptedmain -linkall str.cma scriptedmain.ml
$ ./scriptedmain
Main: The meaning of life is 42
$ ocamlc -o test -linkall str.cma scriptedmain.ml test.ml
$ ./test
Test: The meaning of life is 42

scriptedmain.ml:

let meaning_of_life : int = 42

let main () = print_endline ("Main: The meaning of life is " ^ string_of_int meaning_of_life)

let _ =
    let program = Sys.argv.(0)
    and re = Str.regexp "scriptedmain" in
        try let _ = Str.search_forward re program 0 in
            main ()
        with Not_found -> ()

test.ml:

let main () = print_endline ("Test: The meaning of life is " ^ string_of_int Scriptedmain.meaning_of_life)

let _ =
    let program = Sys.argv.(0)
    and re = Str.regexp "test" in
        try let _ = Str.search_forward re program 0 in
            main ()
        with Not_found -> ()

Posted on RosettaCode.

mcandre
  • 22,868
  • 20
  • 88
  • 147
  • Ok, after reading that page about “scripted main” I see what you're trying to do. I have to say it doesn't seem that useful, unlike the Python idiom (which is not an implementation of “scripted main”!). – Gilles 'SO- stop being evil' Oct 03 '11 at 22:57
  • I code in several languages, and there's no term for this behavior. So I deem it "scripted main". How is the Python idiom not scripted main? – mcandre Oct 04 '11 at 23:25
  • I didn't know the term “scripted main” before, so I'm going by that [Rosetta Code](http://rosettacode.org/wiki/ScriptedMain) page. It looks like most languages check the name of the program against a hard-coded value. That's not how the Python idiom works. The Python idiom keeps working in the same way even if you rename the module. – Gilles 'SO- stop being evil' Oct 04 '11 at 23:41
  • I wrote that page. :) Ah, I understand what you're saying now. Yeah, when languages don't include a way to access the module's name programmatically, you have to use the executable's name. – mcandre Oct 05 '11 at 06:53