views:

236

answers:

2

I'm a very novice OCaml programmer so please forgive me if this is a stupid/obvious question. There's a lot to absorb and I may have missed this in the documentation.

I have a base of code that's starting to look like this:

let update_x p x =
  add_delta p;
  p.x <- x;
  refresh p

let update_y p y =
  add_delta p;
  p.y <- y;
  refresh p

let update_z p z =
  add_delta p;
  p.z <- z;
  refresh p

The duplication is starting to bug me because I want to write something like this:

let update_scalar p scalar value =
    add_delta p;
    magic_reflection (p, scalar) <- value;
    refresh p

This way when I update x I can simply call:

update_scalar p 'x' value

This calls out "macros!" to me but I don't believe OCaml has a macro system. What else can I do?

+1  A: 

No, you can't do what you want in plain OCaml. You could write a syntax extension with camlp4 (which is a kind of a macro system, though a different kind than you're probably accustomed to) that would transform

UPDATE_FIELD p x val

into

p.x <- val

Alternatively, you could stuff things into a hash table and forgo type safety.

NOTE: The version of camlp4 included in OCaml version 3.10 and later is different than and incompatible with the previous version. For information about the latest version, see the OCaml tutorial site.

Chris Conway
+2  A: 

You can't do quite what you want, but you can greatly reduce the boilerplate with a higher-order function:

let update_gen set p x =
  add_delta p;
  set p x;
  refresh p

let update_x = update_gen (fun p v -> p.x <- v)
let update_y = update_gen (fun p v -> p.y <- v)
let update_z = update_gen (fun p v -> p.z <- v)

OCaml does have a macro system (camlp4) and it does allow you to implement this kind of thing, with some work.

zrr