F# basic function definition syntax
In the comments to this post, Anon and Josh complain about the syntax of F#. On one hand, they've got a point: most programmers are used to notations similar to those of Visual Basic, C# or Java, and for them many of the syntactic details of F# will look weird (or just plainly annoying ;-) ). On the other hand, it's not the case -as Josh suggests- that Microsoft is creating a new language with a purposedly cryptic syntax :-D; actually, F# was designed to follow as much as possible the syntax -and semantics- of OCaml (1996), a popular language in the functional world. OCaml in turn basically offers object-oriented extensions to Caml (1985), which inherits most of its syntax -and semantics- from ML (circa 1973). So, as much as I would like to say that Microsoft has created a whole new language, its more like it is moving the spotlight to a tradition as old (LISP anyone?) as imperative languages themselves, by providing an implementation nicely integrated into .NET Framework.
But, history and traditions apart, as Anon says, F# could look like greek to someone fluent in C#, so I'll try to give you one or two tips on the basic fsharpian vocabulary:
In line 2, you can see how you define a function in F#, a few points worth mentioning:
-
You don't need parenthesis to surround the parameters
-
You don't use commas to separate parameters, a simple blank space will do (and beware that the comma is used to denote a totally different thing: a tuple, but let's not get ahead of ourselves).
-
To separate the "head" (my term) of the function from its "body" you put an equal sign
-
To the right of the equal sign you put the expression that is evaluated every time you call the function (just one expression, mind you, although it can perfectly grow to fill several lines, and it usually does)
-
There are no methods or procedures in F#, just functions, everything you call must return something
-
The function definition ends when:
-
The line finishes, as in my example in line 2
-
If we are using the so called "light" syntax (which will be so most of the time), the body indents one or more spaces to the right of the let keyword, in this case the function finishes when the indentation finishes, as in the other 3 examples of the figure above
-
One curious thing is the fact that, most of the time, you don't need to declare the type of the parameters or the result, but beware:
-
F# is a totally strongly typed language (like C# or Java) so everything has a type
-
What's going on is that F# has a powerful type inference mechanism, so the compiler (yes, F# is compiled not interpreted) deducts the type of the parameters and the results from the operations you do with them. For example, when you do oper1 * oper2, you already know that oper1 and oper2 must be numbers. This works like a charm and trasparently in most scenarios, but sometimes you have to give a hand to the compiler by writing down the types explicitly, but again let's live that for (very) later
All in all, if you think about it, F# syntax is simpler than that of C#, what with:
let addSquares a b = a * a + b * b
Instead of:
int AddSquares(int a, int b) { return a * a + b * b; }
So in the end we have a very clean result, but, whew, now that I tried to explain it, may be Josh has got a point indeed: there's a lot to be said about F# syntax, so I'll live the explanation of the dreaded match expression for other night ;-). Furthermore, you'll have to trust me: after a few nights toying with the language you'll become comfortable with the syntax.
One last interesting point to note is that, syntax aside, the real power of languages like F# lays in its semantics and power of expression, that's why a sizable portion of that power has been implemented in C# 3.0 and VB 9 (LINQ being its more visible offspring) so, even if you run from the F# syntax, you won't be able to hide from its semantics... ;-)