# Physical equality of functions

**URL:** <https://discuss.ocaml.org/t/physical-equality-of-functions/8993>\
**Category:** Learning\
**Created:** [December 10, 2021, 7:15pm UTC](https://discuss.ocaml.org/t/physical-equality-of-functions/8993 "2021-12-10T19:15:52Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![nated](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/nated/32/6354_2.png) [@nated](https://discuss.ocaml.org/u/nated)\
**Post date:** [December 10, 2021, 7:15pm UTC](https://discuss.ocaml.org/t/physical-equality-of-functions/8993/1 "2021-12-10T19:15:52Z")

</div>

So… I’ve been trying to understand hash functions better, and so I was passing random stuff into Hashtbl.hash.

Apropos of nothing, I tried passing functions into `Hashtbl.hash` to see what would happen, and found that some functions produce new hashes every time and some produce the same hash every time, which piqued my curiosity. I noticed I could also observe this by testing a function for physical equality with itself. (Also it’s fun to make ascii robot faces like `(+) == (+)` in utop.)

I promise I’m not going to use this knowledge for anything (😅), but why are some functions physically equal to themselves and some aren’t? My only guess is that ones that aren’t equal are being inlined on use, but I have no idea.

---

<div class="post-metadata">

**Author:** ![mnxn](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/mnxn/32/2445_2.png) [@mnxn](https://discuss.ocaml.org/u/mnxn)\
**Post date:** [December 10, 2021, 8:25pm UTC](https://discuss.ocaml.org/t/physical-equality-of-functions/8993/2 "2021-12-10T20:25:33Z")

</div>

I think it depends if the function was declared with `external` or not:

```ocaml
external id1 : 'a -> 'a = "%identity"
let id2 x = x

```

`id1 == id1` is false, but `id2 == id2` is true.

---

<div class="post-metadata">

**Author:** ![nated](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/nated/32/6354_2.png) [@nated](https://discuss.ocaml.org/u/nated)\
**Post date:** [December 10, 2021, 9:06pm UTC](https://discuss.ocaml.org/t/physical-equality-of-functions/8993/3 "2021-12-10T21:06:11Z")

</div>

Oh interesting. There are more externals than I thought (I’m surprised stuff like `|>`, `@@`, `ignore`, and `incr` are external). Thanks!

---

<div class="post-metadata">

**Author:** ![nojb](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/nojb/32/519_2.png) [@nojb](https://discuss.ocaml.org/u/nojb)\
**Post date:** [December 10, 2021, 10:52pm UTC](https://discuss.ocaml.org/t/physical-equality-of-functions/8993/4 "2021-12-10T22:52:06Z")

</div>

> [@mnxn](#):
>
> I think it depends if the function was declared with `external` or not:

Indeed, externals are not first-class objects in the language and each mention of `id1` as a variable it implicitly eta-expanded to `fun x -> id1 x` causing a fresh allocation.

Cheers,  
Nicolas
