2011-01-09

A jolt, or a shock?

Things in OCaml Batteries that annoy me (i.e., this is merely opinion on my part, and not very informed at that. Caveat lector):

  • It is incompatible with stdlib in minor random ways:
    • List.sort requires label ~cmp
    • Channels are not completely wrapped, so that in_channel_length (open_in_bin "foo") doesn't type
  • Functional combinators are not what I've grown accustomed to. Turnstiles for composition are something I would never have thought of
  • Enumerators are in scope by default but conversion functions aren't. You can't do anything directly useful with --, for instance
  • Compiling it in results in huge executables
  • The help system is broken, at least on my install. I can't persuade it to know about anything at all

Edit: A maintainer left me a comment regarding reporting the issue to GitHub. I haven't got an account with them, and I don't plan to have one in the future, so to give further information:

# let inch = open_in_bin "dblib.mli" in let len = in_channel_length inch in close_in inch; len ;;
Characters 66-70:
  let inch = open_in_bin "dblib.mli" in let len = in_channel_length inch in close_in inch; len ;;
                                                                    ^^^^
Error: This expression has type BatIO.input = BatInnerIO.input
       but an expression was expected of type
         Batteries.in_channel = in_channel
# Pervasives.(let inch = open_in_bin "dblib.mli" in let len = in_channel_length inch in close_in inch; len) ;;
- : int = 21289

It is a minor oversight (in_channel_length needs lifting), but it bite me. This means in practice that you can't program against Batteries' Pervasives as if it were the stdlib's.

As to the second point, I entered the following in my .ocamlinit:


let id _ = failwith "Use Batteries ``identity'' function" ;;

let ( % ) _ = failwith "Use Batteries turnstiles ``|-'' and ``-|''" ;;

I expect the conditioning to kick in pretty quickly. As to the third point, of course it is my ignorance of the extensive library that frustrates me, and not a limitation of Batteries itself. Maybe I should retract it, but rest assured I am aware that I'm railing against my own limitations here.

As to the fourth… #man "modules" doesn't work; #man "topics" doesn't work; #man_module "BatIO" doesn't work… I'm reading batteries_help.ml here and nothing I can think of that is reasonable gives me a response other than Sorry, I don't know anything about X. If the indices can't be read, I'd expect an error message. If the syntax is incorrect, I'd expect a short blurb guiding me in the right direction. I just don't know what to tell it to satisfy it.

Edit 2: Regarding the help issue, upon further investigation I've found that none of the .idex files in /usr/local/share/doc/batteries-included/html/api were generated, so that #man is right in being perplexed. I've also found a number of working starting pointers (write Hashtbl.keys Toploop.directive_table |> List.of_enum and be amazed).

I've made a couple of changes that I expect will make my life easier with Batteries on Cygwin/MINGW:

  • Added the following to my .ocamlinit:
    let (browser: (_, _, _) format) = "\"path/to/chrome.exe\" %s" in
    Batteries_config.set_browser (fun url -> Sys.command (Printf.sprintf browser url))
    ;;
    
  • Rewritten /usr/local/share/doc/ocaml-batteries/language.idex to read:
    "batteries":  "html/index.html"
    "directives": "html/toplevel.html#directives"
    "ocaml":      "http://caml.inria.fr/pub/docs/manual-ocaml/"
    "wrappers":   "http://www.linux-nantes.org/~fmonnier/ocaml/ocaml-wrapping-c.php"
    
  • Rewritten /usr/local/share/doc/ocaml-batteries/toplevel.help to read:
    Welcome to OCaml, Batteries Included.
    
    Some directives:
     #quit;;                   (*Use this to quit OCaml.                *)
     #use "some_file.ml";;     (*Use this to load another program.      *)
     #require "some_package";; (*Use this to load an installed library. *)
     #help;;                   (*Well, you just used that one.          *)
     #man "some subject";;     (*Read the manual on some subject.       *)
     #browse "Some_module";;   (*Describe Some_module's contents.       *)
     #warnings "on";;          (*Turn on warnings.                      *)
     #warn_errors "on";;       (*Turn warnings into errors.             *)
    
    Some starting points:
     #man "batteries";;
     #man "directives";;
     #man "ocaml";;
     #man "wrappers";;
    

Now #help suits me.