Showing posts with label F#. Show all posts
Showing posts with label F#. Show all posts

Friday, May 14, 2010

F#: Piping and Composition

Piping and compositions are very expressive tools in F#. It significantly improves code readability.

Let’s have the following functions:

> let square x = x*x;;
val square : int -> int

> let negate x = -x;;
val negate : int –> int

Function square returns the square of x, while negate returns the negated value of x.

We can calculate square(negate(10)) as follows:

> let x = negate 10;;
val x : int = –10

> let x = square x;;
val x : int = 100

Or a simpler way:

> let x = square (negate 10);;
val x : int = 100

Piping

We can define piping as symbol-named function definition that simply applies two functions in reverse order:

let (|>) f x =
  x f

The example with piping:

> 10 |> negate |> square;;
val it : int = 100

That means ((10 negate) square) –> (square (negate 10)). I used an integer (10) as f.

Composition

Composition is a reverse-order function composition:

let (>>) f g x =
  g(f x)

The example with composition:

> (negate >> square) 10;;
val it : int = 100

That means ((negate square) 10) –> (square (negate 10)).

Usage

The examples above are very simple ones. The real benefits of piping and composition reveal in case of function definitions and usage.

Pipes can reverse parameter definition orders (like in 10 |> negate) and can help type inferring. When F# infers types, it evaluates from upper left corner to lover right corner of the text file, so sometimes it doesn't know the type of a function parameter. Pipe brings parameters forward.

Composition can help omitting function parameter declaration. If the first function expects a parameter, the composed function expects it’s parameter. 

Monday, March 16, 2009

UML Object Constraint Language

I’m using Object Constraint Language (OCL) for a small MDA project. OCL is a constraint language for UML and part of the standard. I have a small experience in F# and OCL reminds me to functional languages.

Wikipedia definition for OCL:

The Object Constraint Language (OCL) is a declarative language for describing rules that apply to Unified Modeling Language (UML) models developed at IBM and now part of the UML standard. Initially, OCL was only a formal specification language extension to UML. OCL may now be used with any Meta-Object Facility (MOF) Object Management Group (OMG) meta-model, including UML. The Object Constraint Language is a precise text language that provides constraint and object query expressions on any MOF model or meta-model that cannot otherwise be expressed by diagrammatic notation. OCL is a key component of the new OMG standard recommendation for transforming models, the Queries/Views/Transformations (QVT) specification.

So OCL is a declarative language. And functional languages are subsets of these. Here is a typical OCL expression:

Team.allInstances()->forAll( t | t.name = ‘teamname’)

It reminds me a lambda expression. t | t.name in F# is something like t –> t.name.

Now I’m sure it worths learning new paradigms like functional programming. You never know what kind of language (element) you have to use in the future.

Sunday, February 8, 2009

F# - Exceptions

#light

/// Standard exception and rethrow
try
    1/0
with
    | :? System.DivideByZeroException as exc ->
            printfn "1/0: %s" exc.Message
            1
    | _ -> rethrow()
            
    
/// Raise exception            
try
    raise (new System.Exception("Generic error"))
with
    | _ as exc -> printfn "Error: %s" exc.Message
    
/// F# exception
try
    failwith "F# error"
with
    | _ as exc -> 
        printfn "Error: %s" exc.Message
        printfn "Exception type: %O" (exc.GetType())

/// Finally
try
    failwith "Finally test"
finally
    printfn ">>Finally"
1/0: Attempted to divide by zero.
Error: Generic error
Error: F# error
Exception type: Microsoft.FSharp.Core.FailureException

Unhandled Exception: Microsoft.FSharp.Core.FailureException: Finally test
   at Microsoft.FSharp.Core.Operators.failwith[T](String message)
   at <StartupCode$Tupples>.$Program._main() in C:\Users\XXXXX\Documents\Visual
Studio 2008\Projects\XXXXX\Program.fs:line 29
>>Finally

