Experimental 'Functional' Language Emerges from Microsoft Research
Are the C programming language and its object-oriented offspring - C++, C#, Objective-C - still well-suited to the requirements of multithreaded, network-oriented computing environments today? That's the question on the minds of engineers at Microsoft Research, whose latest programming language is today being officially moved off the back burner. The F# language has received the company's official blessing.
"I am a big fan of technology transfer between a research organization and a product development organization so that we can 'productize' the great research ideas and deliver to customers in a timely manner," pronounced Microsoft corporate vice president for the Developer Division, S. Somasegar, in a blog post last Wednesday. "This is one of the best things that has happened at Microsoft ever since we created Microsoft Research over 15 years ago. Here is another great example of technology transfer at work."
There is no "F" language - F# is a fairly new concept from the ground up. It's designed for the .NET Framework, so it can integrate directly into Windows and also so it can share a workspace in Visual Studio.
The language itself is based on a long-forgotten premise, one that had not only been discarded but literally kicked aside at the onset of object-oriented programming in the early 1980s: Every instruction is a mathematical expression. Its syntax is adapted to work somewhat like a more conventional lexicon, but the F# interpreter is built to reduce everything it processes to a fundamental value.
Because of this, F# is extremely different from IronPython or IronRuby, two of the so-called dynamically typed languages built for .NET's new Dynamic Language Runtime. For that matter, it's on the other side of the planet from PowerShell, which is a very dynamic and flexible language best suited for scripting everyday Windows tasks.
Instead, F# takes several steps back in language evolution, looking away from objects and de-emphasizing code modularization. It even brings back the old let statement first introduced to programming by Profs. Kemeny and Kurtz, the creators of BASIC and the men who first brought ALGOL-based procedural languages into the reach of ordinary human beings.
Having backtracked all that long way, F# finds itself the derivative of an old University of Edinburgh project called Standard ML. Like BASIC, it's a mathematical language, but it's more strictly structured. Mathematicians call this concept "functional language," though Microsoft has already misused that phrase in its explanation, as though it meant "capable of doing stuff." No, it means that every F# program defines a mathematical function that has any number of inputs and at least one discrete output. Thus, it is essentially what some of the first programming languages used to be.
This makes F# phraseology very different from what many Windows programmers have become accustomed to. Here's a fragment of an example from the most current F# distribution, that sets up and displays one of the common forms in a Windows form library:
let mnuiOpen =
new EventHandler(fun _ _ ->
let d = new OpenFileDialog() in
d.InitialDirectory <- "c:\\";
d.Filter <- "txt files (*.txt)|*.txt|All files (*.*)|*.*";
d.FilterIndex <- 2;
d.RestoreDirectory <- true;
if d.ShowDialog() = DialogResult.OK then
match d.OpenFile() with
| null -> printf "Ooops... Could not read the file...\n"
| s ->
let r = new StreamReader(s) in
printf "The first line of the file is: %s!\n" (r.ReadLine());
In a typical procedural language, you'd declare a set of variables for holding the contents of the parameters for this Open dialog box. You'd load those variables with default values, then you might pass the method for opening the box, and then invoke a new variable for trapping the user's response to that box.
But in F#, you express a dialog box the way you'd express a function. So you don't "declare" anything right up front; instead, you say there's a statically typed value (here called mnuiOpen) that represents the user's response. You state that first, not last. The parameters of the built-in MenuItem() function are themselves comprised of multiple instructions, because remember, all instructions in F# reduce to expressions, which have static values. The second parameter of that function is an event handler, which draws its result from the value of variable d.
Now, this is important, because d hasn't done anything yet. With a typical procedural language, you'd solve for d and then pass it along as a parameter. Here, you introduce d by way of explaining what d does, which is what makes this language functional rather than purely procedural.
As with internationally recognized mathematics, you introduce the symbol and then you explain it. Note all these components of d, which here take on the structure of the .NET OpenFileDialog() function. All these things are explained by way of introducing them as functionally intrinsic to the result.
After a whole lot of historical backtracking, F# takes several steps forward in a different direction, as though programming evolution all this time weren't driven by the search for objects or some kind of underlying, all-inclusive philosophy there, but by mathematics. F# is a statically typed language at its heart, which means it has something very much in common with C after all.
That direction is multithreading, which is something the Standard ML creators never considered. F# embraces a concept called asynchronous workflows, in which a thread is considered a workflow (not like a Microsoft Workflow Foundation concept) whose result is, like every other F# instruction, a discrete value. You create the thread by encapsulating it as a workflow whose result is represented by the static variable.
But the way that these workflows are cast, they are not immediately executed the way they would normally be in F#. Instead, they are cast as arguments to the method Async.Run, which triggers separate threads for them but does not await the result.
Asynchronous workflow is extremely important for F#, because now it has a way of forking off its functionality to Web services - which all take place asynchronously, and which aren't always reliable - without having to pause like a ping utility awaiting either a response or a timeout. It also gives F# an indirect, though solid, connection to all the other functionality on local and global networks alike, that are not written in F#, and should not have to be "interfaced" like in Microsoft's rapidly-more-ancient concept of DCOM.
"The somewhat mathematical slant of functional programming just seems naturally appealing to professionals whose primary domain is described with mathematical notation - domains such as financial, scientific and technical computing," Somasegar continued. "On top of the syntactic appeal, the strong type system yields the sort of guarantees which are often crucial in these domains, and enables a superb tooling experience through Visual Studio."
The F# compiler for .NET is available from this page. The interactive command line tool does not require Visual Studio, though the installer package does include VS extensions.