# Styles in defining functions

**URL:** <https://discuss.ocaml.org/t/styles-in-defining-functions/9983>\
**Category:** Learning\
**Tags:** performance\
**Created:** [June 6, 2022, 11:38pm UTC](https://discuss.ocaml.org/t/styles-in-defining-functions/9983 "2022-06-06T23:38:27Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![zhtprog](https://avatars.discourse-cdn.com/v4/letter/z/58f4c7/32.png) [@zhtprog](https://discuss.ocaml.org/u/zhtprog)\
**Post date:** [June 6, 2022, 11:38pm UTC](https://discuss.ocaml.org/t/styles-in-defining-functions/9983/1 "2022-06-06T23:38:27Z")

</div>

I noticed a style of defining top functions without its arguments, as in:

```auto
let f =
  let aux1 = ... in
  let aux2 ... = ... in
  (* now really define the function *)
  let f x y z = ... in
  f 

```

This way aux values are defined within the local scope but evaluated once. I wonder if there is any performance advantage writing in this style when compared to the more “conventional”(?) style:

```auto
let f x y z =
  let aux1 = ... in
  let aux2 ... = ... in
  ...

```

---

<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:** [June 7, 2022, 1:14am UTC](https://discuss.ocaml.org/t/styles-in-defining-functions/9983/2 "2022-06-07T01:14:41Z")

</div>

There could be, depends on if `aux1`/`aux2` are expensive to calculate. Some people just don’t like doing extra work in functions if it can be avoided especially if the function is in a hot path. Some functions are called only once so it doesn’t really matter.

---

<div class="post-metadata">

**Author:** ![glennsl](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/glennsl/32/142_2.png) [@glennsl](https://discuss.ocaml.org/u/glennsl)\
**Post date:** [June 7, 2022, 9:27am UTC](https://discuss.ocaml.org/t/styles-in-defining-functions/9983/3 "2022-06-07T09:27:28Z")

</div>

It can also be useful for controlling and scoping side-effects. Consider this id generation function, for example:

```auto
let generate_id =
  let last_id = ref 0 in
  fun () -> 
    incr last_id; 
    !last_id

```

---

<div class="post-metadata">

**Author:** ![emillon](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/emillon/32/1206_2.png) [@emillon](https://discuss.ocaml.org/u/emillon)\
**Post date:** [June 7, 2022, 11:34am UTC](https://discuss.ocaml.org/t/styles-in-defining-functions/9983/4 "2022-06-07T11:34:33Z")

</div>

As an example, this style is often used with the `re` library. There’s a `Re.t` type which describes regexps (a sort of AST I suppose) and a `Re.re` type which is for compiled regexps (a sort of DFA maybe). There’s a function `Re.compile` to turn `Re.t` into `Re.re`, and the rest of the library expects `Re.re` values. Since `Re.compile` can be expensive, this patterns allows the compiled regexp to have local scope but a global lifetime:

```ocaml
let parse_line =
  let re = Re.compile (Re.seq [Re.alt [...]]) in
  fun line ->
  match Re.exec re line with
  ...

```
