ocaml / ocaml.org

The official OCaml website.
https://ocaml.org
Other
156 stars 311 forks source link

elaborate more on functor comparing to higher order function #2607

Open geohuz opened 1 month ago

geohuz commented 1 month ago

In the ocaml docmentation chapter functor, when I read this paragraph:

Note: Most set operations need to compare elements to check if they are the same. To allow using a user-defined comparison algorithm, the Set.Make functor takes a module that specifies both the element type t and the compare function. Passing the comparison function as a higher-order parameter, as done in Array.sort, for example, would add a lot of boilerplate code. Providing set operations as a functor allows specifying the comparison function only once.

I couldn't image how the higher order function way can "add a lot of boilerplate code", as a new ocaml user this can be confusing. I've tried to look at source code like Map module, I found a funcion that calling compare like add:

let rec add x data = function
        Empty ->
          Node{l=Empty; v=x; d=data; r=Empty; h=1}
      | Node {l; v; d; r; h} as m ->
          let c = Ord.compare x v in
          if c = 0 then
            if d == data then m else Node{l; v=x; d=data; r; h}
          else if c < 0 then
            let ll = add x data l in
            if l == ll then m else bal ll v d r
          else
            let rr = add x data r in
            if r == rr then m else bal l v d rr

So for this case, the add function if without functor, then we have to define it like this:

let rec add x data cmp = function
....

I'm not sure if I understand it correctly, but I guess this should be one of the rational of using functor instead of higher order function. I wish this can be elaborated in a crystal clear way because that is the point of having functor in Ocaml?

cuihtlauac commented 1 month ago

Hi @geohuz, thanks for your careful reading and feedback; this is helpful.

Passing the comparison function as a higher-order parameter, as done in Array.sort, for example, would add a lot of boilerplate code.

Yes, this sentence isn't great.

I couldn't image how the higher order function way can "add a lot of boilerplate code", as a new ocaml user this can be confusing.

You are right.

I'm not sure if I understand it correctly, but I guess this should be one of the rational of using functor instead of higher order function.

Yes, you got it right. This is what a functor allows, not having to pass the comparison function (for instance) at each function call.

“Boilerplate” isn't a great term, but client code is somehow simpler/shorter as the comparison function isn't passed at each call to a functor-hosted function.

And yes, this is one of the main rationales for using functors.

Do you have suggestions on how to improve this text?

geohuz commented 1 month ago

Hi @cuihtlauac, thanks for your prompt reply! My suggestion is to give an example to explain the idea, so this can happen in other functors like Set...

cuihtlauac commented 1 month ago

Do you want to propose a PR with with? It would be easier to discuss the matter with the actual example. An we love contributions :-)