mlin / twt

The Whitespace Thing for OCaml
10 stars 1 forks source link

"The Whitespace Thing" for OCaml

http://github.com/mlin/twt

Maintainer: Mike Lin

"The Whitespace Thing" for OCaml is a preprocessor (invoked as ocaml+twt) that uses indentation to auto-parenthesize multi-line expressions, like in Python and Haskell. Using natural indentation patterns, it eliminates:

The language syntax is otherwise the same as OCaml's, with a few restrictions.

Version 1 is implemented as a line-oriented preprocessor; this is something of a hack. At some unspecified time in the future, it should be rewritten with a proper syntax tree parser, although the current approach honestly gets quite far!

Code examples

ocaml ocaml+twt
let rec main magic_number =
 Printf.printf "Your guess? ";
 let guess = int_of_string (read_line ()) in
  if guess > magic_number then
   (Printf.printf "Too high!\n";
    main magic_number)
  else if guess < magic_number then
   (Printf.printf "Too low!\n";
    main magic_number)
  else
   (Printf.printf "You win!\n";
    exit 0);;

Random.self_init ();;

main (Random.int 100);;
let rec main magic_number =
 Printf.printf "Your guess? "
 let guess = int_of_string (read_line ())
 if guess > magic_number then
  Printf.printf "Too high!\n"
  main magic_number
 else if guess < magic_number then
  Printf.printf "Too low!\n"
  main magic_number
 else
  Printf.printf "You win!\n"
  exit 0

Random.self_init ()

main (Random.int 100)
let list_out lst =
 (List.map
  (function Some x -> x)
  (List.filter
   (function Some x -> true | None -> false)
   lst))
let list_out lst =
 List.map
  function Some x -> x
  List.filter
   function Some x -> true | None -> false
   lst
for i = 1 to 10 do
 print_int i;
 print_newline ()
done;
print_string "done"
for i = 1 to 10 do
 print_int i
 print_newline ()
print_string "done"
let contrived = function
   s when (String.length s) > 0 ->
    begin
     try
      Some (float_of_string s)
     with
      Failure _ -> Some nan
    end
 | _ -> None
let contrived = function
 | s when (String.length s) > 0 ->
    try
     Some (float_of_string s)
    with
     | Failure _ -> Some nan
 | _ -> None

Language documentation

See the quick reference, and the longer examples/.

Installation

ocaml+twt is available in OPAM: opam install ocaml+twt. Once installed, the ocaml+twt executable is available in your path when you eval $(opam config env).

Without OPAM, extract the source tarball and make install. This installs the executable to PREFIX/bin where PREFIX=/usr/local. You can override this with make install PREFIX=/home/alice

Usage

To use the preprocessor, either manually invoke it using ocaml+twt mycode.ml and pipe the results to a file, or use the preprocessor flag to ocamlc:

ocamlc -pp ocaml+twt mycode.ml

There are a few optional behaviors available for the preprocessor. They're pretty self-explanatory by looking at the usage printed by invoking ocaml+twt.

With ocamlbuild, you can just add something like this to the _tags file in your project directory:

<**/*.ml> or <**/*.mli>: pp(ocaml+twt)

If you use OCamlMakefile, you can make the first line of your file (*pp ocaml+twt *).

Tips and FAQs

ppcompose utility

Because the -pp flag to ocamlc is somewhat limited, I included a 'ppcompose' utility that makes it simple to compose several preprocessors. For example, one can compose a list comprehension camlp4 syntax with ocaml+twt as follows:

ocamlc -pp "ppcompose 'camlp4o pa_compr.cmo' 'ocaml+twt -spaceonly'" source.ml

The last preprocessor specified on the command line is applied first to the source code. This means you usually want to put ocaml+twt last.

Useful links

Version history

7/5/15 version 0.94.0

10/05/13 version 0.93.2

10/24/12 version 0.931

02/01/12 version 0.93

08/02/10 version 0.92

03/11/08 version 0.91

01/16/07 version 0.90

12/10/06 version 0.86

07/24/06 version 0.85

02/19/06 version 0.81

11/21/05 version 0.8