Showing posts with label ocamljs. Show all posts
Showing posts with label ocamljs. Show all posts

Thursday, August 26, 2010

ocamljs 0.3

I am happy to announce version 0.3 of ocamljs. Ocamljs is a system for compiling OCaml to Javascript. It includes a Javascript back-end for the OCaml compiler, as well as several support libraries, such as bindings to the browser DOM. Ocamljs also works with orpc for RPC over HTTP, and froc for functional reactive browser programming.

Changes since version 0.2 include:

  • support for OCaml 3.11.x and 3.12.0
  • jQuery binding (contributed by Dave Benjamin)
  • full support for OCaml objects (interoperable with Javascript objects)
  • Lwt 2.x support
  • ocamllex and ocamlyacc support
  • better interoperability with Javascript
  • many small fixes and improvements

Development of ocamljs has moved from Google Code to Github; see

Comparison to js_of_ocaml

Since I last did an ocamljs release, a new OCaml-to-Javascript system has arrived, js_of_ocaml. I want to say a little about how the two systems compare:

Ocamljs is a back-end to the existing OCaml compiler; it translates the “lambda” intermediate language to Javascript. (This is also where the bytecode and native code back-ends connect to the common front-end.) Js_of_ocaml post-processes ordinary OCaml bytecode (compiled and linked with the ordinary OCaml bytecode compiler) into Javascript. With ocamljs you need a special installation of the compiler (and special support for ocamlbuild and ocamlfind), you need to recompile libraries, and you need the OCaml source to build it. With js_of_ocaml you don’t need any of this.

Since ocamljs recompiles libraries, it’s possible to special-case code for the Javascript build to take advantage of Javascript facilities. For example, ocamljs implements the Buffer module on top of Javascript arrays instead of strings, for better performance. Similarly, it implements CamlinternalOO to use Javascript method dispatch directly instead of layering OCaml method dispatch on top. Js_of_ocaml can’t do this (or at least it would be necessary to recognize the compiled bytecode and replace it with the special case).

Because js_of_ocaml works from bytecode, it can’t always know the type of values (at the bytecode level, ints, bools, and chars all have the same representation, for example). This makes interoperating with native Javascript more difficult: you usually need conversion functions between the OCaml and Javascript representation of values when you call a Javascript function from OCaml. Ocamljs has more information to work with, and can represent OCaml bools as Javascript bools, for example, so you can usually call a Javascript function from OCaml without conversions.

Ocamljs has a mixed representation of strings: literal strings and the result of ^, Buffer.contents, and Printf.sprintf are all immutable Javascript strings; strings created with String.create are mutable strings implemented by Javascript arrays (with a toString method which returns the represented string). This is good for interoperability—you can usually pass a string directly to Javascript—but it doesn’t match regular OCaml’s semantics, and it can cause runtime failures (e.g. if you try to mutate an immutable string). Js_of_ocaml implements only mutable strings, so you need conversions when calling Javascript, but the semantics match regular OCaml.

With ocamljs, Javascript objects can be called from OCaml using the ordinary OCaml method-call syntax, and objects written in OCaml can be called using the ordinary Javascript syntax. With js_of_ocaml, a special syntax is needed to call Javascript objects, and OCaml objects can’t easily be called from Javascript. However, there is an advantage to having a special call syntax: with ocamljs it is not possible to partially apply calls to native Javascript methods, but this is not caught by the compiler, so there can be a runtime failure.

Ocamljs supports inline Javascript, while js_of_ocaml does not. I think it might be possible for js_of_ocaml to do so using the same approach that ocamljs takes: use Camlp4 quotations to embed a syntax tree, then convert the syntax tree from its OCaml representation (as lambda code or bytecode) into Javascript. However, you would still need conversion functions between OCaml and Javascript values.

I haven’t compared the performance of the two systems. It seems like there must be a speed penalty to translating from bytecode compared to translating from lambda code. On the other hand, while ocamljs is very naive in its translation, js_of_ocaml makes several optimization passes. With many programs it doesn’t matter, since most of the time is spent in browser code. (For example, the planet example seems to run at the same speed in ocamljs and js_of_ocaml.) It would be interesting to compare them on something computationally intensive like Andrej Bauer’s random-art.org.

Js_of_ocaml is more complete and careful in its implementation of OCaml (e.g. it supports int64s), and it generates much more compact code than ocamljs. I hope to close the gap in these areas, possibly by borrowing some code and good ideas from js_of_ocaml.

Tuesday, March 23, 2010

Inside OCaml objects

In the ocamljs project I wanted to implement the OCaml object system in a way that is interoperable with Javascript objects. Mainly I wanted to be able to call Javascript methods with the OCaml method call syntax, but it is also useful to write objects in OCaml which are callable in the usual way from Javascript.

I spent some time a few months ago figuring out how OCaml objects are put together in order to implement this (it is in the unreleased ocamljs trunk—new release coming soon I hope). I got a bug report against it the other day, and it turns out I don’t remember much of what I figured out. So I am going to figure it out again, and write it down, here in this very blog post!

Objects are implemented mostly in the CamlinternalOO library module, with a few compiler primitives for method invocation. The compiler generates CamlinternalOO calls to construct classes and objects. Our main tool for figuring out what is going on is to write a test program, dump out its lambda code with -dlambda, and read the CamlinternalOO source to see what it means. I will explain functions from camlinternalOO.ml but not embed them in the post, so you may want it available for reference.

I have hand-translated (apologies for any errors) the lambda code back to pseudo-OCaml to make it more readable. The compiler-generated code works directly with the OCaml heap representation, and generally doesn’t fit into the OCaml type system. Where the heap representation can be translated back to an OCaml value I do that; otherwise I write blocks with array notation, and atoms with integers. Finally I have used OO as an abbreviation for CamlinternalOO.

Immediate objects

Here is a first test program, defining an immediate object:

let p = 
object 
  val mutable x = 0 
  method get_x = x 
  method move d = x <- x + d 
end 

And this is what it compiles to:

let shared = [|"move";"get_x"|] 
let p = 
  let clas = OO.create_table shared in 
  let obj_init = 
    let ids = OO.new_methods_variables clas shared [|"x"|] in 
    let move = ids.(0) in 
    let get_x = ids.(1) in 
    let x = ids.(2) in 
    OO.set_methods clas [| 
      get_x; OO.GetVar; x; 
      move; (fun self d -> self.(x) <- self.(x) + d); 
    |]; 
    (fun env -> 
       let self = OO.create_object_opt 0 clas in 
       self.(x) <- 0; 
       self) in 
  OO.init_class clas; 
  obj_init 0 

An object has a class, created with create_table and filled in with new_methods_variables, set_methods, and init_class; the object itself is created by calling create_object_opt with the class as argument, then initializing the instance variable.

A table (the value representing a class) has the following fields (and some others we won’t cover):

type table = { 
  mutable size: int; 
  mutable methods: closure array; 
  mutable methods_by_name: meths; 
  mutable methods_by_label: labs; 
  mutable vars: vars; 
} 

Each instance variable has a slot (its index in the block which represents the object); vars maps variable names to slots. The size field records the total number of slots (including internal slots, see below).

Each public method has a label, computed by hashing the method name. The methods field (used for method dispatch) holds each method of the class, with the label of the method at the following index (the type is misleading). Each method then has a slot (the index in methods of the method function); methods_by_name maps method names to slots, and the confusingly-named methods_by_label marks slots to whether it is occupied by a public method.

The create_table call assigns slots to methods, fills in the method labels in methods, and sets up methods_by_name and methods_by_label. The new_methods_variables call returns the slot of each public method and each instance variable in a block (which is unpacked into local variables).

The set_methods call sets up the method functions in methods. Its argument is a block containing alternating method slots and method descriptions (the description can take more than one item in the block). For some methods (e.g. move) the description is just an OCaml function (here you can see that self is passed as the first argument). For some the description is given by a value of the variant OO.impl along with some other arguments. For get_x it is GetVar followed by the slot for x. The actual function that gets the instance variable is generated by set_methods. As far as I understand it, the point of this is to reduce object code size by factoring out the common code from frequently occurring methods.

Finally create_object_opt allocates a block of clas.size, then fills in the first slot with the methods array of the class and the second with the object’s unique ID. (We will see below what the _opt part is about.)

Method calls

A public method call:

p#get_x 

compiles to:

send p 291546447 

where send is a built-in lambda term. The number is the method label. To understand how the method is applied we have to go a little deeper. In bytegen.ml there is a case for Lsend which generates the Kgetpubmet bytecode instruction to find the method function; the function is then applied like any other function. Next we look to the GETPUBMET case in interp.c to see how public methods are looked up in the methods block (stored in the first field of the object).

A couple details about methods we didn’t cover before: The first field contains the number of public methods. The second contains a bitmask used for method caching—briefly, it is enough bits to store offsets into methods. The rest of the block is method functions and labels as above, padded out so that the range of an offset masked by the bitmask does not overflow the block.

Returning to GETPUBMET, we first check to see if the method cache for this call site is valid. The method cache is an extra word at each call site which stores an offset into methods (but may be garbage—masking it takes care of this). If the method label at this offset matches the label we’re looking for, the associated method function is returned. Otherwise, we binary search methods to find the method label (methods are sorted in label order in transclass.ml), then store the offset in the cache and return the associated method function.

Classes

A class definition:

class point = 
object 
  val mutable x = 0 
  method get_x = x 
  method move d = x <- x + d 
end 
let p = new point 

compiles to:

let shared = [|"move";"get_x"|] 
let point = 
  let point_init clas = 
    let ids = OO.new_methods_variables clas shared [|"x"|] in 
    let move = ids.(0) in 
    let get_x = ids.(1) in 
    let x = ids.(2) in 
    OO.set_methods clas [| 
      get_x; OO.GetVar; x; 
      move; (fun self d -> self.(x) <- self.(x) + d); 
    |]; 
    (fun env self -> 
       let self = OO.create_object_opt self clas in 
       self.(x) <- 0; 
       self) in 
  OO.make_class shared point_init 
let p = (point.(0) 0) 

This is similar to the immediate object code, except that the class constructor takes the class table as an argument rather than constructing it itself, and the object constructor takes self as an argument. We will see that class and object constructors are each chained up the inheritance hierarchy, and the tables / objects are passed up the chain. The make_class call calls create_table and init_class in the same way we saw in the immediate object case, and returns a tuple, of which the first component is the object constructor. So the new invocation calls the constructor.

Inheritance

A subclass definition:

class point = ... (* as before *) 
class point_sub = 
object 
  inherit point 
  val mutable y = 0 
  method get_y = y 
end 

compiles to:

let point = ... (* as before *) 
let point_sub = 
  let point_sub_init clas = 
    let ids = 
      OO.new_methods_variables clas [|"get_y"|] [|"y"|] in 
    let get_y = ids.(0) in 
    let y = ids.(1) in 
    let inh = 
      OO.inherits 
        clas [|"x"|] [||] [|"get_x";"move"|] point true in 
    let obj_init = inh.(0) in 
    OO.set_methods clas [| get_y; GetVar; y |]; 
    (fun env self -> 
      let self' = OO.create_object_opt self clas in 
      obj_init self'; 
      self'.(y) <- 0; 
      OO.run_initializers_opt self self' clas) in 
  OO.make_class [|"move";"get_x";"get_y"|] point_sub_init 

The subclass is connected to its superclass through inherits, which calls the superclass constructor on the subclass (filling in methods with the superclass methods) and returns the superclass object constructor (and some other stuff). In the subclass object constructor, the superclass object constructor is called. (This is why the object is created optionally—the class on which new is invoked actually allocates the object; further superclass constructors just initialize instance variables.) In addition, we run any initializers, since some superclass may have them.

Self- and super-calls

A class with a self-call:

class point = 
object (s) 
  val mutable x = 0 
  method get_x = x 
  method get_x5 = s#get_x + 5 
end 

becomes:

let point = 
  let point_init clas = 
    ... (* as before *) 
    OO.set_methods clas [| 
      get_x; OO.GetVar; x; 
      get_x5; (fun self -> sendself self get_x + 5); 
    |] 
    ... 

Here sendself is a form of Lsend for self-calls, where we know the method slot at compile time. Instead of generating the Kgetpubmet bytecode, it generates Kgetmethod, which just does an array reference to find the method.

A class with a super-call:

class point = ... (* as before *) 
class point_sub = 
object 
  inherit point as super 
  method move1 n = super#move n 
end 

becomes:

let point = ... (* as before *) 
let point_sub = 
  let point_sub_init clas = 
    ... 
    let inh = 
      OO.inherits 
        clas [|"x"|] [||] [|"get_x";"move"|] point true in 
    let move = inh.(3) in 
    ... 
    OO.set_methods clas [| 
      move1; (fun self n -> move self n) 
    |]; 
    ... 

In this case, we are able to look up the actual function for the super-call in the class constructor (returned from inherits), so the invocation is just a function application rather than a slot dereference.

I don’t totally understand why we don’t know the function for self calls. I think it is because the superclass constructor runs before the subclass constructor, so the slot is assigned (this happens before the class constructors are called) but the function hasn’t been filled in yet. Still it seems like the knot could somehow be tied at class construction time to avoid a runtime slot dereference.

ocamljs implementation

The main design goal is that we be able to call methods on ordinary Javascript objects with the OCaml method call syntax, simply by declaring a class type giving the signature of the object. So if you want to work with the browser DOM you can say:

class type document = 
object 
  method getElementById : string -> #element 
  ... (* and so on *) 
end 

for some appropriate element type (see src/dom/dom.mli in ocamljs for a full definition), and say:

document#getElementById "content" 

to make the call.

These are always public method calls, so they use the Lsend lambda form. We don’t want to do method label dispatch, since Javascript already has dispatch by name, so first off we need to carry the name rather than the label in Lsend.

We have seen how self is passed as the first argument when methods are invoked. We can’t do that for an arbitrary Javascript function, but the function might use this, so we need to be sure that this points to the object.

There is no way to know at compile time whether a particular method invocation is on a regular Javascript object or an OCaml object. Maybe we could mark OCaml objects somehow and do a check at runtime, but I decided to stick with a single calling convention. So whatever OCaml objects compile to, they have to support the convention for regular Javascript objects—foo#bar compiles to foo.bar, with this set to foo.

As we have seen, self-calls are compiled to a slot lookup rather than a name lookup, so we also need to support indexing into methods.

So here’s the design: an OCaml object is represented by a Javascript object, with numbered slots containing the instance variables. There is a constructor for each class, with prototype set up so each method is accessible by name, and the whole methods block is accessible in a special field, so we can call by slot. (Since we don’t need method labels, methods just holds functions.)

The calling convention passes self in this, so we bind a local self variable to this on entry to each method. It doesn’t work to say this everywhere instead of self, because this in Javascript is a bit fragile. In particular, if you define and apply a local function (ocamljs does this frequently), this is null rather than the lexically-visible this.

For sendself we look up the function by slot in the special methods field. Finally, for super-calls, we know the function at class construction time. In this case the function is applied directly, but we need to take care to treat it as a method application rather than an ordinary function call, since the calling convention is different.

The bug

The OCaml compiler turns super-calls into function applications very early in compilation (during typechecking in typecore.ml). There is no difference in calling convention for regular OCaml, so it doesn’t matter that later phases don’t know that these function applications are super-calls. But in our case we have to carry this information forward to the point where we generate Javascript (in jsgen.ml). It is a little tricky without changing the “typedtree” intermediate language.

I had put in a hack to mark these applications with a special extra argument, and it worked fine for my test program, where the method had no arguments. I didn’t think through or test the case where the method has arguments though. I was able to fix it (I think!) with a different hack: super calls are compiled to self calls (that is, to Texp_send with Tmeth_val) but the identifier in Tmeth_val is marked with an unused bit to indicate that it binds a function rather than a slot, so we don’t need to dereference it.


Appendix: other features

It is interesting to see how the various features of the object system are implemented, but maybe not that interesting, so here they are as an appendix.

Constructor parameters

A class definition with a constructor parameter:

class point x_init = 
object 
  val mutable x = x_init 
  ... (* as before *) 
end 

compiles to:

let point = 
  let point_init clas = 
    ... (* as before *) 
    (fun env self x_init -> 
      OO.create_object_opt self clas; 
      self.(x) <- x_init; 
      self) in 
  ... (* as before *) 

So the constructor parameter in the surface syntax just turns into a constructor parameter internally. (There is a slightly funny interaction between constructor parameters and let-bound expressions after class but before object: if there is no constructor parameter the let is evaluated at class construction, but if there is a parameter it is evaluated at object construction, whether or not it depends on the parameter.)

Virtual methods and instance variables

A class definition with a virtual method:

class virtual abs_point = 
object 
  method virtual move : int -> unit 
end 

compiles to:

let abs_point = [| 
  0; 
  (fun clas -> 
    let move = OO.get_method_label clas "move" in 
    (fun env self -> 
      OO.create_object_opt self clas); 
  0; 0 
|] 

Since a virtual class can’t be instantiated, there’s no need to create the class table with make_class; we just return the tuple that represents the class, containing the class and object constructor. (I don’t understand the call to get_method_label, since its value is unused; possibly it is called for its side effect, which is to register the method in the class table if it does not already exist.)

A subclass implementing the virtual method inherits from the virtual class in the usual way.

A class declaration with a virtual instance variable:

class virtual abs_point2 = 
object 
  val mutable virtual x : int 
  method move d = x <- x + d 
end 

becomes:

let abs_point = [| 
  0; 
  (fun clas 
    let ids = 
      OO.new_methods_variables [|"move"|] [|"x"|] in 
    ... (* as before *)); 
  0; 0 
|] 

Again, a subclass providing the instance variable inherits from the virtual class in the usual way. By the time new_methods_variables is called in the superclass, the subclass has registered a slot for the variable.

Private methods

A class definition with a private method:

class point = 
object 
  val mutable x = 0 
  method get_x = x 
  method private move d = x <- x + d 
end 

compiles to:

let point = 
  let point_init clas = 
    let ids = 
      OO.new_methods_variables clas [|"move";"get_x"|] [|"x"|] in 
    ... (* as before *) 
  OO.make_class [|"get_x"|] point_init 

Everything is the same except that the private method is not listed in the public methods of the class. Since a private method is callable only from code in which the class of the object is statically known, there is no need for dispatch or a method label. The private method functions are stored in methods after the public methods and method labels.

If we expose a private method in a subclass:

class point = ... (* as before *) 
class point_sub = 
object 
  inherit point 
  method virtual move : _ 
end 

we get:

let point = ... (* as before *) 
let point_sub = 
  let point_sub_init clas = ... (* as before *) 
  OO.make_class [|"move";"get_x"|] point_sub_init 

Putting "move" in the call to make_class registers it as a public method, so later, when set_method is called for move in the superclass constructor, it puts the method and its label in methods for dispatch.

Monday, May 11, 2009

Sudoku in ocamljs, part 3: functional reactive programming

In part 1 and part 2 of this series, we made a simple Sudoku game and connected it to a game server. In this final installment I want to revisit how we check that a board satisfies the Sudoku rules. There's a small change to the UI: instead of a "Check" button, the board is checked continuously as the player enters numbers; any conflicts are highlighted as before. Here's the final result.

Let's review how we want checking to work: a cell is colored red if any other cell in the same row, column, or square (outlined in bold) contains the same number; otherwise the cell is colored white. Now take another look at the check_board function from part 1. Is it obvious that this code meets the specification? The function is essentially stateful, clearing all the cell colors then setting them red when it discovers a conflict. In fact, I had a bug in it related to state--I was clearing the background color in the None arm of check_set, so each checked constraint would overwrite the highlighting of the previous ones where they overlapped.

It would be easier to convince ourselves that we'd gotten it right if the code looked more like the specification. What we want is a function that maps each cell and its "adjacent" cells (the ones in the same row, column, or square) to a boolean (true if the cell is highlighted). Abstracting from the DOM details, suppose a cell is an int option and we have a function adjacents i j that returns a list of cells adjacent to the cell at (i, j). Then the check function is just:

let highlighted cell i j =
  cell <> None && List.mem cell (adjacents i j)

So how do we hook this function into the UI? We could just call it for every cell, every time we get a change event for some cell. That seems like a lot of needless computation, since almost all the cells haven't changed. On the other hand, if we manually keep track of which cells might be affected by a change, our code is no longer obviously correct. It would be nice to have some kind of incremental update, like a spreadsheet.

This is where functional reactive programming comes in. The main idea is to write functions over behaviors, or values that can change. If you change an input to a function, the output (another behavior) is automatically recomputed. The dependency bookkeeping is taken care of by the framework; we'll use the froc library.

It turns out to be convenient to give behaviors a monadic interface. So we have a type 'a behavior; we turn a constant into a behavior with return, and we use a behavior with bind. We saw in part 2 that the monadic interface of Lwt enables blocking: since bind takes a function to apply to the result of a thread, the framework can wait until the thread has completed before applying it. With froc, the framework applies the function passed to bind whenever the bound behavior changes. With both Lwt and froc you can think of a computation as a collection of dependencies rather than a linear sequence.

There's another important piece of functional reactive programming: events. An 'a event in froc is a channel over which values of type 'a can be passed. You can connect froc events to DOM events to interact with the stateful world of the UI. The library includes several functions for working with events (e.g. mapping a function over an event stream) and in particular for mediating between behaviors and events, such as:

val hold : 'a -> 'a event -> 'a behavior
which takes an initial value and an event channel, and returns a behavior that begins at the initial value then changes to each successive value that's sent on the channel, and
val changes : 'a behavior -> 'a event
which takes a behavior and returns an event channel that has a value sent on it whenever the behavior changes.

This all probably seems a bit abstract, so let's dive into the example code:

module D = Dom
let d = D.document

module F = Froc
module Fd = Froc_dom
let (>>=) = F.(>>=)
We set up some constants we'll need below. The Froc module contains the core FRP implementation, not tied to a particular UI toolkit; Froc_dom contains functions that are specific to DOM programming (with the Dom module we saw before).
let make_cell v =
  let ev = F.make_event () in
  let cell = F.hold v ev in
  let set v = F.send ev v in
  (cell, set)
let notify_e e f =
  F.notify_e e (function
    | F.Fail _ -> ()
    | F.Value v -> f v)
These are a couple of functions that really should be part of froc (and will be in the next version). The first makes a cell, which is a behavior (the hold of an event channel) along with a function to set its value (which sends the value on the channel). It's like a ref cell, but we can bind it so changes are propagated. We'll have one of these for each square on the Sudoku board, but it is a generally useful construct.

The second papers over a design error in the froc API: like with Lwt threads, a froc behavior or event value can be either a normal value or an exception (together, a result). The notify_e function sets a callback that's called when an event arrives on the channel, but most of the time we just want to ignore exceptional events.

let attach_input_value i b =
  notify_e (F.changes b) (fun v -> i#_set_value v)
let attach_backgroundColor e b =
  notify_e
    (F.changes b)
    (fun v -> e#_get_style#_set_backgroundColor v)
These are functions that should be part of Froc_dom. To attach a DOM element to a behavior means to update the DOM element whenever the behavior changes. But there are lots of ways to update a DOM element, and Froc_dom doesn't include them all. (This design contrasts with that of Flapjax, where you work with behaviors whose value is an entire DOM element. It's certainly possible to do this in froc, but more tedious because of the types.)
let (check_enabled, set_check_enabled) = make_cell false
Now we're in the application code. The check_enabled cell controls whether checking is turned on--we'll see below what this is for, as you may have noticed that there is no such switch in the actual UI.
let make_board () =
  let make_input () =
    let input = (d#createElement "input" : D.input) in
    input#setAttribute "type" "text";
    input#_set_size 1;
    input#_set_maxLength 1;
    let style = input#_get_style in
    style#_set_border "none";
    style#_set_padding "0px";

    let (cell, set) = make_cell None in
    attach_input_value input
      (cell >>= function
        | None -> F.return ""
        | Some v -> F.return (string_of_int v));
    let ev =
      F.map
        (function
          | "1" | "2" | "3" | "4" | "5"
          | "6" | "7" | "8" | "9"  as v ->
            Some  (int_of_string v)
          | _ -> None)
        (Fd.input_value_e input) in
    notify_e ev set;
    (cell, set, input) in
Here we make the game board much as we did in part 1. The main difference is that instead of working directly with DOM input nodes, we connect each input to a cell of type int option. The attach_input call sets the value of the DOM input node whenever the cell changes, and the notify_e call sets the cell whenever the input node changes. (This doesn't loop, because Fd.input_value_e makes an event stream from the "onchange" events of the input, and "onchange" events are only sent when the user changes the input, not when it's changed from Javascript.) We take the stream of strings and map it into a stream of int options, validating the string as we go.
  let rows =
    Array.init 9 (fun i ->
      Array.init 9 (fun j ->
        make_input ())) in

  let adjacents i j =
    let adj i' j' =
      (i' <> i || j' <> j) &&
        (i' = i or j' = j or
            (i' / 3 = i / 3 && j' / 3 = j / 3)) in
    let rec adjs i' j' l =
      match i', j' with
        | 9, _ -> l
        | _, 9 -> adjs (i'+1) 0 l
        | _, _ ->
            let l =
              if adj i' j'
              then
                let (cell,_,_) = rows.(i').(j') in
                cell::l
              else l in
            adjs i' (j'+1) l in
    adjs 0 0 [] in
We make the game board as a matrix of inputs as before, but now each element of the matrix contains a cell (an int option behavior), the function to set that cell, and the actual DOM input element. Next we set up the rule-checking. The adjacents function returns a list of cells adjacent to the cell at (i, j) (adjacent in the sense we discussed above). All my bugs when I wrote this example were in this function, but it clearly embodies the specification we're trying to meet: a cell is adjacent to the current cell if it is not the same cell and is in the same row, column, or square. (The loop would be clearer if we had Array.foldi.)
  ArrayLabels.iteri rows ~f:(fun i row ->
    ArrayLabels.iteri row ~f:(fun j (cell, _, input) ->
      let adjs = adjacents i j in
      attach_backgroundColor input
        (check_enabled >>= function
          | false -> F.return "#ffffff"
          | true ->
              F.bindN adjs (fun adjs ->
                cell >>= fun v ->
                  if v <> None && List.mem v adjs
                  then F.return "#ff0000"
                  else F.return "#ffffff"))));
This is the functional reactive core of the program. For each square on the board we compute essentially the highlighted function above, but in monadic form (the bindN function binds a list of behaviors at once), and attach the result to the background color of the input node. Because the set of adjacent cells does not depend on the value of the cells, we can hoist its computation out of the reactive part so it won't be recomputed every time a cell changes (and since dependency on a behavior is captured in the type of a function, the fact that this typechecks tells us it is safe to do!).

That's it. The rest of the program is almost the same as before. (Here's the full code.) The one important change has to do with check_enabled. In the reaction to cell changes, we consult check_enabled, returning the unhighlighted color when it's false. Since we do this before binding the cells, a change to a cell causes no recomputation when check_enabled is false. So we turn off check_enabled while loading a new game board, saving a lot of needless recomputation that otherwise makes it annoyingly slow.

It's interesting to compare functional reactive programming to the model-view-controller pattern. The point of MVC is to separate the changeable state (the model) from how it is displayed (the view). Although MVC is typically implemented with change events and state update, a view behaves as a pure function of the state (or can be made so by making the state of UI components explicit). So you could think of FRP as "automatic" MVC: you just write down dependencies (with bind) and the framework manages events and state update. For small examples this may not seem like a big win, but FRP takes care of some complexities that tend to swamp MVC apps: managing dynamic dependencies (registering and unregistering event handlers in response to events) and maintaining coherence (i.e. functional behavior) over different event orders.

I haven't yet written a serious application with froc, but so far I think it is awesome!

Sunday, May 3, 2009

Sudoku in ocamljs, part 2: RPC over HTTP

Last time we made a simple user interface for Sudoku with the Dom module of ocamljs. It isn't a very fun game though since there are no pre-filled numbers to constrain the board. So let's add a button to get a new game board; here's the final result.

I don't know much about generating Sudoku boards, but it seems like it might be slow to do it in the browser, so we'll do it on the server, and communicate to the server with OCaml function calls using the RPC over HTTP support in orpc.

The 5-minute monad

But first I'm going to give you a brief introduction to monads (?!). Bear with me until I can explain why we need monads for Sudoku, or skip it if this is old hat to you. We'll transform the following fragment into monadic form:

let foo () = 7 in
bar (foo ())
First put it in named form by let-binding the result of the nested function application:
let foo () = 7 in
let f = foo () in
bar f
Then introduce two new functions, return and bind:
let return x = x
let bind x f = f x

let foo () = return 7 in
bind (foo ()) (fun f ->
  bar f)
These functions are a bit mysterious (although the name "bind" is suggestive of let-binding), but we haven't changed the meaning of the fragment. Next we would like to enforce that the only way to use the result of foo () is by calling bind. We can do that with an abstract type:
type 'a t
val return : 'a -> 'a t
val bind  : 'a t -> ('a -> 'b t) -> 'b t
Taking type 'a t = 'a, the definitions of return and bind match this signature. So what have we accomplished? We've abstracted out the notion of using the result of a computation. It turns out that there are many useful structures matching this signature (and satisfying some equations), called monads. It's convenient that they all match the same signature, in part because we can mechanically convert ordinary code into monadic code, as we've done here, or even use a syntax extension to do it for us.

Lightweight threads in Javascript

One such useful structure is the Lwt library for cooperative threads. You can write Lwt-threaded code by taking ordinary threaded code and converting it to monadic style. In Lwt, 'a t is the type of threads returning 'a. Then bind t f calls f on the value of the thread t once t has finished, and return x is an already-finished thread with value x.

Lwt threads are cooperative: they run until they complete or block waiting on the result of another thread, but aren't ever preempted. It can be easier to reason about this kind of threading, because until you call bind, there's no possibility of another thread disturbing any state you're working on.

Lwt threads are a great match for Javascript, which doesn't have preemptive threads (although plugins like Google Gears provide them), because they need no special support from the language except closures. Typically in Javascript you write a blocking computation as a series of callbacks. You're doing essentially the same thing with Lwt, but it's packaged up in a clean interface.

Orpc for RPC over HTTP

The reason we care about threads in Javascript is that we want to make a blocking RPC call to the server to retrieve a Sudoku game board, without hanging the browser. We'll use orpc to generate stubs for the client and server. In the client the call returns an Lwt thread, so you need to call bind to get the result. In the server it arrives as an ordinary procedure call.

To use orpc you write down the signature of the RPC interface, in Lwt and Sync forms for the client and server. Orpc checks that the two forms are compatible, and generates the stubs. Here's our interface (proto.ml):

module type Sync =
sig
  val get_board : unit -> int option array array
end

module type Lwt =
sig
  val get_board : unit -> int option array array Lwt.t
end
The get_board function returns a 9x9 array, each cell of which may contain None or Some k where k is 1 to 9. We can't capture all these constraints in the type, but we get more static checking than if we were passing JSON or XML.

Generating the board

On the server, we implement a module that matches the Sync signature. (You can see that I didn't actually implement any Sudoku-generating code, but took some fixed examples from Gnome Sudoku.) Then there's some boilerplate to set up a Netplex HTTP server and register the module at the /sudoku path. It's pretty simple. The Proto_js_srv module contains stubs generated by orpc from proto.ml, and Orpc_js_server is part of the orpc library.

Using the board

The client is mostly unchanged from last time. There's a new button, "New game", that makes the RPC call, then fills in the board from the result.

let (>>=) = Lwt.(>>=)
The >>= operator is another name for bind. If you aren't using pa_monad (which we aren't here), it makes a sequence of binds easier to read.
module Server =
  Proto_js_clnt.Lwt(struct
    let with_client f = f (Orpc_js_client.create "/sudoku")
  end)
This sets up the RPC interface, so calls on the Server module become RPC calls to the server. The Proto_js_client module contains stubs generated from proto.ml, and Orpc_js_client is part of the orpc library. (In the actual source you'll see that I faked this out in order to host the running example on Google Code--there's no way to run an OCaml server, so I randomly choose a canned response.)
let get_board rows _ =
  ignore
    (Server.get_board () >>= fun board ->
      for i = 0 to 8 do
        for j = 0 to 8 do
          let cell = rows.(i).(j) in
          let style = cell#_get_style in
          style#_set_backgroundColor "#ffffff";
          match board.(i).(j) with
            | None ->
                cell#_set_value "";
                cell#_set_disabled false
            | Some n ->
                cell#_set_value (string_of_int n);
                cell#_set_disabled true
        done
      done;
      Lwt.return ());
  false
This is the event handler for the "New game" button. We call get_board, bind the result, then fill in the board. If there's a number in a cell we disable the input box so the player can't change it. Here's the full code.

Doing AJAX programming with orpc and Lwt really shows off the power of compiling OCaml to Javascript. While Google Web Toolkit has a similar RPC mechanism (that generates stubs from Java interfaces), it's much clumsier to use, because you're still working at the level of callbacks rather than threads. Maybe you could translate Lwt to Java, but it would be painfully verbose without type inference.

This monad stuff will come in handy again next time, when we'll revisit the problem of checking the Sudoku constraints on the board, using froc.

Sunday, April 26, 2009

Sudoku in ocamljs, part 1: DOM programming

Let's make a Sudoku game with ocamljs and the Dom library for programming the browser DOM. Like on the cooking shows, I have prepared the dish we're about to make beforehand; why don't you taste it now? OK, it is not yet Sudoku, lacking the important ingredient of some starting numbers to guide the game--we'll come back to that next time.

module D = Dom
let d = D.document
We begin with some definitions. The Dom module includes class types for much of the standard browser DOM, using the ocamljs facility for interfacing with Javascript objects. Dom.document is the browser document object.
let make_board () =
  let make_input () =
    let input = (d#createElement "input" : D.input) in
    input#setAttribute "type" "text";
    input#_set_size 1;
    input#_set_maxLength 1;
    let style = input#_get_style in
    style#_set_border "none";
    style#_set_padding "0px";
    let enforce_digit () =
      match input#_get_value with
        | "1" | "2" | "3" | "4" | "5"
        | "6" | "7" | "8" | "9" -> ()
        | _ -> input#_set_value "" in
    input#_set_onchange (Ocamljs.jsfun enforce_digit);
    input in
We construct the Sudoku board in several steps. First, we make an input box for each square. Notice that you can call DOM methods (e.g. createElement) with OCaml object syntax. But what is the type of createElement? The type of the object you get back depends on the tag name you pass in; OCaml has no type for that. So createElement is declared to return #element (that is, a subclass of element). If you need only methods from element then you usually don't need to ascribe a more-specific type, but in this case we need an input node. (Static type checking with Javascript objects is therefore only advisory in some cases--if you ascribe the wrong type you can get a runtime error--but still better than nothing.)

We next set some attributes, properties, and styles on the input box. Properties are manipulated with specially-named methods: foo#_get_bar becomes foo.bar in Javascript, and foo#_set_bar baz becomes foo.bar = baz. Finally we add a validation function to enforce that the input box contains at most a single digit. To set the onchange handler, you need to wrap it in Ocamljs.jsfun, because the calling convention of an ocamljs function is different from that of plain Javascript function (to accomodate partial application and tail recursion).

  let make_td i j input =
    let td = d#createElement "td" in
    let style = td#_get_style in
    style#_set_borderStyle "solid";
    style#_set_borderColor "#000000";
    let widths = function
      | 0 -> 2, 0 | 2 -> 1, 1 | 3 -> 1, 0
      | 5 -> 1, 1 | 6 -> 1, 0 | 8 -> 1, 2
      | _ -> 1, 0 in
    let (top, bottom) = widths i in
    let (left, right) = widths j in
    let px k = string_of_int k ^ "px" in
    style#_set_borderTopWidth (px top);
    style#_set_borderBottomWidth (px bottom);
    style#_set_borderLeftWidth (px left);
    style#_set_borderRightWidth (px right);
    ignore (td#appendChild input);
    td in
Next we make a table cell for each square, containing the input box, with borders according to its position in the grid. Here we don't ascribe a type to the result of createElement since we don't need any td-specific methods.
  let rows =
    Array.init 9 (fun i ->
      Array.init 9 (fun j ->
        make_input ())) in

  let table = d#createElement "table" in
  table#setAttribute "cellpadding" "0px";
  table#setAttribute "cellspacing" "0px";
  let tbody = d#createElement "tbody" in
  ignore (table#appendChild tbody);
  ArrayLabels.iteri rows ~f:(fun i row ->
    let tr = d#createElement "tr" in
    ArrayLabels.iteri row ~f:(fun j cell ->
      let td = make_td i j cell in
      ignore (tr#appendChild td));
    ignore (tbody#appendChild tr));

  (rows, table)
Then we assemble the full board: make a 9 x 9 matrix of input boxes, make a table containing the input boxes, then return the matrix and table. Notice that we freely use the OCaml standard library. Here the tbody is necessary for IE; the cellpadding and cellspacing don't work in IE for some reason that I have not tracked down. This raises an important point: the Dom module is the thinnest possible wrapper over the actual DOM objects, and as such gives you no help with cross-browser compatibility.
let check_board rows _ =
  let error i j =
    let cell = rows.(i).(j) in
    cell#_get_style#_set_backgroundColor "#ff0000" in

  let check_set set =
    let seen = Array.make 9 None in
    ArrayLabels.iter set ~f:(fun (i,j) ->
      let cell = rows.(i).(j) in
      match cell#_get_value with
        | "" -> ()
        | v ->
            let n = int_of_string v in
            match seen.(n - 1) with
              | None ->
                  seen.(n - 1) <- Some (i,j)
              | Some (i',j') ->
                  error i j;
                  error i' j') in

  let check_row i =
    check_set (Array.init 9 (fun j -> (i,j))) in

  let check_column j =
    check_set (Array.init 9 (fun i -> (i,j))) in

  let check_square i j =
    let set = Array.init 9 (fun k ->
      i * 3 + k mod 3, j * 3 + k / 3) in
    check_set set in

  ArrayLabels.iter rows ~f:(fun row ->
    ArrayLabels.iter row ~f:(fun cell ->
      cell#_get_style#_set_backgroundColor "#ffffff"));

  for i = 0 to 8 do check_row i done;
  for j = 0 to 8 do check_column j done;
  for i = 0 to 2 do
    for j = 0 to 2 do
      check_square i j
    done
  done;
  false
Now we define a function to check that the Sudoku constraints are satisfied: that no row, column, or heavy-lined square has more than one occurrence of a digit. If more than one digit occurs then we color all occurrences red. The only ocamljs-specific parts here are getting the cell contents (with _get_value) and setting the background color style. However, it's worth noticing the algorithm: we imperatively clear the error states for all cells, then set error states as we check each constraint. I'll revisit this in a later post about functional reactive programming.
let onload () =
  let (rows, table) = make_board () in
  let check = d#getElementById "check" in
  check#_set_onclick (Ocamljs.jsfun (check_board rows));
  let board = d#getElementById "board" in
  ignore (board#appendChild table)

;;

D.window#_set_onload (Ocamljs.jsfun onload)
Finally we put the pieces together: make the board, insert it into the DOM, call check_board when the Check button is clicked, and call this setup code once the document has been loaded. See the full source for build files.

By writing this in OCaml rather than directly in Javascript, we've gained the assurance of static type checking; we get to use OCaml's syntax, pattern matching, and standard library; we have a for loop that's not broken. On the flip side we have to worry about type ascription and Ocamljs.jsfun. If you don't already think that OCaml is a better language than Javascript, this won't convince you. But perhaps the followup posts, in which I'll show how to use RPC over HTTP with orpc and functional reactive programming with froc, will tip the scales for you.