Standard .NET exceptions can be handled by try … with expression. | is a pattern matching. :? is a type test, here against System.DivideByZeroException .NET exception.  as exc means exc is a variable that stores the exception (just like in C#). rethrow() rethrows the exception, like throw() in C#.

raise can raise an exception. | _ means pattern matching for any kind of exception.

F# exception can also be thrown. F# uses Microsoft.FSharp.Core.FailureException as its base exception type.

There is a finally block as well, just like in C#, to execute code after try block independently from try block results. Unfortunately with and finally can’t be combined.

F# – Control Flow

There are 3 main loop types in F# for imperative programming style:

  • Iteration
    for id = … to … do
  • Sequence loop
    for … in expression do
  • Pre-test loop
    while … do

This is an example code for each loops:

#light

/// Iteration
printfn "for to do"
printf "["
for i=1 to 5 do
    printf "%d " i
printf "]"

/// Sequence loop
printfn ""
printfn ""
printfn "for in do"
let items = seq{1..5}
printf "["
for i in items do
    printf "%d " i
printf "]"

/// Pre-test loop
printfn ""
printfn ""
printfn "while do"
printf "["
let mutable i = 1
while i<=5 do 
    printf "%d " i
    i <- i+1
printf "]"
for to do
[1 2 3 4 5 ]

for in do
[1 2 3 4 5 ]

while do
[1 2 3 4 5 ]

All the loop types can be found in C#.

seq{1..5} is a sequence data type that means:

val it : seq<int> = seq [1; 2; 3; 4; ...]

So we can say it contains 1,2,3,4,5.

The

let mutable i = 1

line means variable i can change its value. So i <- i+1 means assignment and can be evaluated.

F# – Functional Composition

I have created an example code in a previous blog entry to demonstrate the piping capabilities of F#:

let replace from tos list =
    List.map (fun item -> 
                if item = from then tos
                else item )
             list
        
let count list =
    List.length list
    
let printList list =
    List.iter (fun item -> printfn "[%s]" item) list
    
let abc = ["a";"b";"c"]
abc |> printList

abc |> replace "a" "k" |> count |> printfn "Number of items: %d"
abc |> replace "a" "k" |> printList
[a]
[b]
[c]
Number of items: 3
[k]
[b]
[c]

This is a form of code we got used to in C-like languages: we have a function and we have arguments. What can we do if we don’t want to specify the arguments for a function? We can use functional composition.

let count =
    List.length

let replace from tos =
    List.map (fun item ->
                if item = from then tos
                else item)

let printList =
       List.iter (fun item -> printfn "[%s]" item)
       

let abc = ["a";"b";"c"]
abc |> printList

let nrOfItems =
    replace "a" "k"
    >> count
    >> printfn "Number of items: %d"
    
let printReplace =
    replace "a" "k"
    >> printList

abc |> nrOfItems
abc |> printReplace
[a]
[b]
[c]
Number of items: 3
[k]
[b]
[c]

You can omit the parameter of the function and you can specify that at calling time. Code is more readable, maintainable.

The operator specification for functional composition (>>) is:

let (>>) f g x = g(f(x))

The operator specification for pipeline (|>) is:

let (|>) x f = f x

Wednesday, February 4, 2009

F# – Pipeline

One of the unique functional elements of F# is piping. Piping means

let (|>) x f = f x

So a |> b means b a. It’s a reverse application function. Let’s see an example:

#light

let replace from tos list =
    List.map (fun item -> 
                if item = from then tos
                else item )
             list
        
let count list =
    List.length list
    
let printList list =
    List.iter (fun item -> printfn "[%s]" item) list
    
let abc = ["a";"b";"c"]
abc |> printList

abc |> replace "a" "k" |> count |> printfn "Number of items: %d"
abc |> replace "a" "k" |> printList
[a]
[b]
[c]
Number of items: 3
[k]
[b]
[c]

replace function changes list elements from to tos(tring). count function counts the number of list elements. printList prints the elements of the list.

Piping can be used to chain the results of the functions after each other. It’s very similar to the piping pattern employed on Unix/Linux systems.

F# – Visual Studio Integration

The newer versions of F# support Visual Studio better and better, but don’t wait such feature rich designer support as C# and other mainstream languages have. In fact F# doesn’t have any designer support (yet?).

F# integrates with Visual Studio, so first of all you can create an F# project from File/New/Project… Select Visual F# node. There are three project types:

Project Description
F# Application It creates a project that compiles to .NET .exe. It can be run from command prompt.
F# Library It creates a project that compiles to .NET .dll. It can be referenced from other .NET applications.
F# Tutorial It creates a project containing examples of F# language constructs.

So application template compiles to a standalone application, library templates compiles to a .NET DLL, and tutorial template contains several examples. Library template contains a Script.sfx file. This file can be directly accessed from F# Interactive and loads the DLL so it can be tested in an interactive manner.

F# Interactive is the interactive environment of F#. It’s reminds me to qBasic: expressions are evaluated as you type and close them. It’s basically an interpreter. F# Interactive can be accessed either from command prompt (called fsi.exe) or from Visual Studio. You can display it clicking on View/Other Windows/F# Interactive (CTRL+ALT+F). I prefer it full (editor) screen, so I usually drag it up to the editor area (e.g. over the editor window).
Expressions must be closed with ;; operator in F# Interactive.

Tuesday, February 3, 2009

F# - Immutability

Many F# data structures are immutable. Immutable means data can't be modified. It is one of the main ideas of functional programming. Let’s look at the following code:

#light
let text = "Hello F#"
printf "4th character: %c" text.[3]
4th character: l

Dynamic data modification can be done by using the <- operator. Let’s try to modify the 4th character of the string.

> a.[3] <- 'r';;

  a.[3] <- 'r';;
  ^^^^^^^^^^^^^

stdin(8,1): error FS0191: invalid indexer expression.

It means that a character of a string cannot be modified because a string is an immutable type. There are no background mechanism, to cover string immutability, similar to C#.

Array is also an immutable type. Here is an example:

let enumFruits fruitList =
    List.iter (fun element -> printf "[%s] " element) fruitList
    printfn ""

let fruits = ["Apple"; "Banana"; "Cherry"]
printf "Fruits: "
enumFruits fruits

"Nut"::fruits
printf "Fruits: "
enumFruits fruits

let extFruits = "Nut"::fruits
printf "extFruits: "
enumFruits extFruits
Fruits: [Apple] [Banana] [Cherry]
Fruits: [Apple] [Banana] [Cherry]
extFruits: [Nut] [Apple] [Banana] [Cherry]

enumFruits is a function to enumerate the items of the fruit list.

The fruits array initially contains 3 elements: Apple, Banana, Cherry. The :: operator attaches an element called Nut to the head of the array. Inspecting the elements of fruits reveals that nothing has changed, fruits contains the same 3 elements. Array is immutable. extFruits is just for showing that :: operator really works.

Monday, February 2, 2009

F# – User Interface

F# can access .NET assemblies, so Windows Forms is the UI library for F#. The following code reads microsoft.com and displays the HTML code in a TextBox.

#light
open System.Windows.Forms
open System.IO
open System.Net

let form = new Form(Visible=false,Text="Hello F#")

let result = new TextBox(Multiline=true,Dock=DockStyle.Fill, Text="")
form.Controls.Add(result)

let getHtml (url: string) =
    let req = System.Net.WebRequest.Create(url)
    let resp = req.GetResponse()
    printfn "Connected"
    let stream = resp.GetResponseStream()
    let reader = new StreamReader(stream)
    let html = reader.ReadToEnd()
    printfn "Response read"
    resp.Close()
    html
    
printfn "Connecting..."
let microsoft = getHtml("http://www.microsoft.com")
result.Text <- microsoft

form.Visible <- true
Application.Run(form)
Connecting...
Connected
Response read

As you can see, Windows Forms knowledge is a requirement for F# UI development. Personally I don’t think UI elements should be developed in F#, C# has much better IDE designer support so far (F# don’t have designers).

F# – Sequential code

F# can handle sequential code. Expressions evaluated sequentially. Just the last result will be kept, other results will be dismissed to prevent side effects.

#light
let a = (2+3;5+7;4+4)
printfn "a= %d" a
let b = (a+2;a+5)
printfn "b= %d" b
a= 8
b= 13

It can be useful when we are doing complicated computations or initializations and we want to indicate the progress:

printf "Processing"
let c = (printf ".."; 2; printfn ".."; 3)
printfn "c= %d" c
Processing....
c= 3

F# – Typed tuples

F# is a typed language. I create 2 tuples containing site URLs and relevancies. I create a tuple from the tuples above. I execute a pattern matching on site1 tuple, splitting it up to a string and an integer variables. Finally I print the content of the url and relevance variable to the console.

#light
let site1 = ("www.microsoft.com",10)
let site2 = ("www.bbc.com",9)
let sites = (site1, site2)
let url,relevance = site1

printfn "site: %s" url
printfn "relevance: %d" relevance
site: www.microsoft.com
relevance: 10

Let’s test type safety:

let url = url +2

> let url = url + 2;;

  let url = url + 2;;
  ----------------^^

stdin(34,17): error FS0001: The type 'int' does not match the type 'string'.
>

This error message means that integer cannot be converted to string.

Tuples can be used effectively in functions:

let increase (a,b) =
    (a+1,b+1)

let printIncreased (a,b) =
    let (a,b) = increase (a,b)
    printfn "a: %d" a
    printfn "b: %d" b
    
printIncreased (5,6)
a: 6
b: 7

Finally a tuple with 4 elements:

let quad = ("Doe", "John", 23, "New York")
let last,first,age,location = quad
System.Console.WriteLine("Last name: {0}\nFirst name: {1}\nAge: {2}\nLocation: {3}", last, first, age, location)
Last name: Doe
First name: John
Age: 23
Location: New York

Sunday, February 1, 2009

F# - Hello World

A simple Hello World code in F#:

#light
let HelloWorld =
    printfn "Hello World"

HelloWorld

It is the IL code for the F# code above:

Code to execute in IL:

  1: .class private abstract auto ansi sealed beforefieldinit $Program
  2:     extends [mscorlib]System.Object
  3: {
  4:     .method public static void _main() cil managed
  5:     {
  6:         .entrypoint
  7:         .maxstack 3
  8:         L_0000: nop 
  9:         L_0001: ldstr "Hello World"
 10:         L_0006: newobj instance void [FSharp.Core]Microsoft.FSharp.Text.Format`5<class [FSharp.Core]Microsoft.FSharp.Core.Unit, class [mscorlib]System.IO.TextWriter, class [FSharp.Core]Microsoft.FSharp.Core.Unit, class [FSharp.Core]Microsoft.FSharp.Core.Unit, class [FSharp.Core]Microsoft.FSharp.Core.Unit>::.ctor(string)
 11:         L_000b: call !!0 [FSharp.Core]Microsoft.FSharp.Core.Pervasives::printfn<class [FSharp.Core]Microsoft.FSharp.Core.Unit>(class [FSharp.Core]Microsoft.FSharp.Text.Format`4<!!0, class [mscorlib]System.IO.TextWriter, class [FSharp.Core]Microsoft.FSharp.Core.Unit, class [FSharp.Core]Microsoft.FSharp.Core.Unit>)
 12:         L_0010: stsfld class [FSharp.Core]Microsoft.FSharp.Core.Unit <StartupCode$ConsoleApplication1>.$Program::HelloWorld@19
 13:         L_0015: call class [FSharp.Core]Microsoft.FSharp.Core.Unit Program::get_HelloWorld()
 14:         L_001a: pop 
 15:         L_001b: ret 
 16:     }
 17: 
 18: 
 19:     .field assembly static class [FSharp.Core]Microsoft.FSharp.Core.Unit HelloWorld@19
 20: 
 21: }
 22: 
 23: 

