# Function argument polymorphism

**URL:** <https://discuss.ocaml.org/t/function-argument-polymorphism/3224>\
**Category:** Learning\
**Created:** [January 24, 2019, 8:01am UTC](https://discuss.ocaml.org/t/function-argument-polymorphism/3224 "2019-01-24T08:01:39Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![XVilka](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/xvilka/32/5334_2.png) [@XVilka](https://discuss.ocaml.org/u/XVilka)\
**Post date:** [January 24, 2019, 8:01am UTC](https://discuss.ocaml.org/t/function-argument-polymorphism/3224/1 "2019-01-24T08:01:39Z")

</div>

For example I have two different record types, like:

```
   type rec1 = {
       prop1 : int;
       prop2 : int;
       prop3 : int;
       prop3 : int;
   }
   type rec2 = {
       prop4 : int;
       prop2 : int;
       prop3 : int;
       prop5 : int;
   }

```

where they have prop2 and prop3 in common, but rest is different.  
And I want to write a function which takes an argument of type rec1 or rec2 and uses only prop2 and prop3 from them. But I don’t want to duplicate a code if create two different functions for different argument types. And creating a sum type is not an option. Are there any more ways to achieve that?

---

<div class="post-metadata">

**Author:** ![jfeser](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/jfeser/32/2093_2.png) [@jfeser](https://discuss.ocaml.org/u/jfeser)\
**Post date:** [January 24, 2019, 8:11am UTC](https://discuss.ocaml.org/t/function-argument-polymorphism/3224/2 "2019-01-24T08:11:24Z")

</div>

OCaml functions aren’t allowed to be polymorphic over record fields this way. However, this kind of polymorphism is a classic use case for objects! Instead of records you can create two objects:

```
let rec1 =
  object
    method prop1 = 1
    method prop3 = 2
  end
let rec2 =
  object
    method prop2 = 3
    method prop3 = 4
  end
let func r = r#prop3
let x = func rec1
let y = func rec2

```

If you check the types you’ll see that `func` is polymorphic, and accepts any object with a `prop3` method:

`val func : < prop3 : 'a; .. > -> 'a`

---

<div class="post-metadata">

**Author:** ![XVilka](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/xvilka/32/5334_2.png) [@XVilka](https://discuss.ocaml.org/u/XVilka)\
**Post date:** [January 24, 2019, 8:15am UTC](https://discuss.ocaml.org/t/function-argument-polymorphism/3224/3 "2019-01-24T08:15:35Z")

</div>

Interesting, thank you! A bit inconsistent for my taste - such drastic difference in handling them.

---

<div class="post-metadata">

**Author:** ![smolkaj](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/smolkaj/32/266_2.png) [@smolkaj](https://discuss.ocaml.org/u/smolkaj)\
**Post date:** [January 24, 2019, 10:42am UTC](https://discuss.ocaml.org/t/function-argument-polymorphism/3224/4 "2019-01-24T10:42:48Z")

</div>

If you’re interested, the theorey for how to add this kind of polymorphism to an ML like language while keeping decidable type inference has recently been worked out:  
[https://www.cl.cam.ac.uk/~sd601/mlsub/](https://www.cl.cam.ac.uk/~sd601/mlsub/)

It’s more complicated than you might imagine at first. This was an open problem for quite a while.
