0

I have defined the following function that computes the greatest common divisor of two numbers.

let rec gcd n m = if m = 0 then n else gcd m (n mod m);;

It wouldn't work without the keyword rec.

I'm curious, why is there a need to have rec?

There is no other function called gcd in scope so it's clear what the compiler has to call.

Even if there would be another function gcd in scope, the compiler could try matching in some order and see what fits, like in Haskell.

Can you give an example of why this is useful?

bsky
  • 19,326
  • 49
  • 155
  • 270
  • Does `rec` indicate that you want it to perform TCO? If that's the case, it's like Scala's recursive annotation that warns you if it can't optimize the recursion. – Carcigenicate Oct 25 '16 at 12:38
  • @Carcigenicate: No, `rec` is required for any recursive function definition. – Marth Oct 25 '16 at 12:39
  • 2
    Possible duplicate of [Why are functions in Ocaml/F# not recursive by default?](http://stackoverflow.com/questions/900585/why-are-functions-in-ocaml-f-not-recursive-by-default) – Marth Oct 25 '16 at 12:41
  • Half duplicate of http://softwareengineering.stackexchange.com/q/162583/139925? It's about F#, but apparently they're similarly rooted. – Carcigenicate Oct 25 '16 at 12:41
  • 1
    Haskell doesn't see what fits. In Haskell the name `gcd` would always refer to the function itself in its definition. If there were a previous value with that name in scope, it'd be shadowed for as long as the new `gcd` is in Scope. – sepp2k Oct 25 '16 at 12:45
  • 1
    Possible duplicate of [What's the reason of 'let rec' for impure functional language OCaml?](http://stackoverflow.com/questions/28796904/whats-the-reason-of-let-rec-for-impure-functional-language-ocaml) – ivg Oct 25 '16 at 12:46
  • @sepp2k I meant that you can declare the same function multiple times with different arguments, and the compiler pattern matches the call from up to down. – bsky Oct 25 '16 at 13:03
  • 1
    @octavian You're talking about defining one function that does pattern matching on its arguments. But you can't define multiple functions that way. If you do `f x = x` and then `f x y = y` in the same module, that's an error. You can't have multiple functions with the same name in Haskell. – sepp2k Oct 25 '16 at 13:07
  • sorry, I didn't express myself well. yes, I meant pattern matching on arguments – bsky Oct 25 '16 at 13:10

1 Answers1

3

Most of the functions are nonrecursive, so it is a reasonable, that by default, the function name is not visible in its body. This also helps in redefining a function, suppose you have module User with name function, and you would like to redefine it in your new module:

module User = struct 
   type t = {name : string}
   let name t = t.name
end

module RespectedUser = struct 
  include User
  let name t = "Mr. " ^ name user
end

If name name (what a bad choice of a function name for the example) would be visible in the body, then it would be much harder to implement the name function. It will stand in the way more often, then it is actually needed. This is always a problem for me while programming in Haskell, when you accidentally make a function recursive, although you just wanted to overload an existing function.

ivg
  • 34,431
  • 2
  • 35
  • 63
  • 2
    Neither Haskell nor OCaml support overloading. You definition of `name` replaces the old one. – sepp2k Oct 25 '16 at 12:59
  • I meant overriding (usually confuse these two words). And OCaml supports methods overloading, as methods has late binding. – ivg Oct 25 '16 at 13:06
  • 3
    Overloading is if you have two functions with the same name, but a different number or type of arguments and the compiler calls the right one based on which arguments you call it with. Overriding is if a subclass defines a method with the same signature as a supertype and the correct version is picked at runtime based on the receiver's type. OCaml does not support the former. It does support the latter. What you did is neither. – sepp2k Oct 25 '16 at 13:10
  • Nope, just checked the terminology, I was right. It is called overloading. When you overload an existing name in the scope with the new method. And overriding is when you rebound the same variable to the new name. – ivg Oct 25 '16 at 13:10
  • (Previous answer, was a comment to my second comment, it comes at the same time as your comment). Well, we pick the terminology from different languages, and the terminology is not fixed so far. I have a different definition of overloading. Probably, name rebinding would be better. Do you agree? – ivg Oct 25 '16 at 13:13