Evan Martin (evan) wrote in evan_tech,
Evan Martin

hidden state pattern in javascript

A common pattern in functional languages is attaching some mutable state to a function that needs to exist across calls. (Like static local variables in C.) You could just make the state a global variable alongside the function, but you can hide it in a cute way.

The idea is you write a function that has the state as a local variable, then return a closure holding that variable. It's harder to explain in text than it is in code:
# let at_most n f =
    let count = ref 0 in  (* "ref" is ml for "mutable" *)
    fun x ->
      if !count < n then (incr count; f x)
                    else ()
val at_most : int -> ('a -> unit) -> 'a -> unit = <fun>

(* and demonstration: *)
# let say_hi () = print_endline "hi";;
val say_hi : unit -> unit = <fun>
# let limited_say_hi = at_most 2 say_hi;;
val limited_say_hi : unit -> unit = <fun>
# limited_say_hi ();;
- : unit = ()
# limited_say_hi ();;
- : unit = ()
# limited_say_hi ();;
- : unit = ()
(* ... it ran twice, so it will no longer
   produce any output. *)

It occurred to me that this would be pretty useful in JavaScript, especially when you're doing alert()-based debugging. The problem you often run into is that you want to alert() inside of a loop to see a value but if you let the loop go you get an endless cascade of popups.

function at_most(n, f) {
  var i = 0;
  return function(x) {
    if (i++ < n) f(x);
var aler = at_most(3, alert);

(I can't promise I got the JS-closure-fu right, but it seems to work.) I can now sprinkle calls to aler(...) throughout my code and it'll never bring up more than three popups.
Tags: javascript

  • blog moved

    As described elsewhere, I've quit LiveJournal. If you're interested in my continuing posts, you should look at one of these (each contains feed…

  • dremel

    They published a paper on Dremel, my favorite previously-unpublished tool from the Google toolchest. Greg Linden discusses it: "[...] it is capable…

  • treemaps

    I finally wrote up my recent adventures in treemapping, complete with nifty clickable visualizations.

  • Post a new comment


    default userpic
    When you submit the form an invisible reCAPTCHA check will be performed.
    You must follow the Privacy Policy and Google Terms of use.