Jul 5, 2011

f# essential - part 7 Curry

Function application, also sometimes referred to as function composition or composing functions is a big thing in functional programming. One style of composition is called Curry. Curry is feature of lots functional language. When you have a function with two parameter, you can pass one argument to the function, that create an new partial function, which accept one parameter. This partial function is also called curried function. F# support this in a very elegant syntax.

let print x y = 
     printfn "%i" x 
     printfn "%s" y 
let print100y = print 100 //create a curried function 
print100y "hello" //call the curried function 

If you want to fill in the second argument to create a new function, this is also support, like below.

let printx_hello x = dosomething x "hello" 
printx_hello 100

Jul 4, 2011

f# essential - part 6 - tuple

In other language, a method can not return more than one parameter. There are two way to get around this, use passed-by-reference parameter, or use composite type to encapsulate two or more fields in to one object. Both of them are not elegant. However, f# can express this using a very simple syntax to solve this problem, "tuple", which is a strongly typed structure. Here is an example.

let (x, y, z) = (1, 2, 3)
//or
let x, y, z = 1, 2, 3

f# essential - part 5 - mutable, ref

As mentioned in previous post, the "let" syntax define a identifier binding, which is immutable. So it is not variable in the sense of traditional programming. But we can not programming in pure functional language environment. We need to create state, and side effect. F# is pragmatic and play nice with .net framework, so it has to be support variable. To use variable, you just need to add a "mutable" in front identifier, then the identifier became variable in the sense of traditional programming.

let totalArray2 () =
    let array = [|1; 2; 3|]
    let mutable total = 0
    
    for x in array do
        total <- total + x

    printfn "total: %i" total

totalArray2()

However, mutable does not support closure. So if you write the following code, you will get a compiler error.

let totalArray2 () =
    let array = [|1; 2; 3|]
    let mutable total = 0
    
    let sum() = 
        for x in array do
            total <- total + x

    sum()
    printfn "total: %i" total

//The mutable variable 'total' is used in an invalid way. Mutable variables cannot be captured
//by closures. Consider eliminating this use of mutation or using a heap-allocated mutable 
//reference cell via 'ref' and '!'. 

The reason is that closure is bound to identifier but not variable. This identifier need to be immutable. To get around this, we can use immutable record identifier, but a member is mutable.

type MyRefRec<'a> = { mutable myref: 'a }
let totalArray1 () =
    let array = [|1; 2; 3|]
    let total = { myref = 0 }

    let sum() =
        for x in array do
            //now total is not a mutable type, so it can 
            //be captured by closure
            total.myref <- total.myref + x

    sum()

    printfn "total: %i" total.myref

You can see, MyRefRec is generic record. It has only one field. F# provide a shortcut and operator to simplified the above steps. This is "ref". So the above code can not be simplified as below.

let totalArray4 () =
    let array = [|1; 2; 3|]
    let total = ref 0

    let sum() =
        for x in array do
            //now total is ref type 
            total := !total + x

    sum()

    printfn "total: %i" !total

f# essential part 4 - closure

f# support closure. Here is the definition of closure

In computer science, a closure (also lexical closure, function closure or function value) is a function together with a referencing environment for the nonlocal names (free variables) of that function.

In f#, you can define functions within other functions. The inner function can use any identifier in scope, including identifiers defined in outer function. When the inner identifier return as result of the outer function, identifiers defined in outer function is still being captured by the inner function, the inner is called closure.

let buildGreet greeting  = 
    let prefix = Printf.sprintf "%s ," greeting
    let greet name = 
        Printf.sprintf "%s%s" prefix name
    greet //greet is a closure, even the it is return it can still access,


let getHelloMessage = buildGreet "hello"
let message = getHelloMessage "fred"
printfn "%s" message

Jun 29, 2011

f# essential - part 3 matching shortcut

F# provide a shortcut to define a function which purely use input parameter for matching purpose. For example the following are equal.

let printInt =
    function 1 -> printfn "1"
            | 2 -> printfn "2"
            | _ -> printfn "something else"

let printInt number =
    match number with 1 -> printfn "1"
                      | 2 -> printfn "2"
                      | _ -> printfn "something else"

let printInt number =
    match number with
        | 1 -> printfn "1"
        | 2 -> printfn "2"
        | _ -> printfn "something else"

f# essential - part 2 - pipleline operator

Before I discuss pipeline operator, let's talk about operator. F# allow us to define operator as function. The following are infix operators

$ % & * + - . / < = > @ ^ | 

The following are prefix operators.

! ? ~

You can define a infix operator like below

let (operator) ops1 ops2 = ...
//for example 
let (+) a b = a - b
2+3

You can define a prefix operator like below

let (!) a = 1
!8

So you can change your expression from "add 2 4" to "2 + 3" or "m1 a" to "!a", let's defined our pipleine operator as below.

let (-->) x f = f x
let rb = 0.5 --> System.Math.Cos

However, F# already define the "|>" for us, so we should use "|>". Operator is not a function, definition, rather you should think of it as macro. The compiler will change the syntax before it compile.

f# essential - part 1 binding

I was very puzzled with some concept when learning F#. Here is some. Even I explain it here, you may be still confused, but it is ok, as you read on.

let t1 = 1
//fsi shows val t1 : int = 1
//think of it as (val t1) bind to (int = 1)

Based on the concept of other language, you think t1 is variable, and it is initialized or assigned with value 1. But here it should be understood as identifier t1 is bind to a value, the value is not function value, it is int 1. So what is the big deal of "identifier", "bind", "function value", and "value", we will see later. If you run the following expression in fsi

t1
//fsi shows val it: int =1

This is evaluation of expression "t1", the process is to bind value int 1 to unknown identifier. Let's read another example.

let t2() = 1
//fsi shows  val t2 : unit -> int
//here fsi should shows
//val t2: unit -> int = <fun:it@91-2>

Here it means identifier t2 is bind to a value, the value is a function value, and the value is a function take unit type parameter and return a int type value. Here unit is similar the concept of "void" in other language. How do I prove my remark "here fsi should shows...", because we can find out what is the value of t2, by evaluating expression "t2" like below, it return the value of t2, here what I really means "the value that t2 is bind to "

t2
//val it : (unit -> int) = <fun:it@91-2>

t2 is different from t1 in that the value t2 bind to is a function, while the value that t1 bind to is not. Because the value is function, we can call the function like below. The concept of "function is a value" is an important concept in functional language, it may not looks a big deal for you. But it is very powerful. Please note the function here is not a traditional function in VB, a method in c#, conceptually it is like C#'s delegate, or javascript's function, people call it lamda in other functional language.

t2();
//fsi shows val it : int = 1

The type description generated by fsi need some explanation.


t2();
int //int type
int -> string //function type take one int input, return one string
int -> string -> double // a function take one int, one string, return one double
int * string -> double // a function take a (int, string) tuple , and return one double