The same code in C#:

  1: internal static class $Program
  2: {
  3:     // Fields
  4:     internal static Unit HelloWorld@19;
  5: 
  6:     // Methods
  7:     public static void _main()
  8:     {
  9:         HelloWorld@19 = Pervasives.printfn<Unit>(new Format<Unit, TextWriter, Unit, Unit, Unit>("Hello World"));
 10:         Program.get_HelloWorld();
 11:     }
 12: }
 13: 
 14: 

Something similar in C#:

  1: class Program
  2: {
  3:     static void Main(string[] args)
  4:     {
  5:         Console.WriteLine("Hello World");
  6:     }
  7: }

It is the IL code for the C# code above:

  1: .class private auto ansi beforefieldinit Program
  2:     extends [mscorlib]System.Object
  3: {
  4:     .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
  5:     {
  6:         .maxstack 8
  7:         L_0000: ldarg.0 
  8:         L_0001: call instance void [mscorlib]System.Object::.ctor()
  9:         L_0006: ret 
 10:     }
 11: 
 12:     .method private hidebysig static void Main(string[] args) cil managed
 13:     {
 14:         .entrypoint
 15:         .maxstack 8
 16:         L_0000: nop 
 17:         L_0001: ldstr "Hello World"
 18:         L_0006: call void [mscorlib]System.Console::WriteLine(string)
 19:         L_000b: nop 
 20:         L_000c: ret 
 21:     }
 22: 
 23: }
 24: 
 25: