Version franaise
Home About Download Resources Contact us

This site is updated infrequently. For up-to-date information, please visit the new OCaml website at

Browse thread
The Implicit Accumulator: a design pattern using optional arguments
[ Home ] [ Index: by date | by threads ]
[ Search: ]

[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
Date: 2007-06-27 (12:20)
From: Jon Harrop <jon@f...>
Subject: The Implicit Accumulator: a design pattern using optional arguments

I can't find the thread where we were talking about design patterns recently 
but I'd like to note a design pattern that works nicely in OCaml. I'll call 
it "The Implicit Accumulator".

ML programmers often use nested auxiliary functions or separate functions to 
handle base cases. For example, writing rev in terms of rev_append:

# let rec rev_append l1 l2 = match l1 with
    | [] -> l2
    | a :: l -> rev_append l (a :: l2);;
val rev_append : 'a list -> 'a list -> 'a list = <fun>
# let rev l = rev_append l [];;
val rev : 'a list -> 'a list = <fun>

Provided performance is unimportant, you can make the accumulator implicit in 
OCaml by specifying the default value in an optional argument instead of 
having a separate function:

# let rec rev ?(back=[]) = function
    | [] -> back
    | h::t -> rev ~back:(h::back) t;;
val rev : ?back:'a list -> 'a list -> 'a list = <fun>

When you don't want the auxiliary (rev_append) function, I think this style 
results in shorter and clearer code. I used it in the "search" function of my 
Sudoku solver, for example:

let rec search ?(x=0) ?(y=0) f accu = match x, y with
    9, y -> search ~x:0 ~y:(y+1) f accu (* Next row *)
  | 0, 9 -> f accu                      (* Found a solution *)
  | x, y ->
      if m.(y).[x] <> '0' then search ~x:(x+1) ~y f accu else
        fold (fun accu n ->
                let n = Char.chr (n + 48) in
                if invalid x y n then accu else
                  (m.(y).[x] <- n;
                   let accu = search ~x:(x+1) ~y f accu in
                   m.(y).[x] <- '0';
                   accu)) accu 1 10

and it crops up quite a lot in addition to all of the "conventional" uses of 
optional arguments.

Dr Jon D Harrop, Flying Frog Consultancy Ltd.
The OCaml Journal