ocamlocaml-batteries

How to return void in a function in OCaml?


Simple example: I have some functions and I need to call them all, to modify a structure, only in one function. With these simple functions the task can be made in ways that don't use void, but in others tasks you have to use void. So what can you do?

type player = { mutable name : string; mutable points : int } ;;

let putname brad = match brad with
  { name = x; points = y } -> { name = brad; points = y } ;;

let putpoint guy score = match guy with
  { name = x; points = y } -> { name = x; points = score } ;;

let loosers listplayer guy = guy :: listplayer ;;

Here is the problem - How can I do the next function?

let someoneloses guy = void

guy = putpoint guy 0 ;;
listplayer = loosers (listplayer guy) ;;

Solution

  • Given you are using the name "void" I'm assuming you are more familiar with C (or C++). In OCaml the equivalent of "void" (the name of the type for no value) is "unit". There is another difference though: while in C the syntax is complex enough that it have constructs for no values (for instance, you can either "return a_value;" or "return;", two differents yet syntactically valid use cases for the keyword "return"), in OCaml the syntax is simpler and always require a value. So we have a notation for "nothing", which is, astutely but maybe also confusedly, is written "()". So, the OCaml equivalent of the C:

    void do_nothing(void) { return; }
    

    is written:

    let do_nothing () = ()
    

    (notice how OCaml syntax is simpler and easier to grok once you got the "()" trick).

    Now that this is hopefully clearer, back to your question.

    A function that returns nothing is a function that return "()", either explicitly (as "do_nothing" above) or because it ends with an expression that has "()" as its value. For instance, an assignment (something tell me you'll love assignments), such as:

    let putpoint guy score = guy.points <- score
    

    Now back to your problem. You seem to be doing some kind of game with players represented as mutable records and some functions modifying those records as the game develop. You need not use pattern matching for that. Actually, functions such as "putpoint" above is probably what you want. But then you need some more state in your program: the list of loosers for instance is probably going to be a reference to a list that you modify etc.

    This is the "imperative" side of OCaml but there is another one, which is usually regarded as more elegant although often slower in general (but not in functional languages which are optimised for this technique), consisting of refraining from altering state (changing values of things) but instead using functions merely taking values and returning values. Implemented like this, a player would be represented as an immutable record and each function acting a user would take an "old user" and return a "new user", and the same goes with the list of loosers, and so on. Actually, the whole game state would be represented as a big value that the "main loop" of your program would, given the previous value, and possible also the time and user inputs, would compute the "new state" and return it.

    Have fun!

    Also, your question has nothing to do with ocaml-batteries.