Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Record-type recursive member functions and the "rec" keyword

I've always believed that in F# we needed to use the rec keyword for every recursive function, for example:

let rec factorial = function | 0 -> 1 | k when k > 0 ->  k * (factorial (k - 1)) | failwith "oops!" 

Today I was playing around with F# and I came up with a code similar to the following:

let MyRecordType =     { Something     : float;       SomethingElse : int }     with         static member factorial = function             | 0 -> 1             | k when k > 0 ->  k * (MyRecordType.factorial (k - 1))             | failwith "oops!" 

As you see, I've just defined a recursive function, but I made what at first seemed like a mistake: I forgot to declare the function as recursive by means of the rec keyword.

But to my surprise it compiles! And there's more to it: if you add the rec keyword, then it is a syntax error!

type MyRecordType =     { (* ... *) }     with         // syntax error:         static member rec factorial = function         (* ... *) 

I've googled around for an explanation but got nothing. In the MSDN documentation, I couldn't find any mention to the rec keyword outside the page about recursive functions, and as of 2010-01-03 it does not mention the case I'm asking about.

Exactly the same thing happens with non-static members.

So, why is it a syntax error to use the rec keyword on member functions of a record-type?

like image 338
Bruno Reis Avatar asked Jan 03 '10 19:01

Bruno Reis


People also ask

Which keyword is used to define a recursive function?

The rec keyword is used together with the let keyword to define a recursive function.

What are recursive functions give three examples?

For example, Count(1) would return 2,3,4,5,6,7,8,9,10. Count(7) would return 8,9,10. The result could be used as a roundabout way to subtract the number from 10. function Count (integer N) if (N <= 0) return "Must be a Positive Integer"; if (N > 9) return "Counting Completed"; else return Count (N+1); end function.

What is let REC in OCaml?

OCaml uses let to define a new function, or let rec to define a function that is recursive. Why does it need both of these - couldn't we just use let for everything?


2 Answers

All "member" functions are implicitly "rec" within the type they're defined in.

like image 67
Brian Avatar answered Sep 22 '22 20:09

Brian


'let rec' isn't about defining recursive functions, but defining a binding in an environment, that includes the binding for the current variable to be bound. You could use 'let rec' just as well to define e.g. an infinite list. Often, you don't want the binding to be included in the environment, as you might want to access an earlier variable by the same name.

When you are defining the static member function, factorial, you aren't looking for a binding for a variable 'factorial', but for a type 'MyRecordType' (which is in the environment as a type definition), and if it happens to have a static member function called 'factorial', which it has.

like image 32
Sami Avatar answered Sep 21 '22 20:09

Sami