The ML sweet spot

I just got back from visiting Northeastern and Harvard where I yet again flogged a version of my POPL talk. Olin Shivers was my host at Northeastern and Greg Morrisett at Harvard. It was a bit of a rushed visit, but a lot of fun nonetheless.

Both Greg and Olin are very interested in making the next big jump in programming languages, and they both think that that next step will require better ways of reasoning statically about programs. I think they're dead-on in terms of what the right direction to go is, but I think they've got their work cut out for them. It will be hard to beat ML because ML sits in a kind of sweet spot; make it a little bit better in one aspect, and you give something up in another.

Bind without tears

One of the annoyances of using monads in OCaml is that the syntax is awkward. You can see why if you look at a simple example. Assume that you're using the usual option monad. If we define >>= to be the bind operator, you might end up with a piece of code that looks like this:

let f x_opt y_opt z_opt =
  x_opt >>= (fun x ->
               y_opt >>= (fun y ->
                            z_opt >>= (fun z ->
                                         return (x + y + z))))

This is awful for two reasons: the indentation is absurdly deep, and secondly, and there are too many closing parens at the end.

Variable-argument functions

Here's another puzzle:

Is it possible in OCaml to define a variable-argument function? For example, can one define a function f and values a and z such that the following assertions hold:

assert (f z = 0);
assert (f a z = 1);
assert (f a a z = 2);
assert (f a a a z = 3);
...

Typing RPCs

At Jane Street, we end up writing lots of messaging protocols, and many of these protocols end up being simple RPC-style protocols, i.e., protocols with a client and a server, where communication is done in a simple query/response style.

I've always found the writing of these protocols rather unsatisfying, because I could never find a clean way of writing down the types. In the following, I'd like to describe some nice tricks I've learned recently for specifying these protocols more cleanly.

Using let module for matching

In OCaml, referring to constructors defined in other modules can be somewhat awkward. Suppose we have a module like the following.

module Example = struct
  type t = Foo | Bar | Baz
end

To write a function that pattern matches on values of type Example.t we could directly refer to the variants as follows.

let f e =
  match e with
  | Example.Foo -> ...
  | Example.Bar -> ...
  | Example.Baz -> ...

That is pretty verbose.

Extracting an exception from a module

The Unix module defines the Unix_error exception constructor.

module Unix : sig
   exception Unix_error of error * string * string
   ...
end

Suppose you want to create your own My_unix module that defines some Unix utility functions and exports the same Unix_error. How would you do it?

A universal type?

Is it possible in OCaml to implement a universal type, into which any other type can be embedded? More concretely, is possible to implement the following signature?

module type Univ = sig
  type t
  val embed: unit -> ('a -> t) * (t -> 'a option)
end

Talking at Penn

I just got back from an enjoyable visit at Penn. I gave a version of my POPL talk for an audience consisting in large part of students taking Benjamin Pierce's advanced programming class, which is being done in Haskell with a little bit of ML. I also got a chance to chat with some of the PL faculty and grad students and to hear what people are up to on the research front.

It was a fun afternoon.

HOWTO: Static access control using phantom types

We thought that phantom types would be an appropriate topic for our first real post because they are a good example of a powerful and useful feature of OCaml that is little used in practice.

In this post, I'll cover a fairly simple use of phantom types: enforcing a capability-style access-control policy. In particular, I'll describe how you can create easy to use read-only handles to a mutable data structure. We'll explore this using the example of an int ref.

We've got a blog!

Jane Street finally has a blog! Jane Street is one of the biggest commercial users of OCaml, and we like to think that we've picked up a few tricks over the years. In addition to putting down our random musings, we plan to use this space to share what we've learned. We hope that over time this turns into a useful resource for the larger OCaml community.

We'll get our first real post out soon.

Syndicate content Syndicate content