Exploring the New Sharp Academic Language F#

This article describes F# from the beginning to the professional level programming.
 

Introduction

F# (pronounced F sharp) is a mixed functional and object oriented programming language for the Microsoft .NET platform. A strength of F# is its setting within .NET. A key design aim is seamless .NET interoperability, both via direct use of .NET APIs from F# and authorship of natural .NET components in F#. Consequently, the main F# libraries are the .NET libraries themselves (e.g. DirectX, Windows Forms, and ASP.NET, as well as alternatives like Gtk# ). A Visual Studio plugin provides a graphical development environment, including features such as background type-checking with feedback under the mouse, which is extremely helpful for those unfamiliar with type inference.

F# was developed by Don Syme at Microsoft Research, and has a core language that is similar to that of the Caml (itself a member of the ML programming language family).

F# also provides a standard library of its own, designed to be largely compatible with the OCaml standard library. Since the two languages also share a common language subset, it can thus be quite practical to compile a single codebase with both. This enables core Caml code to be ported to the .NET world, and core F# code to run with OCaml. Maintaining this basic compatibility is one of the primary goals of the F#.

As of June 2006, F# was in the beta stage of development.

The Origin of F# 
· At the heart of F# lies Objective Caml, or OCaml, and the .NET language C#. 
· C#, as you probably already know, is based upon C/C++ and Java. 
· OCaml is the latest incarnation of the Caml language. 
· Caml is a dialect of ML. 

Microsoft calls it, of a functional ML(Meta Language)-like language mixed with the power of C#. 

Purpose of F# 
F# is meant to bridge the best of the functional, imperative, object-oriented and typed-classed languages.Java and C# are inherently complex. Each contains a pantheon of objects and libraries that can be used by the developer to accomplish many tasks. Anyone who has programmed in Java or C# knows that the same goal can usually be accomplished many different ways, depending on the developer. Often a complex language spawns complex solutions --and complex code can be difficult to debug, update, and pass on to new developers. Here's where F# comes to the rescue: a simple subtle language designed to solve simple, subtle problems. 

Academic Languages & Compilers

A#

A# is a port of Ada to the Microsoft .NET Platform. A# is freely distributed by the Department of Computer Science at the United States Air Force Academy as a service to the Ada community under the terms of the GNU general public license.

CALM

Caml is a strongly-typed functional programming language from the ML family. OCaml (Objective Caml) and Caml Light are two open source implementations of Caml developed at INRIA Rocquencourt, projet Cristal.

AsmL

AsmL is the Abstract State Machine Language. It is an executable specification language based on the theory of Abstract State Machines. The current version, AsmL 2 (AsmL for Microsoft .NET), is embedded into Microsoft Word and Microsoft Visual Studio.NET. It uses XML and Word for literate specifications. It is fully interoperable with other .NET languages. AsmL generates .NET assemblies which can either be executed from the command line, linked with other .NET assemblies, or packaged as COM components.
Active Oberon for .net

Active Oberon for .net is an evolution of the programming language Oberon in the context of the new Microsoft .net technology. 
Its highlights are: 
· an explicit notion of object type including "active objects" with integrated thread of control 
· a uniform concept of abstraction called definition representing both "facet" and unit of use 
· a module construct simultaneously acting as name-space and singleton object 

Dyalog APL

Dyalog APL, the leading implementation of the APL programming language, is available for PCs running Microsoft Windows (95, 98, NT, 2000, ME and XP); and for several popular UNIX systems including Linux. A new version of Dyalog APL, Pocket APL, is now available for PDAs running PocketPC 2002. 

Dyalog APL is fully compliant with the ISO 8485 standard for APL. In addition, the product has many enhancements and innovative features that make it an outstanding development tool for complex GUI applications. 
Dyalog APL was first introduced in 1983 and is in daily use in many major corporations throughout the world. Dyalog APL is constantly being developed and enhanced to meet the requirements of its users and to take full advantage of emerging technologies. 

ML 
ML(Meta Language) is a programming language originally developed at the University of Edinburgh around twenty years ago. There are now two variants: Standard ML (also known as SML), which has a formal definition most recently revised in 1997, and O'Caml, developed at INRIA in Paris.

