Computer Science Canada

Getting Graphic With O'Caml

Author:  wtd [ Tue May 31, 2005 6:37 pm ]
Post subject:  Getting Graphic With O'Caml

Those who program in Turing are used to its built-in graphics functions, and I find, frequently look upon other languages as inferior if they don't offer the same, regardless of other advantages those languages may bring to the table.

With that in mind, I offer a modern language with similar capabilities: Objective-Caml. Let's dive in.

code:
open Graphics;;

let count = ref 0;;

open_graph " 640x480";;
set_window_title "A Quick Program";;

while true do
   if button_down () then
      let (x, y) = mouse_pos () in
      let coord = string_of_int x ^ "x" ^ string_of_int y in
         begin
            moveto x y;
            draw_string coord;
            print_int !count;
            print_newline ()
         end;
   count := !count + 1     
done


This can be compiled with:

code:
ocamlc graphics.cma sourcefile.ml -o myprog


And then run the resulting "myprog" executable.

The program above runs infinitely (unless one interrupts it), opening a graphics window, then displaying the mouse position each time a click is registered.

Let's look at it line by line.

code:
open Graphics;;


This is simply a convenience step. With it we can avoid having to tack "Graphics." onto the front of every function from the Graphics module.

code:
let count = ref 0;;


Here we declare a reference variable, or a truly variable variable. In this case it's a counter for the number of times the loop has looped.

code:
open_graph " 640x480";;
set_window_title "A Quick Program";;


Here I'm opening the window, with an initial size of 640 pixels by 480 pixels. The I set the title of the window. Pretty straightforward stuff.

Now, for the loop which does all of the fun work.

code:
while true do ... done


Basically loop forever. After this, O'Caml expects some sequence of expressions, then "done".

code:
if button_down () then


A conditional. This checks to see if the mouse button was pressed.

code:
let (x, y) = mouse_pos () in


A couple of local variables. "mouse_pos ()" returns a tuple (pair) of integers representing the x and y positions of the mouse pointer. We use pattern matching to put that info into two variables.

code:
let coord = string_of_int x ^ "x" ^ string_of_int y in


Here we create another local variable. This one is a string representation of the coordinate. The "string_of_int" function converts an integer to a string. The "^" operator concatenates two strings.

code:
begin ... end


An "if" expression only has one expression following the "then". We need several expressions. A begin ... end block conveniently turns a sequence of expressions into a single expression.

code:
moveto x y;


This function from the Graphics module moves the current drawing position to the place where the mouse button was clicked.

code:
draw_string coord;


This function actually draws the coordinate string to the screen.

code:
print_int !count;


Here we print the current loop count to the console. Since "count" is a reference, we have to dereference it with the ! operator.

code:
print_newline ()


And then we skip to a newline on the console.

code:
count := !count + 1


Each time around we increment the count by one. To do this we need to assign a new value to count, with the := operator. As before, the ! operator gets at the value stored in count. The rest simply adds one to that value.

Questions, comments?

Feel free to send them along.

More such tutorials may follow.


: