Using `rec` for non-recursive functions?


#1

Code style question:

I’ve a reducer function that looks like this:

let reducer = (action: action, state: state) => {
  switch(action) {
    | Action1(x) => ReasonReact.Update(...)
    | Action2(x) => ReasonReact.Update(...)
    | Action3(x) => ReasonReact.Update(...)
    | Action4(x) => ReasonReact.UpdateWithSideEffects(..., (self) => {
       /* A lot of code in here */
       /* A lot of code in here */
       /* A lot of code in here */
       /* A lot of code in here */
       /* A lot of code in here */
       /* A lot of code in here */
    })
  };
}

I would like to keep the side effects updating function separately, outside of reducer. I can declare it above the reducer like this:

let doSideEffects = (self) => {
       /* A lot of code in here */
       /* A lot of code in here */
       /* A lot of code in here */
       /* A lot of code in here */
       /* A lot of code in here */
       /* A lot of code in here */
};

let reducer = (action: action, state: state) => {
  switch(action) {
    | Action1(x) => ReasonReact.Update(...)
    | Action2(x) => ReasonReact.Update(...)
    | Action3(x) => ReasonReact.Update(...)
    | Action4(x) => ReasonReact.UpdateWithSideEffects(..., doSideEffects)
  };
}

I don’t find this ideal because it’s the reducer() that I care about the most, I’ll be looking at it most often, and is the entry point to the whole module. I would like to see it on top, above doSideEffects().

So I could either move the doSideEffects() to another file/module, but that’d be a bit artificial as it belongs in the same module as reducer().

I can also use let rec ... and ... this way:

let rec reducer = (action: action, state: state) => {
  switch(action) {
    | Action1(x) => ReasonReact.Update(...)
    | Action2(x) => ReasonReact.Update(...)
    | Action3(x) => ReasonReact.Update(...)
    | Action4(x) => ReasonReact.UpdateWithSideEffects(..., doSideEffects)
  };
}
and doSideEffects = (self) => {
       /* A lot of code in here */
       /* A lot of code in here */
       /* A lot of code in here */
       /* A lot of code in here */
       /* A lot of code in here */
       /* A lot of code in here */
};

This reads nicely, but… - is it idiomatic to use let rec for non-recursive functions? If you stumbled upon such code, would you be confused? Is there another way I didn’t think of?


#2

What about making the doSideEffects an inline function of the reducer?


#3

doSideEffects() would still have to be above the reducer’s main switch() {...} clause. So that’s almost the same as with it just coming before the whole reducer().


#4

I believe it’s not idiomatic. OCaml encourages a bottom-up style where you define things before using them. Hence you will usually see the helper stuff at the top of your modules, and the main code near the bottom of the modules.


#5

Cheers.

That’s what I suspected anyway :wink: