Monday, February 2, 2009

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: 

Early and Late Binding

There are numerous definitions for early and late binding. Some are technical, some are theoretical. I will try to define it from both viewpoints.

Variables and expressions can be assigned at compile time or at runtime. Compile time (declaration time) assignment is called:

  • early binding
  • static binding
  • static typing

An example for early binding:

  1: '  Create a variable to hold a new object.
  2: Dim FS As System.IO.FileStream
  3: ' Assign a new object to the variable.
  4: FS = New System.IO.FileStream("C:\tmp.txt", _
  5:     System.IO.FileMode.Open)

Runtime assignment is called dynamic binding or late binding, when the type of the variable or expression is determined by the current (application) conditions. An example for late binding:

  1: ' To use this example, you must have Microsoft Excel installed on your computer.
  2: ' Compile with Option Strict Off to allow late binding.
  3: Sub TestLateBinding()
  4:     Dim xlApp As Object
  5:     Dim xlBook As Object
  6:     Dim xlSheet As Object
  7:     xlApp = CreateObject("Excel.Application")
  8:     ' Late bind an instance of an Excel workbook.
  9:     xlBook = xlApp.Workbooks.Add
 10:     ' Late bind an instance of an Excel worksheet.
 11:     xlSheet = xlBook.Worksheets(1)
 12:     xlSheet.Activate()
 13:     ' Show the application.
 14:     xlSheet.Application.Visible = True
 15:     ' Place some text in the second row of the sheet.
 16:     xlSheet.Cells(2, 2) = "This is column B row 2"
 17: End Sub

Another example for late binding:

  1: Dim MyVariable As Object
  2: MyVariable = "About Visual Basic"
  3: Debug.WriteLine("The variable data type is: " & MyVariable.GetType.ToString)
  4: MyVariable = #6/30/2006#
  5: Debug.WriteLine("The variable data type is: " & MyVariable.GetType.ToString)

The result for the code above:

The variable data type is: System.String
The variable data type is: System.DateTime

As you can see, the variable named MyVariable can represent a System.String and a System.Date in the code above.

Despite of the advantages of late binding, early binding is recommended:

  • Early binding code can be optimized better by the compiler, so it runs (much) faster
  • It is usually easier to read early binding code (known types, etc.)
  • Automatic code completion, Dynamic Help and other advanced IDE features are available only for early binding codes
  • Compiler can type 'compatibility' for early binding variables and expressions
  • Application constants are accessible (e.g. in MS Word)

Some advantages of late binding:

  • Version independence. E.g. in case of MS Word, programming against Word 97 and changing code libraries to Word 2000 can be smooth and automatic.
  • More references can mean more linking and bigger file size (in case of unmanaged code)

There are numerous methods in C# to use late binding. Most of them employs reflection and dynamic compilation. There will be late binding as a language feature from C# 4.0 specification. Late binding will be as simple as the following:

  1: dynamic d = GetDynamicObject();
  2: d.Foo();
Late binding will be achieved by the dynamic keyword.

Thursday, January 8, 2009

SQL Server service not starting

I had a strange experience recently. I tried to connect to a SQL Server instance and Management Studio stopped working and finally Windows Vista crashed. I couldn't start SQL Server after restart. I got the following messages in Windows Application Error Log:

  1. TDSSNIClient initialization failed with error 0xffffffff, status code 0x80.
  2. TDSSNIClient initialization failed with error 0xffffffff, status code 0x1.
  3. Could not start the network library because of an internal error in the network library. To determine the cause, review the errors immediately preceding this one in the error log.
  4. SQL Server could not spawn FRunCM thread. Check the SQL Server error log and the Windows event logs for information about possible related problems.

Solution:

  1. Set SQL instance to run as Local System Account
  2. Stop SQL Server
  3. Open "SQL Server Surface Area Configuration" and disable remote connection
  4. Start SQL Server

Now it should work.

Resolution:

There are very useful blog entries in SQL Protocols blog: Error Messages of SQL Server 2005 Start Up Failure, and Understanding server-side protocol initialization error codes

Messages from 2 to 4 are generic start up failure messages, you can ignore them. The only meaningful message is:

TDSSNIClient initialization failed with error 0xffffffff, status code 0x80.

Error code 0xffffffff means nothing. If error code was 0x7e, we could do the following:

  1. 0x7e = 126
  2. c:\> net helpmsg 126

    The specified module could not be found.

We have the reason now. Let's see what is status code 0x80.

Status Code (Hexa) Status Code (Dec) Protocol Area
0x03
0x40-0x4F
3 (0x03)
64-79 (0x40-0x4F)
Shared Memory
0x09-0x1E

6-30 (0x09-0x1E)

TCP/IP

0x1F-0x23

31-35 (0x1F-0x23)

DAC

0x35
0x50-0x5F

53 (0x35)
80-95 (0x50-0x5F)

Named Pipes

0x36
0x60-0x6F

54 (0x36)
96-111 (0x60-0x6F)

VIA

0x70-0x7F

112-127 (0x70-0x7F)

HTTP

0x38
0x80-0x8F

56 (0x38)
128-143 (0x80-0x8F)

SSL

0x90-0x9F

144-159 (0x90-0x9F)

General

So it means I have a problem with SSL. Some typical, more specific status codes:

Status Code Description
0x03 Error starting shared memory support
0x04 All protocols disabled
0x0A Unable to initialize the TCP/IP listener
0x1C Server configured to listen on a specific IP address in a cluster environment
0x1E Duplicate IP address detected in network
0x35 Error starting named pipe support
0x36

Error starting VIA support

0x38 Error obtaining or using the Certificate for SSL
0x3A Unable to initialize the communication listeners
0x40 Unable to initialize the Shared Memory listener
0x50 Unable to initialize the Named Pipe listener
0x60 Unable to initialize the VIA listener
0x70 Unable to initialize the HTTP listener
0x80 Unable to initialize SSL support