Fully destructure a record


#1

I was surprised that the compiler didn’t complain about a missing age field in the following code:

  type foo = {
    name: string,
    age: int,
  };
  let f: foo => unit =
    foo => {
      let {name} = foo;
      Js.log(name);
    };

Am I right that when you destructure a record in plan ocaml, you need to handle all the fields? Either way, is there a way to destructure a record s.t. the compiler will force you to handle all the fields?

In my experience, this is a valuable way for the compiler to help you after a record field is added. Let’s say you previously had a function that converted the record to a Js.Json.t, it’d be nice if that function complained when you later added a new field to the record and haven’t yet updated the function to handle that field.


#2

You can add some compiler flags to enable that behaviour


#3

Ok, thanks. It looks like I want to enable compiler error #9, documented here. Do you know how to actually do that?


#4

You can put a setting in bsconfig.json. See https://bucklescript.github.io/docs/en/build-configuration.html#warnings


#5

Great, thanks! That worked.

FYI - to make it work, I had to add +9 to both the numbers and errors field of warnings within the bsconfig, i.e.:

  "warnings": {
    "number": "+9",
    "error" : "+101+9"
  },

I kind of expected just adding +9 to the error section to work. Do you know why I had to do both?


#6

Oh, good point, that’s because # 9 is not one of the warnings OCaml or BuckleScript turn on by default (see What warnings/errors do you always enable (or disable)? for a listing of the defaults). We need to turn it on as a warning and then also upgrade it to a fatal error.