# Should I use objects in this case?

**URL:** <https://discuss.ocaml.org/t/should-i-use-objects-in-this-case/9860>\
**Category:** Learning\
**Created:** [May 15, 2022, 4:33pm UTC](https://discuss.ocaml.org/t/should-i-use-objects-in-this-case/9860 "2022-05-15T16:33:48Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![user1](https://avatars.discourse-cdn.com/v4/letter/u/5daacb/32.png) [@user1](https://discuss.ocaml.org/u/user1)\
**Post date:** [May 15, 2022, 4:33pm UTC](https://discuss.ocaml.org/t/should-i-use-objects-in-this-case/9860/1 "2022-05-15T16:33:48Z")

</div>

In my program, I have to deal with three kinds of things: orders, which can be carrot orders or milk orders. All three types will appear as arguments of some later functions. My current setup is:

```auto
utop # type order = C of carrot_order | M of milk_order
and carrot_order = {client: string; number: int}
and milk_order = {client: string; volume: float};;

utop # let order_client = function
  C {client; _} | M {client; _} -> client;;
val order_client : order -> string = <fun>

```

This is obviously a toy example, and there are other fields for each type. This permits me to write the later functions that I need. (A more or less equivalent way would be to “factor out” the `client` field, see below.)

However, there is a feel of redundancy in the code above, and there is a collision for the field name `client` (the compiler warns: `(warning 30 [duplicate-definitions])`). Not sure if this is bad. Also, I do not know if the “double pun” I use in the function `order_client` is idiomatic to OCaml or on the contrary is bad practice. My first idea, which seemed natural coming from Python, was to use objects and subtyping or row polymorphism instead. But I seem to understand that objects are not much used in OCaml, and should be used mostly when one needs open recursion ([Objects - Real World OCaml](https://dev.realworldocaml.org/objects.html#when-to-use-objects)), which is not the case here.

So, should I be content with my current solution (or the solution below), or should I use objects, or yet another paradigm ?

* * *

Another possibility: factor out the `client` field, and define a function which constructs an order from a `client` and a `bare_order`:

```auto
utop # type order = {client: string; bare_order: bare_order}
and bare_order = Cb of bare_carrot_order | Mb of bare_milk_order
and bare_carrot_order = {number: int}
and bare_milk_order = {volume: float};;

utop # let order_from_bare_order client bare_order = {client; bare_order};;
val order_from_bare_order : string -> bare_order -> order = <fun>

```

This also looks a bit verbose.

---

<div class="post-metadata">

**Author:** ![yawaramin](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/yawaramin/32/3384_2.png) [@yawaramin](https://discuss.ocaml.org/u/yawaramin)\
**Post date:** [May 15, 2022, 4:48pm UTC](https://discuss.ocaml.org/t/should-i-use-objects-in-this-case/9860/2 "2022-05-15T16:48:24Z")

</div>

The factored approach looks good to me. The functions which later handle the orders will ultimately tell you if it’s good or bad. If they are simple to implement, it’s good. A little verbosity now will pay off later.

---

<div class="post-metadata">

**Author:** ![Chet\_Murthy](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/chet_murthy/32/1501_2.png) [@Chet\_Murthy](https://discuss.ocaml.org/u/Chet_Murthy)\
**Post date:** [May 15, 2022, 4:48pm UTC](https://discuss.ocaml.org/t/should-i-use-objects-in-this-case/9860/3 "2022-05-15T16:48:45Z")

</div>

Two thoughts:

1. OCaml’s objects don’t admit downcast (from order down to milk and carrot orders). So if you need to do lots of those “match …with” on your orders, then objects aren’t going to be good for that.
2. But OTOH, if you only have a few such matches, then sure, you can turn each match into a method on order.

But really, objects are designed for when you have a large and ad-hoc hierarchy of types, maybe even extensible by consumers of your library. If you literally have only these two examples, why bother with objects? And also, your example code _does_ seem verbose. I mean …

```auto
type order = string * bare_order
and bare_order = Cb of int | Mb of float
;;
let mk c b : order = (c,b);;
let carrot c n : order = (c,Cb n);;
let milk c n : order = (c,Mb n);;

```

It isn’t necessary to wrap things up in records.

---

<div class="post-metadata">

**Author:** ![Mhouh](https://avatars.discourse-cdn.com/v4/letter/m/838e76/32.png) [@Mhouh](https://discuss.ocaml.org/u/Mhouh)\
**Post date:** [May 15, 2022, 11:15pm UTC](https://discuss.ocaml.org/t/should-i-use-objects-in-this-case/9860/4 "2022-05-15T23:15:26Z")

</div>

Having records is nice if you read the fields or do an update. More concise, and less problem with typing, in my opinion.