F#
Mixed functional/imperative programming is a fantastic paradigm for many programming tasks. Languages such as OCaml and Standard ML provide excellent general purpose programming languages suited to medium-advanced programmers who want simple yet highly expressive tools that boost their productivity, primarily by reducing the error rate, increasing their productivity through type inference, and basically letting them focus on the difficult parts of their applications.

We can access hundreds of .NET libraries using F#. 

F# is an implementation of the core of the Caml programming language for the .NET Framework, along with cross-language extensions. The aim is to have it work together seamlessly with C#, Visual Basic, SML.NET and other .NET programming languages. In particular it is the first ML language where all the types and values in an ML program can be accessed from some significant languages (e.g. C#) in a predictable and friendly way.

SmallScript (S#)

The SmallScript Common Dynamic Language Runtime (CDLR) System is a rich multi-paradigm dynamic and scripting language architecture. It includes S# as its primary language, a superset/dialect of classic Smalltalk-98. Generally referred to as the "S#" language. 
The S# language implementation is a complete modular redesign of the Smalltalk language, offering transparent cross-language integration and component based deployment. Capable of supporting both repository and industry standard file-based source code management, it offers a rich array of streamlined features which enhance the Smalltalk language with features familiar to users of languages such as C, C++, Java, JavaScript, Microsoft Visual C# .NET, Visual Basic .NET, Python, PHP, and many popular scripting languages.
In contrast with a variety of other programming languages, its unique modular composition technology with multi-threaded C-like-performance of dynamic and scripting languages addresses many of today's most difficult fragility and versioning challenges that developers face when working on just-in-time integration within client and server applications. 

Design work and implementation of the SmallScript System began in 1999. Today, it offers modular deployment as a small-footprint, hi-performance, pre-emptive multi-threaded jit-based execution engine for dynamic and scripting languages.

NetCOBOL for .NET

Fujitsu NetCOBOL for .NET smoothly integrates with other languages such as Visual Basic, C#, and Eiffel. Fujitsu Software is the only COBOL vendor to deliver support for Microsoft .NET and ASP.NET, including Web Services. 
Fujitsu Software is ensuring that COBOL will be a first class language in the .NET Framework by developing all of the tools necessary to make COBOL programmers highly productive in the .NET Framework.

Python 

Python for .NET is an exploratory implementation of the Python language for the .NET Framework. The archive includes general documentation on the project itself, documentation and complete source code for the Python for .NET Research compiler. 

Mondrian

Mondrian is a functional language specifically designed to inter-operate with other languages in an OO environment. Current versions of Mondrian run on .NET, and older version for the JVM is also available. Mondrian also supports ASP.NET, allowing you to embed functional language code in web pages along with C# code.

Hotdog/Scheme 

The Hotdog compiler is a Scheme compiler under development by the Autonomous Mobile Robotics Group in the Computer Science Department of Northwestern University, in collaboration with Microsoft Corporation. The compiler was developed by Pinku Surana and Mark DePristo, under the supervision of Ian Horswill. 

The Hotdog compiler backends to the JVM, to C, and to .NET using the same runtime system. The system is designed to support many backends and easy inter-operability between Scheme and the target language.

Fortran for .NET

.NET is Microsoft's latest initiative that focuses on distributed computing and software development productivity. The infrastructure technology supporting that initiative is the .NET Framework. Within this Framework, an application written in multiple languages can share data across multiple platforms with other applications. New technologies, such as .NET Web Services and ASP.NET, and .NET programming languages, such as Microsoft C#, Visual Basic.NET, and Visual C++.NET, make all this possible. A vast set of new tools and libraries are unified to make developers, regardless of programming language, more productive than ever before. Given the enormous amount of Fortran code that exists today and customers' increased desire to connect the world, Lahey Computer Systems, Inc. and Fujitsu Limited have teamed up to integrate Lahey/Fujitsu Fortran with the Microsoft .NET Framework and Visual Studio.NET development environment. 


F# Explored

F# features:
· F# is the first ML language where all the types and values in an ML program can be accessed from some significant other languages (e.g., C#) in a predictable and friendly way. 
· F# was the first released .NET language to produce Generic IL , and the compiler was designed partly with this language in mind. The compiler can also produce (non-generic) v1.0 or v1.1 .NET binaries. 
F# supports features that are often missing from ML implementations such as Unicode strings, dynamic.

F# Vs OCaml

The table below will act as a guide to those features found in ML languages that are supported by F# : 

(Table-1)

Feature

F#

OCaml

Unicode strings and wide chars

Yes

 

Functions as values

Yes

Yes

Discriminated unions

Yes

Yes

Generics/
Type parameters

Yes

Yes

"Interior" bindings

Yes

Yes

Records

Yes

Yes

Pattern matching

Yes

Yes

Type aliases

Yes

Yes

Modules

Yes

Yes

Module Signatures

Yes

Yes

Nested Modules

Yes

Yes

Namespaces

Yes

 

Strong-named assemblies

Yes

 

Inheritance (authoring)

Yes

Yes

Object expressions

Yes

Yes

Structural subtyping constraints

 

Yes

Nominal subtyping constraints

Yes

 

Structured classes

 

Yes

Variance on type parameters

 

Yes

Labelled Arguments

 

Yes

Default parameters

 

Yes

"Printf" style formatting

Yes

Yes

Operator Overloading

Yes

 

Functors

 

Yes

The "platform" features are:

(Table-2)

Feature

F#

OCaml

Structural equality

Yes

Yes

Reference equality

Yes

Yes

Structural hashing

Yes

Yes

Polymorphic serialization/deserialization

Yes

Yes

Cross-module recursion

 

 

C Foreign Function Interface

Via C#

Yes

COM interopability

Via tlbimp.exe

Via camlidl

.NET interopability

Yes

 

 

 F# for developers:
· The interactive environment fsi.exe supports top-level development and exploration of the dynamics of your code and environment. 
· The command line compiler fsc.exe supports separate compilation, debug information and optimization. 
· F# comes with F# for Visual Studio, an extension to Visual Studio 2003 and Visual Studio 2005 that supports features such as an integrated build/debug environment, graphical debugging, interactive syntax highlighting, parsing and typechecking, IntelliSense, CodeSense, MethodTips and a simple project system. 
· F# can be used with tools from the .NET Framework, Microsoft's Visual Studio and many other .NET development tools. 
· F# comes with an ML compatibility library that approximates and extends some of the OCaml 3.06 libraries. This means you don't have to use ·NET libraries if it is not appropriate. It is possible to write large and sophisticated applications that can be cross-compiled as OCaml code or F# code. 

Requirements to Use F# 

There are following requirements for running the F# compiler: 

In order to compile F# on your computer, you'll need to have one of the following installed: 
· VisualStudio.NET (MSDN) (http://msdn.microsoft.com)
· The Microsoft .NET Framework SDK (MSDN/Net) (http://msdn.microsoft.com/net)
· An installation of the Microsoft .NET Framework SDK Redistributable (MSDN/Net). The "redist" is a trimmed-down set of binaries containing just what is needed to run programs, but also contains the IL assembler needed by the F# compiler. 
The runtime requirements for F# are as follows: 
· You will need to have one of the above installed on your system in order to run F# programs. 
· You will also need to have the F# libraries installed in the Global Assembly Cache or copied to your application directory. This is done when you install the F# compiler on your computer. 

You can get more information by checking out the F# site hosted off Microsoft Research. 

You can download the preview version of the F# compiler (http://research.microsoft.com/research/downloads/) from Microsoft Research . 


To use F# effectively you need to learn:

1. How to use the F# compiler FSC, F# Interactive FSI and/or Visual StudioPlugin . 
2. How to write F# functional programs 
3. How to write F# imperative programs 
4. How to use .NET APIs from F# 
5. The details of the specific F# and .NET libraries you would like to use 

Creating and Executing a simple F# program


Here is a simple F# console-based program:
let s = "SKP First F# Program";;
System.Console.WriteLine(x);;
Save the above code in a text file as skp1.fs ( the file can also be saved with extension .ml ) then this program can be compiled from the command line as follows:

> fsc skp1.fs

and executed using 

> skp1.exe

F# Basic Data Types 

F# has a number of litterals built-in; the most basic of these these are string, bool, int, float and char, which are summerised in the table below. These types are based on types in the .NET framework. In F# there is generally no need to declare what type you are using; the compiler can work this out for you. It is possible to explicitly give a label a type by using a colon (:) and then the type name, but this is usually unnecessary.

(Table-3: Summary of F# basic types)

F# type

Example F# Literal Declaration

.NET Framework type

string

"My string"

System.String

int

9

System.Int32

float

3.14

System.Single

char

'a'

System.Char

bool

true

System.Boolean



F# has a number of functions for outputting different types of data to the console. There is no implicit casting in F#, but there are built-in functions to convert most of the basic types to other basic types, so a programmer could convert a non-string type to a string and use the .NET framework methods to output it. A programmer has a number of choices about how to output data to the console. The listing below demonstrates a number of them.

open System

let str = "Test"
let character = 'a'
let boolean = true
let integer = 12
let floatingPoint = 1.01

let _ =
     Console.WriteLine ("Testing conversion to string then output via .NET console ...");
     Console.WriteLine ("string: " ^ str);
     (*
     Note: F# doesn't have a string_of_char method, but you can
     use String.make to have a similar effect.
     *)
     Console.WriteLine ("char: " ^ (String.make 1 character));
     Console.WriteLine ("bool: " ^ string_of_bool(boolean));
     Console.WriteLine ("int: " ^ string_of_int(integer));
     Console.WriteLine ("float: " ^ string_of_float(floatingPoint));
     print_endline "Testing output though native functions ...";
     print_string "string: "; print_string str;
     print_newline();
     print_string "char: "; print_char character;
     print_newline();
     print_string "bool: "; print_any boolean      print_newline();
     print_string "int: "; print_int integer;
     print_newline();
     print_string "float: "; print_float floatingPoint;
     print_newline();

The other thing to note from this listing is use of the keyword "open". An F# programmer can use the keyword open in much the same way a C# programmer uses the keyword “using”, it’s a shortcut to avoid having to qualify classes with namespaces.

Core Language Syntax Examples 

Integers

let i1 = 12
let i2 = 23 + 23
let i3 = 0x80d099FE


let a1 = 0x00FE &&& 0x1211 // and
let a2 = 0x00FE ||| 0x1211 // or
let a3 = 0x00FE ^^^ 0x1211 // xor
let a4 = ~~~ a3 // not
let a5 = 0x1234 <<< 3 // left shift
let a6 = 0x1234 >>> 2 // right shift


do printf "%08x %08x %08x\n" a1 a2 a3
do printf "%08x %08x %08x\n" a4 a5 a6


Floats (double-precision = System.Double)

Compatability note:
· In CAML, you use *. +. -. /. for floating point operators (no overloading). 
· In F# the basic arithmetic operators are overloaded, so dots not necessary. 
· To support cross compiling with OCAML, F# also provides the dotted-ops. 

let r1 = 2.0 * 3.1415 + 1.0
let r2 = float 123
do printf "%f %f\n" r1 r2


let r1_caml = 2.0 *. 3.1415 +. 1.0

Strings ( = System.String)

let strA = "SySt3M H4Ck4Rz"
let strB = "SK Pandey"


// MLLib.String functions:
let lenA = String.length strA // length 
let strC = strA ^ " out fox " ^ strB // concatenation
let strD = String.sub strA 7 7 // substring


// System.String static/instance methods
let lenD = strD.Length // property
let strE = strD.ToUpper() // instance method


Tuples

let tupA = 1,false
let tupB = 1,true,"three"

let fst (a,b) = a
let snd (a,b) = b

let rw1'2 f (a,b) = f a,b
let rw2'2 f (a,b) = a,f b

let tupA2 = rw2'2 not tupA

Arrays 

F# has generic (polymorphic) arrays. In .NET 2.0, there is a generic array type . F# arrays are .NET arrays.

let arrA = [| 0;2;4;6;8 |] // array expressions
let arrB = Array.init 5 (fun i -> i*2) // initialisation calls
let arrC = Array.append [|0;2;4|] [|6;8|] // append


// MLLib.Array.* functions are ML-like functions
let lenArrA = Array.length arrA
let eltArrA = arrA.(0)
let sumArr arr = Array.fold_left (fun sum n -> sum + n) 0 arr


// .NET instance/static members usable
// Note, use of instance members require the type to be known.
let sumArr2 (arr : 'a array) =
let mutable sum = 0 in
for i = 0 to arr.Length - 1 do
sum <- sum + arr.(i)
done;
sum


// Array type can be written in ML or .NET style
let arrX = [| "Alpha"; "Beta" |] : string array
let arrY = [| "Alpha"; "Beta" |] : string[]

Instance methods

Augmenting types with dot-notation property members is common in F#, even for types that are discriminated unions or records, or for abstract types that don't reveal anything else about the implementation.

type Data = 
{ first: string;
second: string; }
with 
member x.First = x.first
member x.Second = x.second
member x.Together = x.first + x.second
end

Static methods

Augmenting non-class and abstract types with static property members is a little less common, but here's an example that represents a common idiom:

type Data = 
{ first: string;
second: string; }
with 
static member Defaults = { first = "1st"; second = "2nd" }
end
let x = Data.Defaults
let y = { Data.Defaults with first = "First" }

Or for an enum-like data structure:

type Flags= Flags of int32
with 
static member LowMask = 0x00000003
static member HighMask = 0xFFFFFFFD
static member A = Flags 0x00000001
static member B = Flags 0x00000002
static member C = Flags 0x00000003
end

let x = Flags.A 
let y = Flags.B

Operator overloading

Instances of operator overloads may be defined on abstract data types using augmentations:

type BigInt 
with 
static member ( + )(n1,n2) = RawBigIntOps.add n1 n2
static member ( * )(n1,n2) = RawBigIntOps.mul n1 n2
static member ( - )(n1,n2) = RawBigIntOps.sub n1 n2 
static member ( / )(n1,n2) = RawBigIntOps.div n1 n2
static member ( ~- )(n1) = RawBigIntOps.neg n1
static member ( ~+ )(n1:BigInt) = n1
end

Here's another example:

type Flags= Flags of int32
with 
static member (+) ((x:Flags),(y:Flags)) =
match x,y with Flags xbits,Flags ybits -> Flags(xbits ||| ybits)
end

let x = Flags.A + Flags.B

Inheritance
1. abstract members 
2. default members 
3. override members 

type seq =
class
abstract step : unit -> unit
abstract x : int
abstract Text : string
default s.Text = s.x.ToString() ^ "..."
new() = {}
end


type natseq =
class
inherit seq as base
val mutable start : int
new(n) = {inherit seq(); start=n}
new() = {inherit seq(); start=0} 
override ns.step() = ns.start <- ns.start + 1
override ns.x = ns.start
end

let ns = new natseq()

Ex:Finding the maximal value in a list of integers coded "F# style"

open List
open Printf

let data = [1; 2; 3; 3; 4; 5]
let rec max_of_list plist =
match plist with
| [] -> failwith "empty list" // empty list: fail
| [x] -> x // single element list: return the element
| x::tail -> max x (max_of_list tail) // multiple element list: recursive case

do printf "result = %d\n" (max_of_list data)

A Simple GUI Application in F#

(* lets us conveniently construct colours from RGB triples *)
let color r g b =
System.Windows.Media.Color.FromRgb(Byte.of_int r, Byte.of_int g, Byte.of_int b)


(* a couple of colours *)
let red = color 204 0 0
let black = color 0 0 0


(*SKP Application's OnStartingUp event builds its main
window *)
let on_starting_up (event_args: System.Windows.StartingUpCancelEventArgs) =
(* create a window *)
let win = new System.Windows.Window() in
win.Text <- "Hello, SKP-F# World!";


(* create a label *)
let text = new System.Windows.Controls.TextBlock() in
text.TextContent <- "Hello,\nSKP-F# world!";
text.FontFamily <- "Lucida Sans";
text.FontSize <- System.Windows.FontSize.FromInches(0.8);
text.TextAlignment <- System.Windows.TextAlignment.Center;
text.VerticalAlignment <- System.Windows.VerticalAlignment.Center;


(* this is SKP, so need to do something vaguely pretty;
here I'm adding a cool gradient to the label's text *)
let brush = new System.Windows.Media.LinearGradientBrush() in
brush.StartPoint <- new System.Windows.Point(0.0, 0.0);
brush.EndPoint <- new System.Windows.Point(0.0, 1.0);
brush.AddStop(red, 0.0);
brush.AddStop(black, 1.0);
text.Foreground <- (brush :> System.Windows.Media.Brush);


(* add the label to the window *)
win.Content <- (text :> obj);


(* show the main window *)
win.Show()


let _ =
(* create and run SKP application *)
let app =
{ new System.Windows.Application() as base with
OnStartingUp(event_args) =
base.OnStartingUp(event_args);
on_starting_up event_args } in
app.Run()

Charting in F# 

#r @"XYGraph.dll";;
open System
open System.Drawing
open System.Collections
open System.ComponentModel
open System.Windows.Forms
open System.Data
open System.Drawing.Drawing2D
open componentXtra
open System.Console
let graph my_data = 
let f = new Form() in 
f.Width <- 400;
f.Height <- 300;
let xyGraph1 = new componentXtra.XYGraph() in 
f.Controls.Add(xyGraph1);
f.Controls.Add(xyGraph1);
xyGraph1.BackColor <- Color.White;
xyGraph1.Dock <- DockStyle.Fill;
xyGraph1.ForeColor <- SystemColors.ActiveCaption;
xyGraph1.XtraLabelX <- "X";
xyGraph1.XtraLabelY <- "Y";
xyGraph1.Location <- new Point(0, 0);
xyGraph1.Name <- "xyGraph1";
xyGraph1.XtraShowGrid <- true;
xyGraph1.XtraShowLegend <- true;
xyGraph1.Size <- new System.Drawing.Size(720, 502);
xyGraph1.TabIndex <- 0;
xyGraph1.XtraTitle <- "My Chart"; 
xyGraph1.Width <- 400;
xyGraph1.Height <- 300;
xyGraph1.Visible<- true;
xyGraph1.AddGraph("my_data", DashStyle.Solid, Color.Red,1,false);
Array.iteri (fun i x -> xyGraph1.AddValue(0,Float32.of_int i, x)) 
(Array.map Float32.of_float my_data) in
xyGraph1.Invalidate();
f.ShowDialog()

F # OleDb 

open System
open System.Data
open System.Data.OleDb
open System.Console


let connstr = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=D:\\usr\\my_db.mdb;UserId=admin;Password=;"
let dbconn = new OleDbConnection(connstr);; 
do dbconn.Open() 
let sql_command= new OleDbCommand("select perf from perfs where id = 1",dbconn)
let sql_stream : Collections.Generic.IEnumerable<System.Data.Common.DbDataRecord> =
sql_command.ExecuteReader(CommandBehavior.CloseConnection) |> IEnumerable.untyped_to_typed ;;
let sql_output = sql_stream |> IEnumerable.map (fun x -> x.GetDouble 0 )
|> IEnumerable.to_array;;
print_any sql_output;

Conclusion

With the simplicity of ML, and the power of .NET, Microsoft could have a winning language for .NET developers. In this article we tried to explore most of the hidden fact inside F# .Microsoft web site can be visited for more detail information about F# because it under research and development with Microsoft .Please send your comments and suggestions at : skphind@yahoo.co.uk.

Web Links & Downloads 

· Download the Preview version of the F# compiler from Microsoft Research 
http://research.microsoft.com/research/downloads/
· www.microsoft.com
· http://msdn.microsoft.com
· http://msdn.microsoft.com/net

About the Authors

1. Sunil Kr.Pandey
Asst. Professor
Department of Computer Science,
School of Management Sciences(SMS),
Varanasi(UP)
India.
E-mail:skphind@rediffmail.com
2. R.B.Mishra
Reader
Department of Computer Engineering 
Institute of Technology(IT),
Banaras Hindu University(BHU),
Varanasi(UP)
India



Added on July 21, 2007 Comment

Comments

Post a comment