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.

2 comments:

gasche said...

I think your first point should be considered a bug. Feel free to report the issue upstream, on Batteries github issue tracker.

For your third point, what kind of support would you want ? I'm not sure a enum_of_list in BatPervasives would be much better than List.enum. If you're not repelled by Camlp4, you may be interested in the pa_comprehension extension.

Anonymous said...

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

I agree. I work on a large ocaml project and batteries wouldn't be a nice addition. Learning it in parallel with casual work, i fear, would confuse the hell out of me.