Jomo Fisher--A few weeks ago, a fellow C# programmer asked me what the biggest differences between programming in C# and programming in F# are. Since then, I've been building a list of differences. My plan was to write a single article that discussed everything. This morning the list got too long to reasonably put in a single article. Also, I'm not sure when I'll be done discovering the differences. So here's my first in a series of articles. (This is based on the 3.0 version of the C# language. If you want to see what's new in C#, it might be helpful to start here.)
You rarely mention types in F# code
In version 3.0, C# added the var keyword. This keyword allows you to not specify a type and instead rely on the compiler to figure out the type. This works for locals only so most types are still explicitly specified in the code. In F#, this balance is reversed. You can explicitly specify types but you're rarely required to. F# has a powerful system for deducing the types. Consider this F# function:
let Add a b = a + b
This defines a function which adds two of something to each other. So what are the types of the variables a and b? The F# compiler has chosen int because of the addition that's happening in the function. A second function:
let AddPlusOne a b = a + b + 1.1
looks similar, but now the a, b and the return of the function are types as float. In this case, the compiler decides float is the right type because we're adding constant float value.
Most of the time in F# you don't specify types. I find myself relying heavily on the tooltips in Visual Studio for type information:
I think its legitimate to be uncomfortable with this level of implicitness. Especially coming from the C++ diaspora there is a tradition of being explicit when possible. Indeed, in F# you are free to explicitly specify types everywhere if you choose.
That said, I really like C#'s type inference and have used it in production code (LINQ to SQL). It tends to make the code more readable because you spend more time looking at the algorithm and less time looking at concrete type names. I haven't shipped or maintained F# code yet, but my feeling is that more type inference is better.
This posting is provided "AS IS" with no warranties, and confers no rights.
PingBack from http://www.artofbam.com/wordpress/?p=10276
In a language designed for functional programming, implicitly-typed variables are taken into consideration in the entire design of the language.
With other languages with roots in object-oriented languages (with roots in procedural languages) some of the language design revolves around explicit typing. As such the design of these languages doesn't really "play nice" with implicitly-typed variables. In C#, for example, there is no operator to multiply an unsigned 32-bit integer with a signed 32-bit integer. Due to implicit conversions this type of operation uses the signed 64-bit integer multiplication operator. So, you can sometimes run into problems with implicitly-types variables and intrinsic types in C#. For example:
uint index = 10;
int value = -5;
var result = value * index;
Results in "Int64", not "Int32" or "UInt32". Imagine your surprise if you try to serialize "result"...
Add intrinsic-type operators with existing rules for associativity and numeric promotions you start to introduce the possibility for several types of hidden bugs when you don't explicitly tell the compiler your intentions by using "var"--bugs that would manifest as compile errors with explicitly-typed variables.
I'm sure, even with F#, there's some implicitly-typed variable "best practices" that would make for more reliable code.
Here's to hoping that F#/FP will influence C# even more :).
Peter, I find that perfectly normal, what if index was uint.MaxValue and value was -1. The only type that could store the result is a long.
Expert F# is about practical programming in a beautiful language that puts the power and elegance of